This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.18.3-rc1
Tony Lindgren tony@atomide.com tty: n_gsm: Fix packet data hex dump output
Ziyang Xuan william.xuanziyang@huawei.com macsec: fix UAF bug for real_dev
Jia-Ju Bai baijiaju1990@gmail.com md: bcache: check the return value of kzalloc() in detached_dev_do_request()
Xiao Ni xni@redhat.com md: fix double free of io_acct_set bioset
Xiao Ni xni@redhat.com md: Don't set mddev private to NULL in raid0 pers->free
Namjae Jeon linkinjeon@kernel.org fs/ntfs3: Fix invalid free in log_replay
Christian Brauner brauner@kernel.org exportfs: support idmapped mounts
Christian Brauner brauner@kernel.org fs: add two trivial lookup helpers
Eric Biggers ebiggers@google.com ext4: only allow test_dummy_encryption when supported
Xiao Yang yangx.jy@fujitsu.com RDMA/rxe: Generate a completion for unsupported/invalid opcode
Yixing Liu liuyixing1@huawei.com RDMA/hns: Remove the num_cqc_timer variable
Carlos Llamas cmllamas@google.com binder: fix sender_euid type in uapi header
Dan Carpenter dan.carpenter@oracle.com staging: r8188eu: delete rtw_wx_read/write32()
Jason A. Donenfeld Jason@zx2c4.com Revert "random: use static branch for crng_ready()"
Zhengjun Xing zhengjun.xing@linux.intel.com perf evlist: Extend arch_evsel__must_be_in_group to support hybrid systems
Waiman Long longman@redhat.com kseltest/cgroup: Make test_stress.sh work if run interactively
Sean Young sean@mess.org media: lirc: add missing exceptions for lirc uapi header file
Alex Elder elder@linaro.org net: ipa: fix page free in ipa_endpoint_replenish_one()
Alex Elder elder@linaro.org net: ipa: fix page free in ipa_endpoint_trans_release()
Johan Hovold johan+linaro@kernel.org phy: qcom-qmp: fix reset-controller leak on probe errors
Mao Jinlong quic_jinlmao@quicinc.com coresight: core: Fix coresight device probe failure issue
Tejun Heo tj@kernel.org blk-iolatency: Fix inflight count imbalances and IO hangs on offline
Eugenio Pérez eperezma@redhat.com vdpasim: allow to enable a vq repeatedly
Dinh Nguyen dinguyen@kernel.org dt-bindings: gpio: altera: correct interrupt-cells
Akira Yokosawa akiyks@gmail.com docs/conf.py: Cope with removal of language=None in Sphinx 5.0.0
Steve French stfrench@microsoft.com SMB3: EBADF/EIO errors in rename/open caused by race condition in smb2_compound_op
Srinivas Kandagatla srinivas.kandagatla@linaro.org misc: fastrpc: fix list iterator in fastrpc_req_mem_unmap_impl
Luís Henriques lhenriques@suse.de ceph: fix decoding of client session messages flags
Arnd Bergmann arnd@arndb.de ARM: pxa: maybe fix gpio lookup tables
Jonathan Bakker xc-racer2@live.ca ARM: dts: s5pv210: Remove spi-cs-high on panel in Aries
Johan Hovold johan+linaro@kernel.org phy: qcom-qmp: fix struct clk leak on probe errors
Diogo Ivo diogo.ivo@tecnico.ulisboa.pt clk: tegra: Add missing reset deassertion
Diogo Ivo diogo.ivo@tecnico.ulisboa.pt arm64: tegra: Add missing DFLL reset on Tegra210
Kathiravan T quic_kathirav@quicinc.com arm64: dts: qcom: ipq8074: fix the sleep clock frequency
Xiaomeng Tong xiam0nd.tong@gmail.com gma500: fix an incorrect NULL check on list iterator
Xiaomeng Tong xiam0nd.tong@gmail.com tilcdc: tilcdc_external: fix an incorrect NULL check on list iterator
Jiri Slaby jirislaby@kernel.org serial: pch: don't overwrite xmit->buf[0] by x_char
Coly Li colyli@suse.de bcache: avoid journal no-space deadlock by reserving 1 journal bucket
Coly Li colyli@suse.de bcache: remove incremental dirty sector counting for bch_sectors_dirty_init()
Coly Li colyli@suse.de bcache: improve multithreaded bch_sectors_dirty_init()
Coly Li colyli@suse.de bcache: improve multithreaded bch_btree_check()
Xiaomeng Tong xiam0nd.tong@gmail.com stm: ltdc: fix two incorrect NULL checks on list iterator
Xiaomeng Tong xiam0nd.tong@gmail.com carl9170: tx: fix an incorrect use of list iterator
Mark Brown broonie@kernel.org ASoC: rt5514: Fix event generation for "DSP Voice Wake Up" control
Alexander Wetzel alexander@wetzel-home.de rtl818x: Prevent using not initialized queues
Yi Yang yiyang13@huawei.com xtensa/simdisk: fix proc_read_simdisk()
Miaohe Lin linmiaohe@huawei.com mm/memremap: fix missing call to untrack_pfn() in pagemap_range()
Mike Kravetz mike.kravetz@oracle.com hugetlb: fix huge_pmd_unshare address update
Christophe de Dinechin dinechin@redhat.com nodemask.h: fix compilation error with GCC12
Mel Gorman mgorman@techsingularity.net mm/page_alloc: always attempt to allocate at least one page during bulk allocation
Eric Dumazet edumazet@google.com mm/page_owner: use strscpy() instead of strlcpy()
Dong Aisheng aisheng.dong@nxp.com Revert "mm/cma.c: remove redundant cma_mutex lock"
Masami Hiramatsu mhiramat@kernel.org kprobes: Fix build errors with CONFIG_KRETPROBES=n
Yunfei Wang yf.wang@mediatek.com iommu/dma: Fix iova map result check bug
Xiaomeng Tong xiam0nd.tong@gmail.com iommu/msm: Fix an incorrect NULL check on list iterator
Hyunchul Lee hyc.lee@gmail.com ksmbd: fix outstanding credits related bugs
Song Liu song@kernel.org ftrace: Clean up hash direct_functions on register failures
Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com kexec_file: drop weak attribute from arch_kexec_apply_relocations[_add]
Maciej W. Rozycki macro@orcam.me.uk MIPS: IP30: Remove incorrect `cpu_has_fpu' override
Maciej W. Rozycki macro@orcam.me.uk MIPS: IP27: Remove incorrect `cpu_has_fpu' override
Vincent Whitchurch vincent.whitchurch@axis.com um: Fix out-of-bounds read in LDT setup
Johannes Berg johannes.berg@intel.com um: chan_user: Fix winch_tramp() return value
Johannes Berg johannes.berg@intel.com um: Use asm-generic/dma-mapping.h
Johannes Berg johannes.berg@intel.com um: virtio_uml: Fix broken device handling in time-travel
Felix Fietkau nbd@nbd.name mac80211: upgrade passive scan to active scan on DFS channels after beacon rx
Dimitri John Ledkov dimitri.ledkov@canonical.com cfg80211: declare MODULE_FIRMWARE for regulatory.db
Felix Fietkau nbd@nbd.name mt76: fix use-after-free by removing a non-RCU wcid pointer
Kant Fan kant@allwinnertech.com thermal: devfreq_cooling: use local ops instead of global ops
Max Filippov jcmvbkbc@gmail.com irqchip: irq-xtensa-mx: fix initial IRQ affinity
Pali Rohár pali@kernel.org irqchip/armada-370-xp: Do not touch Performance Counter Overflow on A375, A38x, A39x
Guo Ren guoren@kernel.org csky: patch_text: Fixup last cpu should be master
Bean Huo beanhuo@micron.com mmc: core: Allows to override the timeout value for ioctl() path
Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com RDMA/hfi1: Fix potential integer multiplication overflow errors
Puyou Lu puyou.lu@gmail.com lib/string_helpers: fix not adding strarray to device's resource list
Sean Christopherson seanjc@google.com Kconfig: Add option for asm goto w/ tied outputs to workaround clang-13 bug
GUO Zihua guozihua@huawei.com ima: remove the IMA_TEMPLATE Kconfig option
Nicolas Dufresne nicolas.dufresne@collabora.com media: coda: Add more H264 levels for CODA960
Nicolas Dufresne nicolas.dufresne@collabora.com media: coda: Fix reported H264 profile
Tokunori Ikegami ikegami.t@gmail.com mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N
Tokunori Ikegami ikegami.t@gmail.com mtd: cfi_cmdset_0002: Move and rename chip_check/chip_ready/chip_good_for_write
Xiaomeng Tong xiam0nd.tong@gmail.com md: fix an incorrect NULL check in md_reload_sb
Xiaomeng Tong xiam0nd.tong@gmail.com md: fix an incorrect NULL check in does_sb_need_changing
Jani Nikula jani.nikula@intel.com drm/i915/dsi: fix VBT send packet port selection for ICL+
Brian Norris briannorris@chromium.org drm/bridge: analogix_dp: Grab runtime PM reference for DP-AUX
Xiaomeng Tong xiam0nd.tong@gmail.com drm/nouveau/kms/nv50-: atom: fix an incorrect NULL check on list iterator
Xiaomeng Tong xiam0nd.tong@gmail.com drm/nouveau/clk: Fix an incorrect NULL check on list iterator
Lucas Stach l.stach@pengutronix.de drm/etnaviv: check for reaped mapping in etnaviv_iommu_unmap_gem
Lyude Paul lyude@redhat.com drm/nouveau/subdev/bus: Ratelimit logging for fault errors
Dave Airlie airlied@redhat.com drm/amdgpu/cs: make commands with 0 chunks illegal behaviour.
Mickaël Salaün mic@digikod.net landlock: Fix same-layer rule unions
Mickaël Salaün mic@digikod.net landlock: Create find_rule() from unmask_layers()
Mickaël Salaün mic@digikod.net landlock: Reduce the maximum number of layers to 16
Mickaël Salaün mic@digikod.net landlock: Define access_mask_t to enforce a consistent access mask size
Mickaël Salaün mic@digikod.net selftests/landlock: Test landlock_create_ruleset(2) argument check ordering
Mickaël Salaün mic@digikod.net landlock: Change landlock_restrict_self(2) check ordering
Mickaël Salaün mic@digikod.net landlock: Change landlock_add_rule(2) argument check ordering
Mickaël Salaün mic@digikod.net selftests/landlock: Add tests for O_PATH
Mickaël Salaün mic@digikod.net selftests/landlock: Fully test file rename with "remove" access
Mickaël Salaün mic@digikod.net selftests/landlock: Extend access right tests to directories
Mickaël Salaün mic@digikod.net selftests/landlock: Add tests for unknown access rights
Mickaël Salaün mic@digikod.net selftests/landlock: Extend tests for minimal valid attribute size
Mickaël Salaün mic@digikod.net selftests/landlock: Make tests build with old libc
Mickaël Salaün mic@digikod.net landlock: Fix landlock_add_rule(2) documentation
Mickaël Salaün mic@digikod.net samples/landlock: Format with clang-format
Mickaël Salaün mic@digikod.net samples/landlock: Add clang-format exceptions
Mickaël Salaün mic@digikod.net selftests/landlock: Format with clang-format
Mickaël Salaün mic@digikod.net selftests/landlock: Normalize array assignment
Mickaël Salaün mic@digikod.net selftests/landlock: Add clang-format exceptions
Mickaël Salaün mic@digikod.net landlock: Format with clang-format
Mickaël Salaün mic@digikod.net landlock: Add clang-format exceptions
Manivannan Sadhasivam mani@kernel.org scsi: ufs: qcom: Add a readl() to make sure ref_clk gets enabled
Xiaomeng Tong xiam0nd.tong@gmail.com scsi: dc395x: Fix a missing check on list iterator
Junxiao Bi via Ocfs2-devel ocfs2-devel@oss.oracle.com ocfs2: dlmfs: fix error handling of user_dlm_destroy_lock
Alexander Aring aahringo@redhat.com dlm: fix missing lkb refcount handling
Alexander Aring aahringo@redhat.com dlm: fix wake_up() calls for pending remove
Dan Carpenter dan.carpenter@oracle.com dlm: uninitialized variable on error in dlm_listen_for_all()
Alexander Aring aahringo@redhat.com dlm: fix plock invalid read
Sven Schnelle svens@linux.ibm.com s390/stp: clock_delta should be signed
Nico Boehr nrb@linux.ibm.com s390/perf: obtain sie_block from the right address
Rei Yamamoto yamamoto.rei@jp.fujitsu.com mm, compaction: fast_find_migrateblock() should return pfn in the target zone
Damien Le Moal damien.lemoal@opensource.wdc.com block: Fix potential deadlock in blk_ia_range_sysfs_show()
Denis Efremov denis.e.efremov@oracle.com staging: r8188eu: prevent ->Ssid overflow in rtw_wx_set_scan()
Johan Hovold johan+linaro@kernel.org PCI: qcom: Fix unbalanced PHY init on probe errors
Johan Hovold johan+linaro@kernel.org PCI: qcom: Fix runtime PM imbalance on probe errors
Johan Hovold johan+linaro@kernel.org PCI: qcom: Fix pipe clock imbalance
Bjorn Helgaas bhelgaas@google.com PCI/PM: Fix bridge_d3_blacklist[] Elo i2 overwrite of Gigabyte X299
Alex Deucher alexander.deucher@amd.com drm/amdgpu: add beige goby PCI ID
Gautam Menghani gautammenghani201@gmail.com tracing: Initialize integer variable to prevent garbage return value
Wonhyuk Yang vvghjk1234@gmail.com tracing: Fix return value of trace_pid_write()
Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp tracing: Fix potential double free in create_var_ref()
Steven Rostedt (Google) rostedt@goodmis.org tracing: Have event format check not flag %p* on __get_dynamic_array()
Laurent Vivier laurent@vivier.eu tty: goldfish: Introduce gf_ioread32()/gf_iowrite32()
Sakari Ailus sakari.ailus@linux.intel.com ACPI: property: Release subnode properties with data nodes
Jan Kara jack@suse.cz ext4: avoid cycles in directory h-tree
Jan Kara jack@suse.cz ext4: verify dir block before splitting it
Baokun Li libaokun1@huawei.com ext4: fix bug_on in __es_tree_search
Theodore Ts'o tytso@mit.edu ext4: filter out EXT4_FC_REPLAY from on-disk superblock field s_state
Ye Bin yebin10@huawei.com ext4: fix bug_on in ext4_writepages
Eric Biggers ebiggers@google.com ext4: fix memory leak in parse_apply_sb_mount_options()
Ye Bin yebin10@huawei.com ext4: fix warning in ext4_handle_inode_extension
Baokun Li libaokun1@huawei.com ext4: fix race condition between ext4_write and ext4_convert_inline_data
Ojaswin Mujoo ojaswin@linux.ibm.com ext4: fix journal_ioprio mount option handling
Ye Bin yebin10@huawei.com ext4: fix use-after-free in ext4_rename_dir_prepare
Dmitry Monakhov dmtrmonakhov@yandex-team.ru ext4: mark group as trimmed only if it was fully scanned
Jan Kara jack@suse.cz bfq: Make sure bfqg for which we are queueing requests is online
Jan Kara jack@suse.cz bfq: Get rid of __bio_blkcg() usage
Jan Kara jack@suse.cz bfq: Track whether bfq_group is still online
Jan Kara jack@suse.cz bfq: Remove pointless bfq_init_rq() calls
Jan Kara jack@suse.cz bfq: Drop pointless unlock-lock pair
Jan Kara jack@suse.cz bfq: Update cgroup information before merging bio
Jan Kara jack@suse.cz bfq: Split shared queues on move between cgroups
Jan Kara jack@suse.cz bfq: Avoid merging queues with different parents
Jan Kara jack@suse.cz bfq: Avoid false marking of bic as stably merged
Aditya Garg gargaditya08@live.com efi: Do not import certificates from UEFI Secure Boot for T2 Macs
Zhihao Cheng chengzhihao1@huawei.com fs-writeback: writeback_sb_inodes:Recalculate 'wrote' according skipped pages
Miaoqian Lin linmq006@gmail.com ipmi:ipmb: Fix refcount leak in ipmi_ipmb_probe
Johannes Berg johannes.berg@intel.com iwlwifi: mei: fix potential NULL-ptr deref
Avraham Stern avraham.stern@intel.com iwlwifi: mei: clear the sap data header before sending
Emmanuel Grumbach emmanuel.grumbach@intel.com iwlwifi: mvm: fix assert 1F04 upon reconfig
Johannes Berg johannes.berg@intel.com iwlwifi: fw: init SAR GEO table only if data is present
Johannes Berg johannes.berg@intel.com wifi: mac80211: fix use-after-free in chanctx code
Peter Zijlstra peterz@infradead.org objtool: Fix symbol creation
Mikulas Patocka mpatocka@redhat.com objtool: Fix objtool regression on x32 systems
Chao Yu chao@kernel.org f2fs: fix to do sanity check for inline inode
Chao Yu chao@kernel.org f2fs: fix fallocate to use file_modified to update permissions consistently
Eric Biggers ebiggers@google.com f2fs: don't use casefolded comparison for "." and ".."
Chao Yu chao@kernel.org f2fs: fix to do sanity check on total_data_blocks
Jaegeuk Kim jaegeuk@kernel.org f2fs: don't need inode lock for system hidden quota
Chao Yu chao@kernel.org f2fs: fix deadloop in foreground GC
Chao Yu chao@kernel.org f2fs: fix to clear dirty inode in f2fs_evict_inode()
Chao Yu chao@kernel.org f2fs: fix to do sanity check on block address in f2fs_do_zero_range()
Chao Yu chao@kernel.org f2fs: fix to avoid f2fs_bug_on() in dec_valid_node_count()
Olga Kornievskaia kolga@netapp.com NFSv4.1 mark qualified async operations as MOVEABLE tasks
Benjamin Coddington bcodding@redhat.com NFSv4: Fix free of uninitialized nfs4_label on referral lookup.
Javier Martinez Canillas javierm@redhat.com video: fbdev: vesafb: Fix a use-after-free due early fb_info cleanup
Zhengjun Xing zhengjun.xing@linux.intel.com perf jevents: Fix event syntax error caused by ExtSel
Daniel Bristot de Oliveira bristot@kernel.org tracing/timerlat: Notify IRQ new max latency only if stop tracing is set
Daniel Bristot de Oliveira bristot@kernel.org rtla: Remove procps-ng dependency
Daniel Bristot de Oliveira bristot@kernel.org rtla: Fix __set_sched_attr error message
John Kacur jkacur@redhat.com rtla: Minor grammar fix for rtla README
John Kacur jkacur@redhat.com rtla: Don't overwrite existing directory mode
Wan Jiabing wanjiabing@vivo.com rtla: Avoid record NULL pointer dereference
Leo Yan leo.yan@linaro.org perf c2c: Use stdio interface if slang is not supported
Jiri Olsa jolsa@kernel.org perf build: Fix btf__load_from_kernel_by_id() feature check
Tiezhu Yang yangtiezhu@loongson.cn MIPS: RALINK: Define pci_remap_iospace under CONFIG_PCI_DRIVERS_GENERIC
Palmer Dabbelt palmer@rivosinc.com RISC-V: Fix the XIP build
Palmer Dabbelt palmer@rivosinc.com RISC-V: Split out the XIP fixups into their own file
Li Huafei lihuafei1@huawei.com tracing: Reset the function filter after completing trampoline/graph selftest
Kuninori Morimoto kuninori.morimoto.gx@renesas.com i2c: rcar: fix PM ref counts in probe error paths
Tali Perry tali.perry1@gmail.com i2c: npcm: Handle spurious interrupts
Tyrone Ting kfting@nuvoton.com i2c: npcm: Correct register access width
Tali Perry tali.perry1@gmail.com i2c: npcm: Fix timeout calculation
Joerg Roedel jroedel@suse.de iommu/amd: Increase timeout waiting for GA log enablement
Amelie Delaunay amelie.delaunay@foss.st.com dmaengine: stm32-mdma: fix chan initialization in stm32_mdma_irq_handler()
Amelie Delaunay amelie.delaunay@foss.st.com dmaengine: stm32-mdma: remove GISR1 register
Miaoqian Lin linmq006@gmail.com video: fbdev: clcdfb: Fix refcount leak in clcdfb_of_vram_setup
Dave Wysochanski dwysocha@redhat.com NFS: Pass i_size to fscache_unuse_cookie() when a file is released
Trond Myklebust trond.myklebust@hammerspace.com NFS: Further fixes to the writeback error handling
Trond Myklebust trond.myklebust@hammerspace.com NFSv4/pNFS: Do not fail I/O when we fail to allocate the pNFS layout
Trond Myklebust trond.myklebust@hammerspace.com NFS: Don't report errors from nfs_pageio_complete() more than once
Trond Myklebust trond.myklebust@hammerspace.com NFS: Do not report flush errors in nfs_write_end()
Trond Myklebust trond.myklebust@hammerspace.com NFS: Don't report ENOSPC write errors twice
Trond Myklebust trond.myklebust@hammerspace.com NFS: fsync() should report filesystem errors over EINTR/ERESTARTSYS
Trond Myklebust trond.myklebust@hammerspace.com NFS: Do not report EINTR/ERESTARTSYS as mapping errors
Christophe JAILLET christophe.jaillet@wanadoo.fr dmaengine: idxd: Fix the error handling path in idxd_cdev_register()
Nathan Chancellor nathan@kernel.org i2c: at91: Initialize dma_buf in at91_twi_xfer()
Miles Chen miles.chen@mediatek.com iommu/mediatek: Fix NULL pointer dereference when printing dev_name
Guenter Roeck linux@roeck-us.net MIPS: Loongson: Use hwmon_device_register_with_groups() to register hwmon
Jean-Philippe Brucker jean-philippe@linaro.org iommu/arm-smmu-v3-sva: Fix mm use-after-free
Rex-BC Chen rex-bc.chen@mediatek.com cpufreq: mediatek: Unregister platform device on exit
Jia-Wei Chang jia-wei.chang@mediatek.com cpufreq: mediatek: Use module_init and add module_exit
Michael Walle michael@walle.cc i2c: at91: use dma safe buffers
Yong Wu yong.wu@mediatek.com iommu/mediatek: Add mutex for m4u_group and m4u_dom in data
Yong Wu yong.wu@mediatek.com iommu/mediatek: Remove clk_disable in mtk_iommu_remove
Yong Wu yong.wu@mediatek.com iommu/mediatek: Add list_del in mtk_iommu_remove
Yong Wu yong.wu@mediatek.com iommu/mediatek: Fix 2 HW sharing pgtable issue
Suravee Suthikulpanit suravee.suthikulpanit@amd.com iommu/amd: Do not call sleep while holding spinlock
Mario Limonciello mario.limonciello@amd.com iommu/amd: Enable swiotlb in all cases
Guo Ren guoren@kernel.org riscv: Fixup difference with defconfig
Jakob Koschel jakobkoschel@gmail.com f2fs: fix dereference of stale list iterator after loop body
Chao Yu chao@kernel.org f2fs: fix to do sanity check on inline_dots inode
Jayesh Choudhary j-choudhary@ti.com dmaengine: ti: k3-psil-am62: Update PSIL thread for saul.
Dan Carpenter dan.carpenter@oracle.com OPP: call of_node_put() on error path in _bandwidth_supported()
Dmitry Torokhov dmitry.torokhov@gmail.com Input: stmfts - do not leave device disabled in stmfts_input_open
Wanpeng Li wanpengli@tencent.com KVM: LAPIC: Drop pending LAPIC timer injection when canceling the timer
Hector Martin marcan@marcan.st pinctrl: apple: Use a raw spinlock for the regmap
Douglas Miller doug.miller@cornelisnetworks.com RDMA/hfi1: Prevent use of lock before it is initialized
Christophe JAILLET christophe.jaillet@wanadoo.fr RDMA/rxe: Fix an error handling path in rxe_get_mcg()
Björn Ardö bjorn.ardo@axis.com mailbox: forward the hrtimer if not queued and under a lock
Julian Schroeder jumaco@amazon.com nfsd: destroy percpu stats counters after reply cache shutdown
Yang Yingliang yangyingliang@huawei.com mfd: davinci_voicecodec: Fix possible null-ptr-deref davinci_vc_probe()
Christophe JAILLET christophe.jaillet@wanadoo.fr gpio: sim: Use correct order for the parameters of devm_kcalloc()
Christophe Leroy christophe.leroy@csgroup.eu powerpc/fsl_book3e: Don't set rodata RO too early
Vaibhav Jain vaibhav@linux.ibm.com powerpc/papr_scm: Fix leaking nvdimm_events_map elements
Miaoqian Lin linmq006@gmail.com powerpc/fsl_rio: Fix refcount leak in fsl_rio_setup
Miaoqian Lin linmq006@gmail.com powerpc/xive: Fix refcount leak in xive_spapr_init
Randy Dunlap rdunlap@infradead.org macintosh: via-pmu and via-cuda need RTC_LIB
Kajol Jain kjain@linux.ibm.com powerpc/perf: Fix the threshold compare group constraint for power9
Kajol Jain kjain@linux.ibm.com powerpc/perf: Fix the threshold compare group constraint for power10
Russell Currey ruscur@russell.cc powerpc/powernv: Get STF barrier requirements from device-tree
Russell Currey ruscur@russell.cc powerpc/powernv: Get L1D flush requirements from device-tree
Michael Ellerman mpe@ellerman.id.au powerpc/64: Only WARN if __pa()/__va() called with bad addresses
Mario Limonciello mario.limonciello@amd.com mailbox: pcc: Fix an invalid-load caught by the address sanitizer
Kan Liang kan.liang@linux.intel.com perf stat: Always keep perf metrics topdown events in a group
Ian Rogers irogers@google.com perf evlist: Keep topdown counters in weak group
Yang Yingliang yangyingliang@huawei.com hwrng: omap3-rom - fix using wrong clk_disable() in omap_rom_rng_runtime_resume()
Dan Williams dan.j.williams@intel.com cxl/mem: Drop mem_enabled check from wait_for_media()
Daire McNamara daire.mcnamara@microchip.com PCI: microchip: Fix potential race in interrupt handling
Fabiano Rosas farosas@linux.ibm.com KVM: PPC: Book3S HV: Fix vcore_blocked tracepoint
Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com PCI/AER: Clear MULTI_ERR_COR/UNCOR_RCV bits
Miaoqian Lin linmq006@gmail.com Input: sparcspkr - fix refcount leak in bbc_beep_probe
Jane Chu jane.chu@oracle.com mce: fix set_mce_nospec to always unmap the whole page
Jane Chu jane.chu@oracle.com x86/mce: relocate set{clear}_mce_nospec() functions
Mina Almasry almasrymina@google.com hugetlbfs: fix hugetlbfs_statfs() locking
Michael Walle michael@walle.cc ARM: dts: lan966x: swap dma channels for crypto node
Eugen Hristev eugen.hristev@microchip.com ARM: dts: at91: sama7g5: remove interrupt-parent from gic node
Sebastian Andrzej Siewior bigeasy@linutronix.de crypto: cryptd - Protect per-CPU resource by disabling BH.
Corentin Labbe clabbe@baylibre.com crypto: sun8i-ss - handle zero sized sg
Corentin Labbe clabbe@baylibre.com crypto: sun8i-ss - rework handling of IV
Qi Zheng zhengqi.arch@bytedance.com tty: fix deadlock caused by calling printk() under tty_port->lock
Alexey Dobriyan adobriyan@gmail.com module: fix [e_shstrndx].sh_size=0 OOB access
Greg Kroah-Hartman gregkh@linuxfoundation.org module.h: simplify MODULE_IMPORT_NS
AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com PCI: mediatek-gen3: Assert resets to ensure expected init state
Francesco Dolcini francesco.dolcini@toradex.com PCI: imx6: Fix PERST# start-up sequence
Waiman Long longman@redhat.com ipc/mqueue: use get_tree_nodev() in mqueue_get_tree()
Alexey Dobriyan adobriyan@gmail.com proc: fix dentry/inode overinstantiating under /proc/${pid}/net
Charles Keepax ckeepax@opensource.cirrus.com ASoC: atmel-classd: Remove endianness flag on class d component
Charles Keepax ckeepax@opensource.cirrus.com ASoC: atmel-pdmic: Remove endianness flag on pdmic component
Robert Marko robert.marko@sartura.hr arm64: dts: marvell: espressobin-ultra: enable front USB3 port
Robert Marko robert.marko@sartura.hr arm64: dts: marvell: espressobin-ultra: fix SPI-NOR config
Yangyang Li liyangyang20@huawei.com RDMA/hns: Add the detection for CMDQ status in the device initialization process
Randy Dunlap rdunlap@infradead.org powerpc/4xx/cpm: Fix return value of __setup() handler
Randy Dunlap rdunlap@infradead.org powerpc/idle: Fix return value of __setup() handler
Yang Yingliang yangyingliang@huawei.com pinctrl: renesas: core: Fix possible null-ptr-deref in sh_pfc_map_resources()
Geert Uytterhoeven geert+renesas@glider.be pinctrl: renesas: r8a779f0: Fix GPIO function on I2C-capable pins
Geert Uytterhoeven geert+renesas@glider.be pinctrl: renesas: r8a779a0: Fix GPIO function on I2C-capable pins
Randy Dunlap rdunlap@infradead.org powerpc/8xx: export 'cpm_setbrg' for modules
Lv Ruyi lv.ruyi@zte.com.cn drm/msm/dpu: fix error check return value of irq_of_parse_and_map()
Kuniyuki Iwashima kuniyu@amazon.co.jp list: fix a data-race around ep->rdllist
Heming Zhao via Ocfs2-devel ocfs2-devel@oss.oracle.com ocfs2: fix mounting crash if journal is not alloced
Sudeep Holla sudeep.holla@arm.com firmware: arm_ffa: Remove incorrect assignment of driver_data
Sudeep Holla sudeep.holla@arm.com firmware: arm_ffa: Fix uuid parameter to ffa_partition_probe
Christophe JAILLET christophe.jaillet@wanadoo.fr drivers/base/memory: fix an unlikely reference counting issue in __add_memory_block()
Muchun Song songmuchun@bytedance.com dax: fix cache flush on PMD-mapped pages
Miaohe Lin linmiaohe@huawei.com drivers/base/node.c: fix compaction sysfs file leak
Jacky Li jackyli@google.com crypto: ccp - Fix the INIT_EX data file open failure
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org pinctrl: mvebu: Fix irq_of_parse_and_map() return value
Dan Williams dan.j.williams@intel.com nvdimm: Allow overwrite in the presence of disabled dimms
Dan Williams dan.j.williams@intel.com nvdimm: Fix firmware activation deadlock scenarios
Cristian Marussi cristian.marussi@arm.com firmware: arm_scmi: Fix list protocols enumeration in the base protocol
Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com ASoC: sh: rz-ssi: Release the DMA channels in rz_ssi_probe() error path
Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com ASoC: sh: rz-ssi: Propagate error codes returned from platform_get_irq_byname()
Matthias Schiffer matthias.schiffer@ew.tq-group.com arm64: dts: ti: k3-am64-mcu: remove incorrect UART base clock rates
QintaoShen unSimple1993@163.com soc: bcm: Check for NULL return of devm_kzalloc()
Gustavo A. R. Silva gustavoars@kernel.org scsi: fcoe: Fix Wstringop-overflow warnings in fcoe_wwn_from_mac()
Lv Ruyi lv.ruyi@zte.com.cn mfd: ipaq-micro: Fix error check return value of platform_get_irq()
Hari Bathini hbathini@linux.ibm.com powerpc/fadump: fix PT_LOAD segment for boot memory area
Andrea Parri (Microsoft) parri.andrea@gmail.com Drivers: hv: vmbus: Fix handling of messages with transaction ID of zero
Vinod Koul vkoul@kernel.org arm64: dts: qcom: qrb5165-rb5: Fix can-clock node name
Fabien Parent fparent@baylibre.com pinctrl: mediatek: mt8195: enable driver on mtk platforms
Caleb Connolly kc@postmarketos.org pinctrl/rockchip: support deferring other gpio params
Chuanhong Guo gch981213@gmail.com arm: mediatek: select arch timer for mt7629
Chia-I Wu olvaffe@gmail.com drm/msm: return the average load over the polling period
Chia-I Wu olvaffe@gmail.com drm/msm: simplify gpu_busy callback
Stefan Wahren stefan.wahren@i2se.com pinctrl: bcm2835: implement hook for missing gpio-ranges
Stefan Wahren stefan.wahren@i2se.com gpiolib: of: Introduce hook for missing gpio-ranges
Corentin Labbe clabbe@baylibre.com crypto: marvell/cesa - ECB does not IV
Vladis Dronov vdronov@redhat.com hwrng: cn10k - Make check_rng_health() return an error code
Vladis Dronov vdronov@redhat.com hwrng: cn10k - Optimize cn10k_rng_read()
Hangyu Hua hbh25y@gmail.com misc: ocxl: fix possible double free in ocxl_file_register_afu
Stefan Wahren stefan.wahren@i2se.com ARM: dts: bcm2835-rpi-b: Fix GPIO line names
Phil Elwell phil@raspberrypi.com ARM: dts: bcm2837-rpi-3-b-plus: Fix GPIO line name of power LED
Phil Elwell phil@raspberrypi.com ARM: dts: bcm2837-rpi-cm3-io3: Fix GPIO line names for SMPS I2C
Phil Elwell phil@raspberrypi.com ARM: dts: bcm2835-rpi-zero-w: Fix GPIO line name for Wifi/BT
Vinod Koul vkoul@kernel.org arm64: dts: qcom: sm8450: Fix missing iommus for qup1
Vinod Koul vkoul@kernel.org arm64: dts: qcom: sm8450: Fix missing iommus for qup
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: qcom: sdx55: remove wrong unit address from RPMH RSC clocks
Bryan O'Donoghue bryan.odonoghue@linaro.org dt-bindings: soc: qcom: smd-rpm: Fix missing MSM8936 compatible
Marek Vasut marex@denx.de ARM: dts: stm32: Fix PHY post-reset delay on Avenger96
Marc Kleine-Budde mkl@pengutronix.de can: xilinx_can: mark bit timing constants as const
Guenter Roeck linux@roeck-us.net platform/chrome: Re-introduce cros_ec_cmd_xfer and use it for ioctls
Max Krummenacher max.krummenacher@toradex.com ARM: dts: imx6dl-colibri: Fix I2C pinmuxing
Tzung-Bi Shih tzungbi@kernel.org platform/chrome: cros_ec: fix error handling in cros_ec_register()
Giovanni Cabiddu giovanni.cabiddu@intel.com crypto: qat - set COMPRESSION capability for DH895XCC
Giovanni Cabiddu giovanni.cabiddu@intel.com crypto: qat - set CIPHER capability for DH895XCC
Sudeep Holla sudeep.holla@arm.com arm64: dts: juno: Fix SCMI power domain IDs for ETF and CS funnel
Sean Christopherson seanjc@google.com KVM: nVMX: Clear IDT vectoring on nested VM-Exit for double/triple fault
Sean Christopherson seanjc@google.com KVM: nVMX: Leave most VM-Exit info fields unmodified on failed VM-Entry
Dan Williams dan.j.williams@intel.com cxl/pci: Make cxl_dvsec_ranges() failure not fatal to cxl_pci
Dan Williams dan.j.williams@intel.com cxl/pci: Add debug for DVSEC range init failures
Bjorn Andersson bjorn.andersson@linaro.org soc: qcom: llcc: Add MODULE_DEVICE_TABLE()
Stephen Boyd swboyd@chromium.org arm64: dts: qcom: sc7280-herobrine: Drop outputs on fpmcu pins
Stephen Boyd swboyd@chromium.org arm64: dts: qcom: sc7280: Fix sar1_irq_odl node name
Thorsten Scherer t.scherer@eckelmann.de ARM: dts: ci4x10: Adapt to changes in imx6qdl.dtsi regarding fec clocks
Jiantao Zhang water.zhangjiantao@huawei.com PCI: dwc: Fix setting error return on MSI DMA mapping failure
Miaoqian Lin linmq006@gmail.com PCI: mediatek: Fix refcount leak in mtk_pcie_subsys_powerup()
Dan Carpenter dan.carpenter@oracle.com PCI: rockchip: Fix find_first_zero_bit() limit
Dan Carpenter dan.carpenter@oracle.com PCI: cadence: Fix find_first_zero_bit() limit
Dmitry Baryshkov dmitry.baryshkov@linaro.org arm64: defconfig: reenable SM_DISPCC_8250
Miaoqian Lin linmq006@gmail.com soc: qcom: smsm: Fix missing of_node_put() in smsm_parse_ipc
Miaoqian Lin linmq006@gmail.com soc: qcom: smp2p: Fix missing of_node_put() in smp2p_parse_ipc
Andre Przywara andre.przywara@arm.com ARM: dts: suniv: F1C100: fix watchdog compatible
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: Update pin controller node name
Christophe JAILLET christophe.jaillet@wanadoo.fr memory: samsung: exynos5422-dmc: Avoid some over memory allocation
Mario Limonciello mario.limonciello@amd.com PCI/ACPI: Allow D3 only if Root Port can signal and wake from D3
Allen-KH Cheng allen-kh.cheng@mediatek.com arm64: dts: mt8192: Fix nor_flash status disable typo
Shawn Lin shawn.lin@rock-chips.com arm64: dts: rockchip: Move drive-impedance-ohm to emmc phy on rk3399
Sean Young sean@mess.org media: lirc: revert removal of unused feature flags
liuyacan liuyacan@corp.netease.com Revert "net/smc: fix listen processing for SMC-Rv2"
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: hci_conn: Fix hci_connect_le_sync
Robin Murphy robin.murphy@arm.com dma-direct: don't over-decrypt memory
liuyacan liuyacan@corp.netease.com net/smc: fix listen processing for SMC-Rv2
liuyacan liuyacan@corp.netease.com net/smc: postpone sk_refcnt increment in connect()
Randy Dunlap rdunlap@infradead.org net: dsa: restrict SMSC_LAN9303_I2C kconfig
Ioana Ciornei ioana.ciornei@nxp.com dpaa2-eth: unmap the SGT buffer before accessing its contents
Ioana Ciornei ioana.ciornei@nxp.com dpaa2-eth: use the correct software annotation field
Ioana Ciornei ioana.ciornei@nxp.com dpaa2-eth: retrieve the virtual address before dma_unmap
Christophe JAILLET christophe.jaillet@wanadoo.fr hinic: Avoid some over memory allocation
David Howells dhowells@redhat.com rxrpc: Fix decision on when to generate an IDLE ACK
David Howells dhowells@redhat.com rxrpc: Don't let ack.previousPacket regress
David Howells dhowells@redhat.com rxrpc: Fix overlapping ACK accounting
David Howells dhowells@redhat.com rxrpc: Don't try to resend the request if we're receiving the reply
David Howells dhowells@redhat.com rxrpc: Fix listen() setting the bar too high for the prealloc rings
David Howells dhowells@redhat.com rxrpc: Fix locking issue
Adam Wujek dev_public@wujek.eu hwmon: (pmbus) Check PEC support before reading other registers
Guenter Roeck linux@roeck-us.net hwmon: (dimmtemp) Fix bitmap handling
Yongzhi Liu lyz_cs@pku.edu.cn hv_netvsc: Fix potential dereference of NULL pointer
Taehee Yoo ap420073@gmail.com amt: fix memory leak for advertisement message
Taehee Yoo ap420073@gmail.com amt: fix gateway mode stuck
Jakub Kicinski kuba@kernel.org net: stmmac: fix out-of-bounds access in a selftest
Kan Liang kan.liang@linux.intel.com perf parse-events: Support different format of the topdown event name
Alexey Khoroshilov khoroshilov@ispras.ru ASoC: max98090: Move check for invalid values before casting in max98090_put_enab_tlv()
Hangbin Liu liuhangbin@gmail.com bonding: fix missed rcu protection
Duoming Zhou duoming@zju.edu.cn NFC: hci: fix sleep in atomic context bugs in nfc_hci_hcp_message_tx
John Garry john.garry@huawei.com scsi: hisi_sas: Fix memory ordering in hisi_sas_task_deliver()
John Garry john.garry@huawei.com scsi: hisi_sas: Fix rescan after deleting a disk
Harini Katakam harini.katakam@xilinx.com net: macb: Fix PTP one step sync support
Ulf Hansson ulf.hansson@linaro.org PM: domains: Fix initialization of genpd's next_wakeup
Heikki Krogerus heikki.krogerus@linux.intel.com platform/x86: intel_cht_int33fe: Set driver data
Ulf Hansson ulf.hansson@linaro.org cpuidle: riscv-sbi: Fix code to allow a genpd governor to be used
Ulf Hansson ulf.hansson@linaro.org cpuidle: psci: Fix regression leading to no genpd governor
Yang Yingliang yangyingliang@huawei.com ASoC: wm2000: fix missing clk_disable_unprepare() on error in wm2000_anc_transition()
YueHaibing yuehaibing@huawei.com ASoC: codecs: lpass: Fix passing zero to 'PTR_ERR'
Jan Kara jack@suse.cz bfq: Allow current waker to defend against a tentative one
Jan Kara jack@suse.cz bfq: Relax waker detection for shared queues
Miaoqian Lin linmq006@gmail.com thermal/drivers/imx_sc_thermal: Fix refcount leak in imx_sc_thermal_probe
Yang Yingliang yangyingliang@huawei.com thermal/core: Fix memory leak in __thermal_cooling_device_register()
Zheng Yongjun zhengyongjun3@huawei.com thermal/drivers/broadcom: Fix potential NULL dereference in sr_thermal_probe
Stefan Wahren stefan.wahren@i2se.com thermal/drivers/bcm2711: Don't clamp temperature at zero
Nathan Chancellor nathan@kernel.org drm/i915: Fix CFI violation with show_dynamic_id()
Abhinav Kumar quic_abhinavk@quicinc.com drm/msm/dpu: handle pm_runtime_get_sync() errors in bind path
Hangbin Liu liuhangbin@gmail.com selftests/bpf: Add missed ima_setup.sh in Makefile
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm: don't free the IRQ if it was not requested
Lai Jiangshan jiangshan.ljs@antgroup.com x86/sev: Annotate stack change in the #VC handler
Hangyu Hua hbh25y@gmail.com drm: msm: fix possible memory leak in mdp5_crtc_cursor_set()
Miaoqian Lin linmq006@gmail.com drm/msm/a6xx: Fix refcount leak in a6xx_gpu_init
Douglas Anderson dianders@chromium.org drm/msm/dsi: don't powerup at modeset time for parade-ps8640
Eric Biggers ebiggers@google.com ext4: reject the 'commit' option on ext2 filesystems
Moshe Tal moshet@nvidia.com net/mlx5e: Correct the calculation of max channels for rep
Gao Xiang hsiangkao@linux.alibaba.com erofs: fix buffer copy overflow of ztailpacking feature
Wolfgang Bumiller w.bumiller@proxmox.com blk-cgroup: always terminate io.stat lines
Miaoqian Lin linmq006@gmail.com regulator: scmi: Fix refcount leak in scmi_regulator_probe
Jonas Karlman jonas@kwiboo.se media: rkvdec: h264: Fix bit depth wrap in pps packet
Nicolas Dufresne nicolas.dufresne@collabora.com media: rkvdec: h264: Fix dpb_valid implementation
Nicolas Dufresne nicolas.dufresne@collabora.com media: rkvdec: Stop overclocking the decoder
Yang Yingliang yangyingliang@huawei.com media: i2c: ov5648: fix wrong pointer passed to IS_ERR() and PTR_ERR()
Mike Pagano mpagano@gentoo.org media: i2c: ov2640: Depend on V4L2_ASYNC
Dongliang Mu mudongliangabcd@gmail.com media: ov7670: remove ov7670_power_off from ov7670_remove
Andre Przywara andre.przywara@arm.com kselftest/arm64: bti: force static linking
Miaoqian Lin linmq006@gmail.com ASoC: ti: j721e-evm: Fix refcount leak in j721e_soc_probe_*
Zheng Bin zhengbin13@huawei.com net: hinic: add missing destroy_workqueue in hinic_pf_to_mgmt_init
Eric Dumazet edumazet@google.com sctp: read sk->sk_bound_dev_if once in sctp_rcv()
Eric Dumazet edumazet@google.com net: annotate races around sk->sk_bound_dev_if
Geert Uytterhoeven geert@linux-m68k.org m68k: math-emu: Fix dependencies of math emulation support
Keith Busch kbusch@kernel.org nvme: set dma alignment to dword
Mark Rutland mark.rutland@arm.com irqchip/gic-v3: Fix priority mask handling
Mark Rutland mark.rutland@arm.com irqchip/gic-v3: Refactor ISB + EOIR at ack time
Mark Rutland mark.rutland@arm.com irqchip/gic-v3: Ensure pseudo-NMIs have an ISB between ack and handling
Dylan Yudaken dylany@fb.com io_uring: only wake when the correct events are set
Pavel Begunkov asml.silence@gmail.com io_uring: avoid io-wq -EAGAIN looping for !IOPOLL
Yunfei Dong yunfei.dong@mediatek.com media: mediatek: vcodec: Fix v4l2 compliance decoder cmd test fail
Sean Wang sean.wang@mediatek.com Bluetooth: btmtksdio: fix the reset takes too long
Sean Wang sean.wang@mediatek.com Bluetooth: btmtksdio: fix possible FW initialization failure
Sean Wang sean.wang@mediatek.com Bluetooth: btmtksdio: fix use-after-free at btmtksdio_recv_event
Niels Dossche dossche.niels@gmail.com Bluetooth: protect le accept and resolv lists with hdev->lock
Niels Dossche dossche.niels@gmail.com Bluetooth: use hdev lock for accept_list and reject_list in conn req
Niels Dossche dossche.niels@gmail.com Bluetooth: use hdev lock in activate_scan for hci_is_adv_monitoring
Ying Hsu yinghsu@chromium.org Bluetooth: fix dangling sco_conn and use-after-free in sco_sock_timeout
Sean Wang sean.wang@mediatek.com Bluetooth: mt7921s: Fix the incorrect pointer check
Benjamin Gaignard benjamin.gaignard@collabora.com media: hantro: HEVC: Fix tile info buffer value computation
Eugen Hristev eugen.hristev@microchip.com media: atmel: atmel-sama5d2-isc: fix wrong mask in YUYV format check
Michael Rodin mrodin@de.adit-jv.com media: vsp1: Fix offset calculation for plane cropping
Randy Dunlap rdunlap@infradead.org media: make RADIO_ADAPTERS tristate
Pavel Skripkin paskripkin@gmail.com media: pvrusb2: fix array-index-out-of-bounds in pvr2_i2c_core_init
Miaoqian Lin linmq006@gmail.com media: exynos4-is: Change clk_disable to clk_disable_unprepare
Laurentiu Palcu laurentiu.palcu@oss.nxp.com media: i2c: rdacm2x: properly set subdev entity function
Miaoqian Lin linmq006@gmail.com media: atmel: atmel-isc: Fix PM disable depth imbalance in atmel_isc_probe
Miaoqian Lin linmq006@gmail.com media: st-delta: Fix PM disable depth imbalance in delta_probe
Peter Chiu chui-hao.chiu@mediatek.com mt76: mt7915: fix twt table_mask to u16 in mt7915_dev
Felix Fietkau nbd@nbd.name mt76: fix tx status related use-after-free race on station removal
Felix Fietkau nbd@nbd.name mt76: do not attempt to reorder received 802.3 packets without agg session
Sean Wang sean.wang@mediatek.com mt76: mt7921: fix kernel crash at mt7921_pci_remove
Deren Wu deren.wu@mediatek.com mt76: fix antenna config missing in 6G cap
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: report rx mode value in mt7915_mac_fill_rx_rate
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: do not pass data pointer to mt7915_mcu_muru_debug_set
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: fix possible NULL pointer dereference in mt7915_mac_fill_rx_vector
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: fix possible uninitialized pointer dereference in mt7986_wmac_gpio_setup
Christophe JAILLET christophe.jaillet@wanadoo.fr mt76: mt7921: Fix the error handling path of mt7921_pci_probe()
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: fix unbounded shift in mt7915_mcu_beacon_mbss
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: honor pm user configuration in mt7921_sniffer_interface_iter
Felix Fietkau nbd@nbd.name mt76: mt7915: fix DBDC default band selection on MT7915D
Miaoqian Lin linmq006@gmail.com media: exynos4-is: Fix PM disable depth imbalance in fimc_is_probe
Christophe JAILLET christophe.jaillet@wanadoo.fr media: aspeed: Fix an error handling path in aspeed_video_probe()
Josh Poimboeuf jpoimboe@kernel.org scripts/faddr2line: Fix overlapping text section failures
Phil Auld pauld@redhat.com kselftest/cgroup: fix test_stress.sh to use OUTPUT dir
Bart Van Assche bvanassche@acm.org block: Fix the bio.bi_opf comment
Miaoqian Lin linmq006@gmail.com ASoC: samsung: Fix refcount leak in aries_audio_probe
Christoph Hellwig hch@lst.de dma-direct: don't fail on highmem CMA pages in dma_direct_alloc_pages
Pierre Gondois Pierre.Gondois@arm.com PM: EM: Decrement policy counter
Miaoqian Lin linmq006@gmail.com regulator: pfuze100: Fix refcount leak in pfuze_parse_regulators_dt
Miaoqian Lin linmq006@gmail.com ASoC: mxs-saif: Fix refcount leak in mxs_saif_probe
Miaoqian Lin linmq006@gmail.com ASoC: imx-hdmi: Fix refcount leak in imx_hdmi_probe
Miaoqian Lin linmq006@gmail.com ASoC: fsl: Fix refcount leak in imx_sgtl5000_probe
Basavaraj Natikar Basavaraj.Natikar@amd.com HID: amd_sfh: Modify the hid name
Basavaraj Natikar Basavaraj.Natikar@amd.com HID: amd_sfh: Modify the bus name
Ajay Singh ajay.kathat@microchip.com wilc1000: fix crash observed in AP mode with cfg80211_register_netdevice()
James Smart jsmart2021@gmail.com scsi: lpfc: Fix dmabuf ptr assignment in lpfc_ct_reject_event()
James Smart jsmart2021@gmail.com scsi: lpfc: Fix element offset in __lpfc_sli_release_iocbq_s4()
Baochen Qiang quic_bqiang@quicinc.com ath11k: Don't check arvif->is_started before sending management frames
Ravi Bangoria ravi.bangoria@amd.com perf/amd/ibs: Use interrupt regs ip for stack unwinding
Jerome Marchand jmarchan@redhat.com samples: bpf: Don't fail for a missing VMLINUX_BTF when VMLINUX_H is provided
Konrad Dybcio konrad.dybcio@somainline.org regulator: qcom_smd: Fix up PM8950 regulator configuration
Viresh Kumar viresh.kumar@linaro.org Revert "cpufreq: Fix possible race in cpufreq online error path"
Andrii Nakryiko andrii@kernel.org selftests/bpf: Prevent skeleton generation race
Yang Yingliang yangyingliang@huawei.com spi: spi-fsl-qspi: check return value after calling platform_get_resource_byname()
Andreas Gruenbacher agruenba@redhat.com iomap: iomap_write_failed fix
Mark Rutland mark.rutland@arm.com arm64: stackleak: fix current_top_of_stack()
Xiaomeng Tong xiam0nd.tong@gmail.com media: uvcvideo: Fix missing check to determine if element is found in list
Dan Carpenter dan.carpenter@oracle.com drm/msm: return an error pointer in msm_gem_prime_get_sg_table()
Jessica Zhang quic_jesszhan@quicinc.com drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is detected
Jessica Zhang quic_jesszhan@quicinc.com drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is detected
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dp: fix event thread stuck in wait_event after kthread_stop()
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dsi: fix address for second DSI PHY on SDM660
Vinod Polimera quic_vpolimer@quicinc.com drm/msm/disp/dpu1: avoid clearing hw interrupts if hw_intr is null during drm uninit
Ilkka Koskinen ilkka@os.amperecomputing.com ACPI: AGDI: Fix missing prototype warning for acpi_agdi_init()
Peter Zijlstra peterz@infradead.org linkage: Fix issue with missing symbol size
H. Nikolaus Schaller hns@goldelico.com wl1251: dynamically allocate memory used for DMA
Zev Weiss zev@bewilderbeest.net regulator: core: Fix enable_count imbalance with EXCLUSIVE_GET
Tong Tiangen tongtiangen@huawei.com arm64: fix types in copy_highpage()
Randy Dunlap rdunlap@infradead.org x86/mm: Cleanup the control_va_addr_alignment() __setup handler
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org irqchip/aspeed-scu-ic: Fix irq_of_parse_and_map() return value
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org irqchip/aspeed-i2c-ic: Fix irq_of_parse_and_map() return value
Daniel Thompson daniel.thompson@linaro.org irqchip/exiu: Fix acknowledgment of edge triggered interrupts
Randy Dunlap rdunlap@infradead.org x86: Fix return value of __setup handlers
Johannes Berg johannes.berg@intel.com nl80211: don't hold RTNL in color change request
Christoph Hellwig hch@lst.de virtio_blk: fix the discard_granularity and discard_alignment queue limits
James Clark james.clark@arm.com perf tools: Use Python devtools for version autodetection rather than runtime
Ian Abbott abbotti@mev.co.uk spi: cadence-quadspi: fix Direct Access Mode disable for SoCFPGA
Yang Yingliang yangyingliang@huawei.com drm/rockchip: vop: fix possible null-ptr-deref in vop_bind()
Daniel Latypov dlatypov@google.com kunit: fix debugfs code to use enum kunit_status, not bool
Luca Weiss luca@z3ntu.xyz drm/msm: Fix null pointer dereferences without iommu
Pin-Yen Lin treapking@chromium.org drm/bridge: it6505: Send DPCD SET_POWER to downstream
Jagan Teki jagan@amarulasolutions.com drm/panel: panel-simple: Fix proper bpc for AM-1280800N3TZQW-T00H
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm: add missing include to msm_drv.c
Lv Ruyi lv.ruyi@zte.com.cn drm/msm/hdmi: fix error check return value of irq_of_parse_and_map()
Yang Yingliang yangyingliang@huawei.com drm/msm/hdmi: check return value after calling platform_get_resource_byname()
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dsi: fix error checks and return values for DSI xmit functions
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dp: do not stop transmitting phy test pattern during DP phy compliance test
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dp: reset DP controller before transmit phy test pattern
Lv Ruyi lv.ruyi@zte.com.cn drm/msm/dp: fix error check return value of irq_of_parse_and_map()
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dp: stop event kernel thread when DP unbind
Vinod Polimera quic_vpolimer@quicinc.com drm/msm/disp/dpu1: set vbif hw config to NULL to avoid use after memory free during pm runtime resume
Yang Jihong yangjihong1@huawei.com perf tools: Add missing headers needed by util/data.h
Nicolas Frattaroli frattaroli.nicolas@gmail.com ASoC: rk3328: fix disabling mclk on pclk probe failure
Josh Poimboeuf jpoimboe@redhat.com x86/speculation: Add missing prototype for unpriv_ebpf_notify()
Yang Yingliang yangyingliang@huawei.com mtd: rawnand: intel: fix possible null-ptr-deref in ebu_nand_probe()
Yang Yingliang yangyingliang@huawei.com mtd: rawnand: cadence: fix possible null-ptr-deref in cadence_nand_dt_probe()
Matthieu Baerts matthieu.baerts@tessares.net x86/pm: Fix false positive kmemleak report in msr_build_context()
Chen-Tsung Hsieh chentsung@chromium.org mtd: spi-nor: core: Check written SR value in spi_nor_write_16bit_sr_and_check()
Andrii Nakryiko andrii@kernel.org libbpf: Fix logic for finding matching program for CO-RE relocation
Colin Ian King colin.king@intel.com selftests/resctrl: Fix null pointer dereference on open failed
Colin Ian King colin.king@intel.com drm/v3d: Fix null pointer dereference of pointer perfmon
Kiwoong Kim kwmad.kim@samsung.com scsi: ufs: core: Exclude UECxx from SFR dump list
Bart Van Assche bvanassche@acm.org scsi: ufs: qcom: Fix ufs_qcom_resume()
Dan Carpenter dan.carpenter@oracle.com scsi: iscsi: Fix harmless double shift bug
Kuogee Hsieh quic_khsieh@quicinc.com drm/msm/dpu: adjust display_v_end for eDP and DP
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm: properly add and remove internal bridges
Yuanchu Xie yuanchu@google.com selftests/damon: add damon to selftests root Makefile
Nuno Sá nuno.sa@analog.com of: overlay: do not break notify on NOTIFY_{OK|STOP}
Luca Ceresoli luca.ceresoli@bootlin.com spi: rockchip: fix missing error on unsupported SPI_CS_HIGH
Amir Goldstein amir73il@gmail.com fsnotify: fix wrong lockdep annotations
Amir Goldstein amir73il@gmail.com inotify: show inotify mask flags in proc fdinfo
Bjørn Mork bjorn@mork.no mtdblock: warn if opened on NAND
Colin Ian King colin.king@intel.com ALSA: pcm: Check for null pointer of pointer substream before dereferencing it
Marek Vasut marex@denx.de drm/panel: simple: Add missing bus flags for Innolux G070Y2-L01
Laurent Pinchart laurent.pinchart@ideasonboard.com media: imx: imx-mipi-csis: Fix active format initialization on source pad
Laurent Pinchart laurent.pinchart@ideasonboard.com media: imx: imx-mipi-csis: Rename csi_state to mipi_csis_device
Chen-Yu Tsai wenst@chromium.org media: hantro: Empty encoder capture buffers by default
Chen-Yu Tsai wenst@chromium.org media: hantro: Implement support for encoder commands
Ming Qian ming.qian@nxp.com media: amphion: fix decoder's interlaced field
Laurentiu Palcu laurentiu.palcu@oss.nxp.com media: i2c: max9286: fix kernel oops when removing module
Dan Carpenter dan.carpenter@oracle.com ath9k_htc: fix potential out of bounds access with invalid rxstatus->rs_keyix
John Ogness john.ogness@linutronix.de printk: wake waiters for safe and NMI contexts
John Ogness john.ogness@linutronix.de printk: add missing memory barrier to wake_up_klogd()
Schspa Shi schspa@gmail.com cpufreq: Fix possible race in cpufreq online error path
Robert Foss robert.foss@linaro.org drm/bridge: Fix it6505 Kconfig DRM_DP_AUX_BUS dependency
Zheng Yongjun zhengyongjun3@huawei.com spi: img-spfi: Fix pm_runtime_get_sync() error checking
Chengming Zhou zhouchengming@bytedance.com sched/psi: report zeroes for CPU full at the system level
Chengming Zhou zhouchengming@bytedance.com sched/fair: Fix cfs_rq_clock_pelt() for throttled cfs_rq
Marco Elver elver@google.com signal: Deliver SIGTRAP on perf event asynchronously if blocked
Nícolas F. R. A. Prado nfraprado@collabora.com drm/mediatek: dpi: Use mt8183 output formats for mt8192
Wei Yongjun weiyongjun1@huawei.com regulator: da9121: Fix uninit-value in da9121_assign_chip_model()
Miaoqian Lin linmq006@gmail.com drm/bridge: Fix error handling in analogix_dp_probe
Miaoqian Lin linmq006@gmail.com HID: elan: Fix potential double free in elan_input_configured
Jonathan Teh jonathan.teh@outlook.com HID: hid-led: fix maximum brightness for Dream Cheeky
Zheyu Ma zheyuma97@gmail.com mtd: rawnand: denali: Use managed device resources
Nícolas F. R. A. Prado nfraprado@collabora.com drm/bridge: anx7625: Use uint8 for lane-swing arrays
Stanislav Fomichev sdf@google.com bpf: Move rcu lock management out of BPF_PROG_RUN routines
Tyler Hicks tyhicks@linux.microsoft.com EDAC/dmc520: Don't print an error for each unconfigured interrupt line
Arnd Bergmann arnd@arndb.de drbd: fix duplicate array initializer
Christoph Hellwig hch@lst.de drbd: use bdev_alignment_offset instead of queue_alignment_offset
Christoph Hellwig hch@lst.de drbd: use bdev based limit helpers in drbd_send_sizes
Christoph Hellwig hch@lst.de drbd: remove assign_p_sizes_qlim
Christoph Hellwig hch@lst.de target: remove an incorrect unmap zeroes data deduction
Ansuel Smith ansuelsmth@gmail.com net: dsa: qca8k: correctly handle mdio read error
Gavin Wan Gavin.Wan@amd.com drm/amd/amdgpu: Remove static from variable in RLCG Reg RW
Andy Shevchenko andriy.shevchenko@linux.intel.com device property: Allow error pointer to be passed to fwnode APIs
Jan Kiszka jan.kiszka@siemens.com efi: Add missing prototype for efi_capsule_setup_info
Javier Martinez Canillas javierm@redhat.com efi: Allow to enable EFI runtime services by default on RT
Kevin Hao haokexin@gmail.com cpufreq: governor: Use kobject release() method to free dbs_data
Lin Ma linma@zju.edu.cn NFC: NULL out the dev->rfkill to prevent UAF
Lv Ruyi lv.ruyi@zte.com.cn ixp4xx_eth: fix error check return value of platform_get_irq()
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: dsa: mt7530: 1G can also support 1000BASE-X link mode
YueHaibing yuehaibing@huawei.com net: ethernet: ti: am65-cpsw: Fix build error without PHYLINK
Paul E. McKenney paulmck@kernel.org scftorture: Fix distribution of short handler delays
Miaoqian Lin linmq006@gmail.com spi: spi-ti-qspi: Fix return value handling of wait_for_completion_timeout
Yongqiang Sun yongqiang.sun@amd.com drm/amd/amdgpu: Fix asm/hypervisor.h build error.
Jiasheng Jiang jiasheng@iscas.ac.cn drm: mali-dp: potential dereference of null pointer
Zhou Qingyang zhou1615@umn.edu drm/komeda: Fix an undefined behavior bug in komeda_plane_add()
Johannes Berg johannes.berg@intel.com nl80211: show SSID for P2P_GO interfaces
Paolo Abeni pabeni@redhat.com mptcp: reset the packet scheduler on PRIO change
Paolo Abeni pabeni@redhat.com mptcp: reset the packet scheduler on incoming MP_PRIO
Paolo Abeni pabeni@redhat.com mptcp: optimize release_cb for the common case
Maciej W. Rozycki macro@orcam.me.uk x86/PCI: Fix ALi M1487 (IBC) PIRQ router link value interpretation
Andrii Nakryiko andrii@kernel.org libbpf: Don't error out on CO-RE relos for overriden weak subprogs
Maxime Ripard maxime@cerno.tech drm/vc4: txp: Force alpha to be 0xff if it's disabled
Maxime Ripard maxime@cerno.tech drm/vc4: txp: Don't set TXP_VSTART_AT_EOF
Maxime Ripard maxime@cerno.tech drm/vc4: hvs: Reset muxes at probe time
Yongqiang Sun yongqiang.sun@amd.com drm/amd/amdgpu: Only reserve vram for firmware with vega9 MS_HYPERV host.
Miles Chen miles.chen@mediatek.com drm/mediatek: Fix mtk_cec_mask()
Maxime Ripard maxime@cerno.tech drm/vc4: hvs: Fix frame count register readout
Maxime Ripard maxime@cerno.tech drm/vc4: kms: Take old state core clock rate into account
Chen-Yu Tsai wenst@chromium.org drm/mediatek: Fix DPI component detection for MT8192
Rex-BC Chen rex-bc.chen@mediatek.com drm/mediatek: Add vblank register/unregister callback functions
Ammar Faizi ammarfaizi2@gnuweeb.org x86/delay: Fix the wrong asm constraint in delay_loop()
Akira Yokosawa akiyks@gmail.com docs: driver-api/thermal/intel_dptf: Use copyright symbol
Miaoqian Lin linmq006@gmail.com ASoC: mediatek: Fix missing of_node_put in mt2701_wm8960_machine_probe
Miaoqian Lin linmq006@gmail.com ASoC: mediatek: Fix error handling in mt8173_max98090_dev_probe
Peter Ujfalusi peter.ujfalusi@linux.intel.com ASoC: SOF: ipc3-topology: Set scontrol->priv to NULL after freeing it
Hui Wang hui.wang@canonical.com ASoC: cs35l41: Fix an out-of-bounds access in otp_packed_element_t
Srinivasa Rao Mandadapu quic_srivasam@quicinc.com ASoC: codecs: Fix error handling in power domain init and exit handlers
Kuldeep Singh singh.kuldeep87k@gmail.com spi: qcom-qspi: Add minItems to interconnect-names
Chuanhong Guo gch981213@gmail.com mtd: spinand: gigadevice: fix Quad IO for GD5F1GQ5UExxG
Marek Vasut marex@denx.de drm: bridge: icn6211: Fix HFP_HSW_HBP_HI and HFP_MIN handling
Marek Vasut marex@denx.de drm: bridge: icn6211: Fix register layout
Lucas Stach l.stach@pengutronix.de drm/bridge: adv7511: clean up CEC adapter when probe fails
Yang Yingliang yangyingliang@huawei.com drm/bridge: anx7625: add missing destroy_workqueue() in anx7625_i2c_probe()
Jani Nikula jani.nikula@intel.com drm/edid: fix invalid EDID extension block filtering
Wenli Looi wlooi@ucalgary.ca ath9k: fix ar9003_get_eepmisc
YueHaibing yuehaibing@huawei.com drm/bridge: it6505: Fix build error
Nicolas Belin nbelin@baylibre.com drm: bridge: it66121: Fix the register page length
Niels Dossche dossche.niels@gmail.com ath11k: acquire ab->base_lock in unassign when finding the peer by addr
Zack Rusin zackr@vmware.com drm/vmwgfx: Fix an invalid read
Chuansheng Liu chuansheng.liu@intel.com fbdev: defio: fix the pagelist corruption
Geert Uytterhoeven geert@linux-m68k.org drm/ssd130x: Reduce temporary buffer sizes
Geert Uytterhoeven geert@linux-m68k.org drm/ssd130x: Fix rectangle updates
Geert Uytterhoeven geert@linux-m68k.org drm/format-helper: Fix XRGB888 to monochrome conversion
Geert Uytterhoeven geert@linux-m68k.org drm/format-helper: Rename drm_fb_xrgb8888_to_mono_reversed()
YueHaibing yuehaibing@huawei.com drm/solomon: Make DRM_SSD130X depends on MMU
Chen-Yu Tsai wens@csie.org drm: ssd130x: Always apply segment remap setting
Chen-Yu Tsai wens@csie.org drm: ssd130x: Fix COM scan direction register mask
Tom Rix trix@redhat.com drm/bridge: anx7625: check the return on anx7625_aux_trans
Noralf Trønnes noralf@tronnes.org dt-bindings: display: sitronix, st7735r: Fix backlight in example
Wan Jiabing wanjiabing@vivo.com drm/omap: fix NULL but dereferenced coccicheck error
Dan Carpenter dan.carpenter@oracle.com drm/selftests: missing error code in igt_buddy_alloc_smoke()
Nikita Yushchenko nikita.yoush@cogentembedded.com drm/bridge_connector: enable HPD by default if supported
Linus Torvalds torvalds@linux-foundation.org drm: fix EDID struct for old ARM OABI format
Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Input: gpio-keys - cancel delayed work only in case of GPIO
Shyam Prasad N sprasad@microsoft.com cifs: do not use tcpStatus after negotiate completes
Douglas Miller doug.miller@cornelisnetworks.com RDMA/hfi1: Prevent panic when SDMA is disabled
Steve French stfrench@microsoft.com smb3: check for null tcon
Vasily Averin vasily.averin@linux.dev fanotify: fix incorrect fmode_t casts
Peng Wu wupeng58@huawei.com powerpc/iommu: Add missing of_node_put in iommu_init_early_dart
Finn Thain fthain@linux-m68k.org macintosh/via-pmu: Fix build failure when CONFIG_INPUT is disabled
Lv Ruyi lv.ruyi@zte.com.cn powerpc/powernv: fix missing of_node_put in uv_init()
Lv Ruyi lv.ruyi@zte.com.cn powerpc/xics: fix refcount leak in icp_opal_init()
Haren Myneni haren@linux.ibm.com powerpc/powernv/vas: Assign real address to rx_fifo in vas_rx_win_attr
Enzo Matsumiya ematsumiya@suse.de cifs: return ENOENT for DFS lookup_cache_entry()
Vasily Averin vasily.averin@linux.dev tracing: incorrect isolate_mote_t cast in mm_vmscan_lru_isolate
Matthew Wilcox (Oracle) willy@infradead.org alpha: fix alloc_zeroed_user_highpage_movable()
Nicholas Piggin npiggin@gmail.com KVM: PPC: Book3S HV Nested: L2 LPCR should inherit L1 LPES setting
Parshuram Thombare pthombar@cadence.com PCI: cadence: Clear FLR in device capabilities register
Yicong Yang yangyicong@hisilicon.com PCI: Avoid pci_dev_lock() AB/BA deadlock with sriov_numvfs_store()
Laurent Dufour ldufour@linux.ibm.com powerpc/rtas: Keep MSR[RI] set when calling RTAS
Conor Dooley conor.dooley@microchip.com PCI: microchip: Add missing chained_irq_enter()/exit() calls
Viresh Kumar viresh.kumar@linaro.org cpufreq: Avoid unnecessary frequency updates due to mismatch
Peng Wu wupeng58@huawei.com ARM: hisi: Add missing of_node_put after of_find_compatible_node
Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com arm64: dts: qcom: sc7280-qcard: Configure CTS pin to bias-bus-hold for bluetooth
Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com arm64: dts: qcom: sc7280-idp: Configure CTS pin to bias-bus-hold for bluetooth
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: exynos: add atmel,24c128 fallback to Samsung EEPROM
Peng Wu wupeng58@huawei.com ARM: versatile: Add missing of_node_put in dcscb_init
Yang Yingliang yangyingliang@huawei.com pinctrl: renesas: rzn1: Fix possible null-ptr-deref in sh_pfc_map_resources()
OGAWA Hirofumi hirofumi@mail.parknet.co.jp fat: add ratelimit to fat*_ent_bread()
Hari Bathini hbathini@linux.ibm.com powerpc/fadump: Fix fadump to work with a different endian capture kernel
Janusz Krzysztofik jmkrzyszt@gmail.com ARM: OMAP1: clock: Fix UART rate reporting algorithm
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Move generic implicit fb quirk entries into quirks.c
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Add quirk bits for enabling/disabling generic implicit fb
Joel Selvaraj jo@jsfamily.in arm64: dts: qcom: sdm845-xiaomi-beryllium: fix typo in panel's vddio-supply property
Zixuan Fu r33s3n6@gmail.com fs: jfs: fix possible NULL pointer dereference in dbFree()
QintaoShen unSimple1993@163.com soc: ti: ti_sci_pm_domains: Check for null return of devm_kcalloc
Marco Chiappero marco.chiappero@intel.com crypto: qat - fix off-by-one error in PFVF debug print
Gilad Ben-Yossef gilad@benyossef.com crypto: ccree - use fine grained DMA mapping dir
Brian Norris briannorris@chromium.org PM / devfreq: rk3399_dmc: Disable edev on remove()
Konrad Dybcio konrad.dybcio@somainline.org arm64: dts: qcom: msm8994: Fix BLSP[12]_DMA channels count
Konrad Dybcio konrad.dybcio@somainline.org arm64: dts: qcom: msm8994: Fix the cont_splash_mem address
Mario Limonciello mario.limonciello@amd.com ASoC: amd: Add driver data to acp6x machine driver
Krzysztof Kozlowski krzk@kernel.org ARM: dts: s5pv210: align DMA channels with dtschema
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: socfpga: align interrupt controller node name with dtschema
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ARM: dts: ox820: align interrupt controller node name with dtschema
Mika Westerberg mika.westerberg@linux.intel.com PCI/ASPM: Make Intel DG2 L1 acceptable latency unlimited
Niels Dossche dossche.niels@gmail.com IB/rdmavt: add missing locks in rvt_ruc_loopback
Daniel Latypov dlatypov@google.com kunit: fix executor OOM error handling logic on non-UML
Bodo Stroesser bostroesser@gmail.com scsi: target: tcmu: Avoid holding XArray lock when calling lock_page
Linus Torvalds torvalds@linux-foundation.org linux/types.h: reinstate "__bitwise__" macro for user space use
Bob Peterson rpeterso@redhat.com gfs2: use i_lock spin_lock for inode qadata
Yonghong Song yhs@fb.com selftests/bpf: fix btf_dump/btf_dump due to recent clang change
Uwe Kleine-König u.kleine-koenig@pengutronix.de char: tpm: cr50_i2c: Suppress duplicated error message in .remove()
Jakub Kicinski kuba@kernel.org eth: tg3: silence the GCC 12 array-bounds warning
David Howells dhowells@redhat.com afs: Adjust ACK interpretation to try and cope with NAT
David Howells dhowells@redhat.com rxrpc, afs: Fix selection of abort codes
David Howells dhowells@redhat.com rxrpc: Return an error to sendmsg if call failed
Mårten Lindahl marten.lindahl@axis.com hwmon: (pmbus) Add get_voltage/set_voltage ops
Geert Uytterhoeven geert@linux-m68k.org m68k: atari: Make Atari ROM port I/O write macros return void
Yuntao Wang ytcoode@gmail.com selftests/bpf: Add missing trampoline program type to trampoline_count test
Alex Elder elder@linaro.org net: ipa: ignore endianness if there is no header
Borislav Petkov bp@suse.de x86/microcode: Add explicit CPU vendor dependency
Vincent Mailhol mailhol.vincent@wanadoo.fr can: mcp251xfd: silence clang's -Wunaligned-access warning
Chaitanya Kulkarni kch@nvidia.com nvme: set non-mdts limits in nvme_scan_work
Pierre Gondois Pierre.Gondois@arm.com ACPI: CPPC: Assume no transition latency if no PCCT
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: rt1015p: remove dependency on GPIOLIB
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: max98357a: remove dependency on GPIOLIB
Laibin Qiu qiulaibin@huawei.com blk-throttle: Set BIO_THROTTLED when bio has been throttled
Andre Przywara andre.przywara@arm.com of/fdt: Ignore disabled memory nodes
Ping-Ke Shih pkshih@realtek.com rtw89: cfo: check mac_id to avoid out-of-bounds
Nicolas Dufresne nicolas.dufresne@collabora.com media: hantro: Stop using H.264 parameter pic_num
Kwanghoon Son k.son@samsung.com media: exynos4-is: Fix compile warning
Fabio Estevam festevam@denx.de net: phy: micrel: Allow probing without .driver_data
Daniel Latypov dlatypov@google.com kunit: tool: make parser stop overwriting status of suites w/ no_tests
Omar Sandoval osandov@fb.com btrfs: fix anon_dev leak in create_subvol()
Hans de Goede hdegoede@redhat.com drm/amdgpu: Move mutex_init(&smu->message_lock) to smu_early_init()
Sathishkumar S sathishkumar.sundararaju@amd.com drm/amd/pm: update smartshift powerboost calc for smu13
Sathishkumar S sathishkumar.sundararaju@amd.com drm/amd/pm: update smartshift powerboost calc for smu12
Xie Yongji xieyongji@bytedance.com nbd: Fix hung on disconnect request if socket is closed before
Lin Ma linma@zju.edu.cn ASoC: rt5645: Fix errorenous cleanup order
Smith, Kyle Miller (Nimble Kernel) kyles@hpe.com nvme-pci: fix a NULL pointer dereference in nvme_alloc_admin_tags
Jason A. Donenfeld Jason@zx2c4.com openrisc: start CPU timer early in boot
Yunfei Dong yunfei.dong@mediatek.com media: mediatek: vcodec: prevent kernel crash when rmmod mtk-vcodec-dec.ko
Pavan Chebbi pavan.chebbi@broadcom.com bnxt_en: Configure ptp filters during bnxt open
Zijun Hu quic_zijuhu@quicinc.com Bluetooth: btusb: Set HCI_QUIRK_BROKEN_ERR_DATA_REPORTING for QCA
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: btusb: Set HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN for QCA
Luiz Augusto von Dentz luiz.von.dentz@intel.com Bluetooth: HCI: Add HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN quirk
Lukas Wunner lukas@wunner.de usbnet: Run unregister_netdev() before unbind() again
Hans Verkuil hverkuil-cisco@xs4all.nl media: cec-adap.c: fix is_configuring state
Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp media: imon: reorganize serialization
Hans Verkuil hverkuil-cisco@xs4all.nl media: ccs-core.c: fix failure to call clk_disable_unprepare
Benjamin Gaignard benjamin.gaignard@collabora.com media: hantro: HEVC: unconditionnaly set pps_{cb/cr}_qp_offset values
Philipp Zabel p.zabel@pengutronix.de media: coda: limit frame interval enumeration to supported encoder frame sizes
Hangyu Hua hbh25y@gmail.com media: rga: fix possible memory leak in rga_probe
Felix Fietkau nbd@nbd.name mt76: fix encap offload ethernet type check
Felix Fietkau nbd@nbd.name mt76: mt7921: accept rx frames with non-standard VHT MCS10-11
Felix Fietkau nbd@nbd.name mt76: mt7915: accept rx frames with non-standard VHT MCS10-11
Dongliang Mu mudongliangabcd@gmail.com rtlwifi: Use pr_warn instead of WARN_ONCE
Daniel Latypov dlatypov@google.com kunit: bail out of test filtering logic quicker if OOM
Corey Minyard cminyard@mvista.com ipmi: Fix pr_fmt to avoid compilation issues
Corey Minyard cminyard@mvista.com ipmi: Add an intializer for ipmi_smi_msg struct
Corey Minyard cminyard@mvista.com ipmi:ssif: Check for NULL msg when handling events and messages
Mario Limonciello mario.limonciello@amd.com ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default
Zheng Bin zhengbin13@huawei.com ASoC: SOF: amd: add missing platform_device_unregister in acp_pci_rn_probe
Christian Brauner brauner@kernel.org fs: hold writers when changing mount's idmapping
Mikulas Patocka mpatocka@redhat.com dma-debug: change allocation mode from GFP_NOWAIT to GFP_ATIOMIC
Patrice Chotard patrice.chotard@foss.st.com spi: stm32-qspi: Fix wait_cmd timeout in APM mode
Hao Jia jiahao.os@bytedance.com sched/core: Avoid obvious double update_rq_clock warning
Ravi Bangoria ravi.bangoria@amd.com perf/amd/ibs: Cascade pmu init functions' return value
Heiko Carstens hca@linux.ibm.com s390/preempt: disable __preempt_count_add() optimization for PROFILE_ALL_BRANCHES
Eric Dumazet edumazet@google.com net: remove two BUG() from skb_checksum_help()
James Smart jsmart2021@gmail.com scsi: lpfc: Alter FPIN stat accounting logic
James Smart jsmart2021@gmail.com scsi: lpfc: Inhibit aborts if external loopback plug is inserted
Xiang Chen chenxiang66@hisilicon.com scsi: hisi_sas: Undo RPM resume for failed notify phy event for v3 HW
Brent Lu brent.lu@intel.com ASoC: Intel: sof_ssp_amp: fix no DMIC BE Link on Chromebooks
Gavin Li gavinl@nvidia.com net/mlx5: Increase FW pre-init timeout for health recovery
Charles Keepax ckeepax@opensource.cirrus.com ASoC: tscs454: Add endianness flag in snd_soc_component_driver
Zhen Lei thunder.leizhen@huawei.com of: Support more than one crash kernel regions for kexec -s
Thierry Reding treding@nvidia.com drm/tegra: gem: Do not try to dereference ERR_PTR()
Dongliang Mu mudongliangabcd@gmail.com HID: bigben: fix slab-out-of-bounds Write in bigben_probe
Jacob Keller jacob.e.keller@intel.com ice: always check VF VSI pointer values
Nícolas F. R. A. Prado nfraprado@collabora.com regulator: mt6315: Enforce regulator-compatible, not name
Alice Wong shiwei.wong@amd.com drm/amdgpu/ucode: Remove firmware load type check in amdgpu_ucode_free_bo
Alex Deucher alexander.deucher@amd.com drm/amdgpu/psp: move PSP memory alloc from hw_init to sw_init
Petr Machata petrm@nvidia.com mlxsw: Treat LLDP packets as control
Petr Machata petrm@nvidia.com mlxsw: spectrum_dcb: Do not warn about priority changes
Peter Ujfalusi peter.ujfalusi@linux.intel.com ASoC: SOF: ipc3-topology: Correct get_control_data for non bytes payload
Mark Brown broonie@kernel.org ASoC: dapm: Don't fold register value changes into notifications
Mark Bloch mbloch@nvidia.com net/mlx5: fs, delete the FTE when there are no rules attached to it
Ziyang Xuan william.xuanziyang@huawei.com net/mlx5: use kvfree() for kvzalloc() in mlx5_ct_fs_smfs_matcher_create
jianghaoran jianghaoran@kylinos.cn ipv6: Don't send rs packets to the interface of ARPHRD_TUNNEL
Xiaoguang Wang xiaoguang.wang@linux.alibaba.com scsi: target: tcmu: Fix possible data corruption
Wen Gong quic_wgong@quicinc.com ath11k: fix warning of not found station for bssid in message
Max Filippov jcmvbkbc@gmail.com xtensa: move trace_hardirqs_off call back to entry.S
Jessica Zhang quic_jesszhan@quicinc.com drm/msm/dpu: Clean up CRC debug logs
Lv Ruyi lv.ruyi@zte.com.cn drm: msm: fix error check return value of irq_of_parse_and_map()
Alexandru Elisei alexandru.elisei@arm.com arm64: compat: Do not treat syscall number as ESR_ELx for a bad syscall
Abhishek Kumar kuabhs@chromium.org ath10k: skip ath10k_halt during suspend for driver state RESTARTING
Evan Quan evan.quan@amd.com drm/amd/pm: fix the compile warning
Mukul Joshi mukul.joshi@amd.com drm/amdkfd: Fix circular lock dependency warning
Steven Price steven.price@arm.com drm/plane: Move range check for format_count earlier
Hans de Goede hdegoede@redhat.com ASoC: Intel: bytcr_rt5640: Add quirk for the HP Pro Tablet 408
Hari Chandrakanthan quic_haric@quicinc.com ath11k: disable spectral scan during spectral deinit
James Smart jsmart2021@gmail.com scsi: lpfc: Fix resource leak in lpfc_sli4_send_seq_to_ulp()
Minghao Chi chi.minghao@zte.com.cn scsi: ufs: Use pm_runtime_resume_and_get() instead of pm_runtime_get_sync()
Haohui Mai ricetons@gmail.com drm/amdgpu/sdma: Fix incorrect calculations of the wptr of the doorbells
Lv Ruyi lv.ruyi@zte.com.cn scsi: megaraid: Fix error check return value of register_chrdev()
Vignesh Raghavendra vigneshr@ti.com drivers: mmc: sdhci_am654: Add the quirk to set TESTCD bit
Aidan MacDonald aidanmacdonald.0x0@gmail.com mmc: jz4740: Apply DMA engine limits to maximum segment size
Heming Zhao heming.zhao@suse.com md/bitmap: don't set sb values if can't pass sanity check
Zheyu Ma zheyuma97@gmail.com media: cx25821: Fix the warning when removing the module
Zheyu Ma zheyuma97@gmail.com media: pci: cx23885: Fix the error handling in cx23885_initdev()
Vikash Garodia quic_vgarodia@quicinc.com media: venus: do not queue internal buffers from previous sequence
Luca Weiss luca.weiss@fairphone.com media: venus: hfi: avoid null dereference in deinit
Zheyu Ma zheyuma97@gmail.com media: i2c: dw9714: Disable the regulator when the driver fails to probe
Sakari Ailus sakari.ailus@linux.intel.com media: Revert "media: dw9768: activate runtime PM and turn off device"
Thibaut VARÈNE hacks+kernel@slashdirt.org ath9k: fix QCA9561 PA bias level
Radhey Shyam Pandey radhey.shyam.pandey@xilinx.com net: macb: In ZynqMP initialization make SGMII phy configuration optional
Kuninori Morimoto kuninori.morimoto.gx@renesas.com ASoC: rsnd: care return value from rsnd_node_fixed_index()
Kuninori Morimoto kuninori.morimoto.gx@renesas.com ASoC: rsnd: care default case on rsnd_ssiu_busif_err_status_clear()
Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp drm/amd/pm: fix double free in si_parse_power_table()
Huang Rui ray.huang@amd.com drm/amdgpu/pm: fix the null pointer while the smu is disabled
Ulf Hansson ulf.hansson@linaro.org cpuidle: PSCI: Improve support for suspend-to-RAM for PSCI OSI mode
James Smart jsmart2021@gmail.com scsi: lpfc: Fix call trace observed during I/O with CMF enabled
James Smart jsmart2021@gmail.com scsi: lpfc: Protect memory leak for NPIV ports sending PLOGI_RJT
James Smart jsmart2021@gmail.com scsi: lpfc: Fix null pointer dereference after failing to issue FLOGI and PLOGI
James Smart jsmart2021@gmail.com scsi: lpfc: Fix SCSI I/O completion and abort handler deadlock
James Smart jsmart2021@gmail.com scsi: lpfc: Move cfg_log_verbose check before calling lpfc_dmp_dbg()
Christoph Hellwig hch@lst.de loop: implement ->free_disk
Eric Dumazet edumazet@google.com tcp: consume incoming skb leading to a reset
Len Brown len.brown@intel.com tools/power turbostat: fix ICX DRAM power numbers
Biju Das biju.das.jz@bp.renesas.com spi: spi-rspi: Remove setting {src,dst}_{addr,addr_width} based on DMA direction
Po-Hao Huang phhuang@realtek.com rtw88: 8821c: fix debugfs rssi value
Po-Hao Huang phhuang@realtek.com rtw88: fix incorrect frequency reported
Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com ALSA: jack: Access input_dev under mutex
Haowen Bai baihaowen@meizu.com sfc: ef10: Fix assigning negative value to unsigned variable
Paul E. McKenney paulmck@kernel.org rcu: Make TASKS_RUDE_RCU select IRQ_WORK
Paul E. McKenney paulmck@kernel.org rcu-tasks: Handle sparse cpu_possible_mask in rcu_tasks_invoke_cbs()
Padmanabha Srinivasaiah treasure4paddy@gmail.com rcu-tasks: Fix race in schedule and flush work
Saaem Rizvi syerizvi@amd.com drm/amd/display: Disabling Z10 on DCN31
Liviu Dudau liviu.dudau@arm.com drm/komeda: return early if drm_universal_plane_init() fails.
Peter Seiderer ps.report@gmx.net mac80211: minstrel_ht: fix where rate stats are stored (fixes debugfs output)
Runqing Yang rainkin1993@gmail.com libbpf: Fix a bug with checking bpf_probe_read_kernel() support in old kernels
Kirill A. Shutemov kirill.shutemov@linux.intel.com ACPICA: Avoid cache flush inside virtual machines
Mike Travis mike.travis@hpe.com x86/platform/uv: Update TSC sync state for UV5
Daniel Vetter daniel.vetter@ffwll.ch fbcon: Consistently protect deferred_takeover with console_lock()
Niels Dossche dossche.niels@gmail.com ipv6: fix locking issues with loops over idev->addr_list
Haowen Bai baihaowen@meizu.com ipw2x00: Fix potential NULL dereference in libipw_xmit()
Haowen Bai baihaowen@meizu.com b43: Fix assigning negative value to unsigned variable
Haowen Bai baihaowen@meizu.com b43legacy: Fix assigning negative value to unsigned variable
Niels Dossche dossche.niels@gmail.com mwifiex: add mutex lock for call in mwifiex_dfs_chan_sw_work_queue
Po Hao Huang phhuang@realtek.com rtw89: fix misconfiguration on hw_scan channel time
Zong-Zhe Yang kevin_yang@realtek.com rtw89: ser: fix CAM leaks occurring in L2 reset
Yuntao Wang ytcoode@gmail.com selftests/bpf: Fix file descriptor leak in load_kallsyms()
Karthikeyan Kathirvel quic_kathirve@quicinc.com ath11k: Change max no of active probe SSID and BSSID to fw capability
Quentin Monnet quentin@isovalent.com selftests/bpf: Fix parsing of prog types in UAPI hdr for bpftool sync
Nikolay Borisov nborisov@suse.com selftests/bpf: Fix vfs_link kprobe definition
Liu Zixian liuzixian4@huawei.com drm/virtio: fix NULL pointer dereference in virtio_gpu_conn_get_modes
Wen Gong quic_wgong@quicinc.com ath11k: fix the warning of dev_wake in mhi_pm_disable_transition()
Zack Rusin zackr@vmware.com drm/vmwgfx: validate the screen formats
Arunpravin Arunpravin.PaneerSelvam@amd.com drm/selftests: fix a shift-out-of-bounds bug
Tejas Upadhyay tejaskumarx.surendrakumar.upadhyay@intel.com iommu/vt-d: Add RPLS to quirk list to skip TE disabling
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: fix comparison of alloc_offset vs meta_write_pointer
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: finish block group when there are no more allocatable bytes left
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: zone finish unused block group
Naohiro Aota naohiro.aota@wdc.com btrfs: zoned: properly finish block group on metadata write
Filipe Manana fdmanana@suse.com btrfs: fix deadlock between concurrent dio writes when low on free data space
Qu Wenruo wqu@suse.com btrfs: fix the error handling for submit_extent_page() for btrfs_do_readpage()
Qu Wenruo wqu@suse.com btrfs: repair super block num_devices automatically
Qu Wenruo wqu@suse.com btrfs: return correct error number for __extent_writepage_io()
Qu Wenruo wqu@suse.com btrfs: add "0x" prefix for unsupported optional features
Eric W. Biederman ebiederm@xmission.com ptrace: Reimplement PTRACE_KILL by always sending SIGKILL
Eric W. Biederman ebiederm@xmission.com ptrace/xtensa: Replace PT_SINGLESTEP with TIF_SINGLESTEP
Eric W. Biederman ebiederm@xmission.com ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP
Eric W. Biederman ebiederm@xmission.com kthread: Don't allocate kthread_struct for init and umh
Kristen Carlson Accardi kristen@linux.intel.com x86/sgx: Set active memcg prior to shmem allocation
Baoquan He bhe@redhat.com x86/kexec: fix memory leak of elf header buffer
Kan Liang kan.liang@linux.intel.com perf/x86/intel: Fix event constraints for ICL
Ammar Faizi ammarfaizi2@gnuweeb.org x86/MCE/AMD: Fix memory leak when threshold_create_bank() fails
Michael Niewöhner linux@mniewoehner.de platform/x86: intel-hid: fix _DSM function index handling
Mathias Nyman mathias.nyman@linux.intel.com xhci: Allow host runtime PM as default for Intel Alder Lake N xHCI
Kishon Vijay Abraham I kishon@ti.com xhci: Set HCD flag to defer primary roothub registration
Ronnie Sahlberg lsahlber@redhat.com cifs: when extending a file with falloc we should make files not-sparse
Ronnie Sahlberg lsahlber@redhat.com cifs: fix potential double free during failed mount
Paulo Alcantara pc@cjr.nz cifs: fix ntlmssp on old servers
Enzo Matsumiya ematsumiya@suse.de cifs: don't call cifs_dfs_query_info_nonascii_quirk() if nodfs was set
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Restore ntfs_xattr_get_acl and ntfs_xattr_set_acl functions
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Update i_ctime when xattr is added
Christophe JAILLET christophe.jaillet@wanadoo.fr fs/ntfs3: Fix some memory leaks in an error handling path of 'log_replay()'
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: In function ntfs_set_acl_ex do not change inode->i_mode if called from function ntfs_init_acl
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Check new size for limits
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Keep preallocated only if option prealloc enabled
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Fix fiemap + fix shrink file size (to remove preallocated space)
Konstantin Komarov almaz.alexandrovich@paragon-software.com fs/ntfs3: Update valid size if -EIOCBQUEUED
Mikulas Patocka mpatocka@redhat.com fs/ntfs3: provide block_invalidate_folio to fix memory leak
Kishon Vijay Abraham I kishon@ti.com usb: core: hcd: Add support for deferring roothub registration
Albert Wang albertccwang@google.com usb: dwc3: gadget: Move null pinter check to proper place
Linus Walleij linus.walleij@linaro.org usb: isp1760: Fix out-of-bounds array access
Monish Kumar R monish.kumar.r@intel.com USB: new quirk for Dell Gen 2 devices
Carl Yin(殷张成) carl.yin@quectel.com USB: serial: option: add Quectel BG95 modem
Johan Hovold johan@kernel.org USB: serial: pl2303: fix type detection for odd device
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Cancel pending work at closing a MIDI substream
Marios Levogiannis marios.levogiannis@gmail.com ALSA: hda/realtek - Fix microphone noise on ASUS TUF B550M-PLUS
Rik van der Kemp rik@upto11.nl ALSA: hda/realtek: Enable 4-speaker output for Dell XPS 15 9520 laptop
Kailang Yang kailang@realtek.com ALSA: hda/realtek - Add new type for ALC245
Nathan Chancellor nathan@kernel.org riscv: Move alternative length validation into subsection
Tobias Klauser tklauser@distanz.ch riscv: Wire up memfd_secret in UAPI header
Samuel Holland samuel@sholland.org riscv: Fix irq_work when SMP is disabled
Alexandre Ghiti alexandre.ghiti@canonical.com riscv: Initialize thread pointer before calling C functions
Xianting Tian xianting.tian@linux.alibaba.com RISC-V: Mark IORESOURCE_EXCLUSIVE for reserved mem instead of IORESOURCE_BUSY
Helge Deller deller@gmx.de parisc/stifb: Keep track of hardware path of graphics card
Helge Deller deller@gmx.de parisc/stifb: Implement fb_is_primary_device()
Mikulas Patocka mpatocka@redhat.com parisc: fix a crash with multicore scheduler
Niklas Cassel niklas.cassel@wdc.com binfmt_flat: do not stop relocating GOT entries prematurely on riscv
Stephen Boyd swboyd@chromium.org arm64: Initialize jump labels before setup_machine_fdt()
-------------
Diffstat:
Documentation/accounting/psi.rst | 9 +- Documentation/conf.py | 2 +- .../bindings/display/sitronix,st7735r.yaml | 1 + .../devicetree/bindings/gpio/gpio-altera.txt | 5 +- .../bindings/regulator/mt6315-regulator.yaml | 2 +- .../devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 1 + .../bindings/spi/qcom,spi-qcom-qspi.yaml | 1 + Documentation/driver-api/thermal/intel_dptf.rst | 2 +- Documentation/sound/alsa-configuration.rst | 4 +- Documentation/userspace-api/landlock.rst | 4 +- .../userspace-api/media/lirc.h.rst.exceptions | 2 + Makefile | 4 +- arch/alpha/include/asm/page.h | 2 +- arch/arm/boot/dts/bcm2835-rpi-b.dts | 13 +- arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 22 +- arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 4 +- arch/arm/boot/dts/bcm5301x.dtsi | 2 +- arch/arm/boot/dts/exynos5250-smdk5250.dts | 4 +- arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts | 6 +- arch/arm/boot/dts/imx6qdl-colibri.dtsi | 6 +- arch/arm/boot/dts/lan966x.dtsi | 6 +- arch/arm/boot/dts/ox820.dtsi | 2 +- arch/arm/boot/dts/qcom-sdx65.dtsi | 2 +- arch/arm/boot/dts/s5pv210-aries.dtsi | 3 +- arch/arm/boot/dts/s5pv210.dtsi | 12 +- arch/arm/boot/dts/sama7g5.dtsi | 1 - arch/arm/boot/dts/socfpga.dtsi | 2 +- arch/arm/boot/dts/socfpga_arria10.dtsi | 2 +- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 1 + arch/arm/boot/dts/suniv-f1c100s.dtsi | 4 +- arch/arm/include/asm/arch_gicv3.h | 7 +- arch/arm/kernel/signal.c | 1 + arch/arm/mach-hisi/platsmp.c | 4 + arch/arm/mach-mediatek/Kconfig | 1 + arch/arm/mach-omap1/clock.c | 2 +- arch/arm/mach-pxa/cm-x300.c | 8 +- arch/arm/mach-pxa/magician.c | 2 +- arch/arm/mach-pxa/tosa.c | 4 +- arch/arm/mach-vexpress/dcscb.c | 1 + arch/arm64/Kconfig.platforms | 1 + arch/arm64/boot/dts/arm/juno-r1-scmi.dts | 4 +- arch/arm64/boot/dts/arm/juno-r2-scmi.dts | 4 +- .../dts/marvell/armada-3720-espressobin-ultra.dts | 5 - arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +- arch/arm64/boot/dts/nvidia/tegra210.dtsi | 5 +- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 8 +- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 2 +- arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 4 +- arch/arm64/boot/dts/qcom/sc7280-idp.dtsi | 18 +- arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi | 19 +- .../boot/dts/qcom/sdm845-xiaomi-beryllium.dts | 2 +- arch/arm64/boot/dts/qcom/sm8450.dtsi | 6 + arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 2 - arch/arm64/configs/defconfig | 1 + arch/arm64/include/asm/arch_gicv3.h | 6 - arch/arm64/include/asm/processor.h | 10 +- arch/arm64/kernel/setup.c | 7 +- arch/arm64/kernel/signal.c | 1 + arch/arm64/kernel/signal32.c | 1 + arch/arm64/kernel/sys_compat.c | 2 +- arch/arm64/mm/copypage.c | 4 +- arch/csky/kernel/probes/kprobes.c | 2 +- arch/m68k/Kconfig.cpu | 2 +- arch/m68k/include/asm/raw_io.h | 6 +- arch/m68k/kernel/signal.c | 1 + .../include/asm/mach-ip27/cpu-feature-overrides.h | 1 - .../include/asm/mach-ip30/cpu-feature-overrides.h | 1 - arch/mips/include/asm/mach-ralink/spaces.h | 2 + arch/openrisc/include/asm/timex.h | 1 + arch/openrisc/kernel/head.S | 9 + arch/parisc/include/asm/fb.h | 4 + arch/parisc/kernel/processor.c | 2 - arch/parisc/kernel/topology.c | 16 +- arch/powerpc/include/asm/page.h | 7 +- arch/powerpc/include/asm/vas.h | 2 +- arch/powerpc/kernel/entry_64.S | 24 +- arch/powerpc/kernel/fadump.c | 8 +- arch/powerpc/kernel/idle.c | 2 +- arch/powerpc/kernel/rtas.c | 9 + arch/powerpc/kvm/book3s_hv.c | 12 +- arch/powerpc/kvm/book3s_hv_nested.c | 3 +- arch/powerpc/kvm/trace_hv.h | 8 +- arch/powerpc/mm/nohash/fsl_book3e.c | 15 +- arch/powerpc/perf/isa207-common.c | 12 +- arch/powerpc/platforms/4xx/cpm.c | 2 +- arch/powerpc/platforms/8xx/cpm1.c | 1 + arch/powerpc/platforms/powernv/opal-fadump.c | 94 +-- arch/powerpc/platforms/powernv/opal-fadump.h | 10 +- arch/powerpc/platforms/powernv/setup.c | 9 + arch/powerpc/platforms/powernv/ultravisor.c | 1 + arch/powerpc/platforms/powernv/vas-fault.c | 2 +- arch/powerpc/platforms/powernv/vas-window.c | 4 +- arch/powerpc/platforms/powernv/vas.h | 2 +- arch/powerpc/platforms/pseries/papr_scm.c | 54 +- arch/powerpc/sysdev/dart_iommu.c | 6 +- arch/powerpc/sysdev/fsl_rio.c | 2 + arch/powerpc/sysdev/xics/icp-opal.c | 1 + arch/powerpc/sysdev/xive/spapr.c | 7 +- arch/riscv/Makefile | 4 + arch/riscv/include/asm/alternative-macros.h | 4 +- arch/riscv/include/asm/asm.h | 26 - arch/riscv/include/asm/irq_work.h | 2 +- arch/riscv/include/asm/unistd.h | 1 - arch/riscv/include/asm/xip_fixup.h | 31 + arch/riscv/include/uapi/asm/unistd.h | 1 + arch/riscv/kernel/head.S | 2 + arch/riscv/kernel/setup.c | 4 +- arch/riscv/kernel/suspend_entry.S | 1 + arch/riscv/mm/init.c | 2 +- arch/s390/include/asm/cio.h | 2 +- arch/s390/include/asm/kexec.h | 10 + arch/s390/include/asm/preempt.h | 15 +- arch/s390/kernel/perf_event.c | 2 +- arch/s390/kernel/time.c | 8 +- arch/sparc/kernel/signal32.c | 1 + arch/sparc/kernel/signal_64.c | 1 + arch/um/drivers/chan_user.c | 9 +- arch/um/drivers/virtio_uml.c | 33 +- arch/um/include/asm/Kbuild | 1 + arch/um/include/asm/thread_info.h | 2 + arch/um/kernel/exec.c | 2 +- arch/um/kernel/process.c | 2 +- arch/um/kernel/ptrace.c | 8 +- arch/um/kernel/signal.c | 4 +- arch/x86/Kconfig | 4 +- arch/x86/entry/entry_64.S | 1 + arch/x86/entry/vdso/vma.c | 2 +- arch/x86/events/amd/ibs.c | 55 +- arch/x86/events/intel/core.c | 2 +- arch/x86/include/asm/acenv.h | 14 +- arch/x86/include/asm/kexec.h | 8 + arch/x86/include/asm/set_memory.h | 52 -- arch/x86/include/asm/suspend_32.h | 2 +- arch/x86/include/asm/suspend_64.h | 12 +- arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 8 +- arch/x86/kernel/cpu/intel.c | 2 +- arch/x86/kernel/cpu/mce/amd.c | 32 +- arch/x86/kernel/cpu/mce/core.c | 6 +- arch/x86/kernel/cpu/sgx/encl.c | 105 ++- arch/x86/kernel/cpu/sgx/encl.h | 7 +- arch/x86/kernel/cpu/sgx/main.c | 9 +- arch/x86/kernel/machine_kexec_64.c | 12 +- arch/x86/kernel/signal_compat.c | 2 + arch/x86/kernel/step.c | 3 +- arch/x86/kernel/sys_x86_64.c | 7 +- arch/x86/kvm/lapic.c | 1 + arch/x86/kvm/vmx/nested.c | 45 +- arch/x86/kvm/vmx/vmcs.h | 5 + arch/x86/lib/delay.c | 4 +- arch/x86/mm/pat/memtype.c | 2 +- arch/x86/mm/pat/set_memory.c | 49 +- arch/x86/pci/irq.c | 19 +- arch/x86/um/ldt.c | 6 +- arch/xtensa/kernel/entry.S | 19 +- arch/xtensa/kernel/ptrace.c | 4 +- arch/xtensa/kernel/signal.c | 4 +- arch/xtensa/kernel/traps.c | 11 +- arch/xtensa/platforms/iss/simdisk.c | 18 +- block/bfq-cgroup.c | 111 +-- block/bfq-iosched.c | 64 +- block/bfq-iosched.h | 7 +- block/blk-cgroup.c | 9 +- block/blk-cgroup.h | 2 +- block/blk-ia-ranges.c | 7 +- block/blk-iocost.c | 5 +- block/blk-iolatency.c | 130 ++-- block/blk-throttle.c | 3 +- crypto/cryptd.c | 23 +- drivers/acpi/arm64/agdi.c | 1 + drivers/acpi/cppc_acpi.c | 17 +- drivers/acpi/property.c | 18 +- drivers/acpi/sleep.c | 12 + drivers/base/memory.c | 5 +- drivers/base/node.c | 1 + drivers/base/power/domain.c | 1 + drivers/base/property.c | 89 +-- drivers/block/drbd/drbd_main.c | 62 +- drivers/block/loop.c | 16 +- drivers/block/nbd.c | 13 +- drivers/block/virtio_blk.c | 7 +- drivers/bluetooth/btmtksdio.c | 26 +- drivers/bluetooth/btusb.c | 6 + drivers/char/hw_random/cn10k-rng.c | 31 +- drivers/char/hw_random/omap3-rom-rng.c | 2 +- drivers/char/ipmi/ipmi_ipmb.c | 1 + drivers/char/ipmi/ipmi_msghandler.c | 4 +- drivers/char/ipmi/ipmi_poweroff.c | 4 +- drivers/char/ipmi/ipmi_ssif.c | 23 + drivers/char/ipmi/ipmi_watchdog.c | 14 +- drivers/char/random.c | 12 +- drivers/char/tpm/tpm_tis_i2c_cr50.c | 4 +- drivers/clk/tegra/clk-dfll.c | 12 + drivers/cpufreq/cpufreq.c | 11 + drivers/cpufreq/cpufreq_governor.c | 20 +- drivers/cpufreq/cpufreq_governor.h | 1 + drivers/cpufreq/mediatek-cpufreq.c | 18 +- drivers/cpuidle/cpuidle-psci-domain.c | 4 +- drivers/cpuidle/cpuidle-psci.c | 46 ++ drivers/cpuidle/cpuidle-riscv-sbi.c | 4 +- .../crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c | 115 ++-- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 30 +- drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 10 +- drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 14 +- drivers/crypto/ccp/sev-dev.c | 30 +- drivers/crypto/ccree/cc_buffer_mgr.c | 27 +- drivers/crypto/marvell/cesa/cipher.c | 1 - drivers/crypto/nx/nx-common-powernv.c | 2 +- drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c | 2 +- .../crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 13 +- drivers/cxl/mem.c | 4 - drivers/cxl/pci.c | 40 +- drivers/devfreq/rk3399_dmc.c | 2 + drivers/dma/idxd/cdev.c | 8 +- drivers/dma/stm32-mdma.c | 23 +- drivers/dma/ti/k3-psil-am62.c | 8 +- drivers/edac/dmc520_edac.c | 2 +- drivers/firmware/arm_ffa/driver.c | 4 +- drivers/firmware/arm_scmi/base.c | 2 +- drivers/firmware/efi/Kconfig | 15 + drivers/firmware/efi/efi.c | 2 +- drivers/gpio/gpio-rockchip.c | 24 +- drivers/gpio/gpio-sim.c | 4 +- drivers/gpio/gpiolib-of.c | 5 + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 13 +- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 95 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 10 +- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 8 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 8 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 7 +- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 + drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 7 +- .../gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 1 + drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 2 +- drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c | 14 +- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 8 +- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 4 +- drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 60 +- .../gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 62 +- drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 10 +- drivers/gpu/drm/arm/malidp_crtc.c | 5 +- drivers/gpu/drm/bridge/Kconfig | 2 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 1 + drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 31 +- drivers/gpu/drm/bridge/analogix/anx7625.c | 21 +- drivers/gpu/drm/bridge/analogix/anx7625.h | 4 +- drivers/gpu/drm/bridge/chipone-icn6211.c | 155 ++++- drivers/gpu/drm/bridge/ite-it6505.c | 29 +- drivers/gpu/drm/bridge/ite-it66121.c | 2 +- drivers/gpu/drm/drm_bridge_connector.c | 4 +- drivers/gpu/drm/drm_edid.c | 6 +- drivers/gpu/drm/drm_format_helper.c | 74 +- drivers/gpu/drm/drm_plane.c | 14 +- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 6 + drivers/gpu/drm/gma500/psb_intel_display.c | 7 +- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 33 +- drivers/gpu/drm/i915/i915_perf.c | 4 +- drivers/gpu/drm/i915/i915_perf_types.h | 2 +- drivers/gpu/drm/mediatek/mtk_cec.c | 2 +- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 16 +- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 22 +- drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 20 +- drivers/gpu/drm/mediatek/mtk_dpi.c | 4 +- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 14 +- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 + drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 29 +- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 + drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 16 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 5 +- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 14 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 6 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 15 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h | 4 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 15 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 +- drivers/gpu/drm/msm/dp/dp_ctrl.c | 16 +- drivers/gpu/drm/msm/dp/dp_display.c | 55 +- drivers/gpu/drm/msm/dp/dp_drm.c | 4 + drivers/gpu/drm/msm/dsi/dsi_host.c | 21 +- drivers/gpu/drm/msm/dsi/dsi_manager.c | 35 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 +- drivers/gpu/drm/msm/hdmi/hdmi.c | 10 +- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 3 + drivers/gpu/drm/msm/msm_drv.c | 11 +- drivers/gpu/drm/msm/msm_gem_prime.c | 2 +- drivers/gpu/drm/msm/msm_gpu.c | 3 +- drivers/gpu/drm/msm/msm_gpu.h | 12 +- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 90 ++- drivers/gpu/drm/msm/msm_kms.h | 1 + drivers/gpu/drm/nouveau/dispnv50/atom.h | 6 +- drivers/gpu/drm/nouveau/dispnv50/crc.c | 27 +- drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 2 + drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c | 14 +- drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c | 6 +- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 6 +- drivers/gpu/drm/omapdrm/omap_overlay.c | 2 +- drivers/gpu/drm/panel/panel-simple.c | 3 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- drivers/gpu/drm/selftests/test-drm_buddy.c | 10 +- drivers/gpu/drm/solomon/Kconfig | 2 +- drivers/gpu/drm/solomon/ssd130x.c | 42 +- drivers/gpu/drm/stm/ltdc.c | 16 +- drivers/gpu/drm/tegra/gem.c | 1 + drivers/gpu/drm/tilcdc/tilcdc_external.c | 8 +- drivers/gpu/drm/tiny/repaper.c | 2 +- drivers/gpu/drm/v3d/v3d_perfmon.c | 3 +- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_hvs.c | 49 +- drivers/gpu/drm/vc4/vc4_kms.c | 5 +- drivers/gpu/drm/vc4/vc4_regs.h | 12 +- drivers/gpu/drm/vc4/vc4_txp.c | 8 +- drivers/gpu/drm/virtio/virtgpu_display.c | 2 + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 30 +- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 14 +- drivers/hid/amd-sfh-hid/amd_sfh_hid.c | 4 +- drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 2 +- drivers/hid/hid-bigbenff.c | 6 + drivers/hid/hid-elan.c | 2 - drivers/hid/hid-led.c | 2 +- drivers/hv/channel.c | 6 +- drivers/hwmon/peci/dimmtemp.c | 6 +- drivers/hwmon/pmbus/pmbus_core.c | 95 ++- drivers/hwtracing/coresight/coresight-core.c | 33 +- drivers/i2c/busses/i2c-at91-master.c | 11 + drivers/i2c/busses/i2c-npcm7xx.c | 103 ++- drivers/i2c/busses/i2c-rcar.c | 15 +- drivers/infiniband/hw/hfi1/file_ops.c | 2 + drivers/infiniband/hw/hfi1/init.c | 2 +- drivers/infiniband/hw/hfi1/sdma.c | 12 +- drivers/infiniband/hw/hns/hns_roce_device.h | 7 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 24 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- drivers/infiniband/hw/hns/hns_roce_main.c | 2 +- drivers/infiniband/sw/rdmavt/qp.c | 6 +- drivers/infiniband/sw/rxe/rxe_mcast.c | 6 +- drivers/infiniband/sw/rxe/rxe_req.c | 2 +- drivers/input/keyboard/gpio_keys.c | 2 +- drivers/input/misc/sparcspkr.c | 1 + drivers/input/touchscreen/stmfts.c | 16 +- drivers/iommu/amd/init.c | 2 +- drivers/iommu/amd/iommu.c | 7 - drivers/iommu/amd/iommu_v2.c | 12 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 13 +- drivers/iommu/dma-iommu.c | 7 +- drivers/iommu/intel/iommu.c | 2 +- drivers/iommu/msm_iommu.c | 11 +- drivers/iommu/mtk_iommu.c | 30 +- drivers/iommu/mtk_iommu.h | 2 + drivers/iommu/mtk_iommu_v1.c | 7 + drivers/irqchip/irq-armada-370-xp.c | 11 +- drivers/irqchip/irq-aspeed-i2c-ic.c | 4 +- drivers/irqchip/irq-aspeed-scu-ic.c | 4 +- drivers/irqchip/irq-gic-v3.c | 183 +++-- drivers/irqchip/irq-sni-exiu.c | 25 +- drivers/irqchip/irq-xtensa-mx.c | 18 +- drivers/macintosh/Kconfig | 6 + drivers/macintosh/Makefile | 3 +- drivers/macintosh/via-pmu.c | 2 +- drivers/mailbox/mailbox.c | 19 +- drivers/mailbox/pcc.c | 2 +- drivers/md/bcache/btree.c | 58 +- drivers/md/bcache/btree.h | 2 +- drivers/md/bcache/journal.c | 31 +- drivers/md/bcache/journal.h | 2 + drivers/md/bcache/request.c | 6 + drivers/md/bcache/super.c | 1 + drivers/md/bcache/writeback.c | 101 +-- drivers/md/bcache/writeback.h | 2 +- drivers/md/md-bitmap.c | 44 +- drivers/md/md.c | 22 +- drivers/md/raid0.c | 1 - drivers/media/cec/core/cec-adap.c | 6 +- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/ccs/ccs-core.c | 7 +- drivers/media/i2c/dw9714.c | 1 + drivers/media/i2c/dw9768.c | 6 - drivers/media/i2c/max9286.c | 19 +- drivers/media/i2c/ov5648.c | 4 +- drivers/media/i2c/ov7670.c | 1 - drivers/media/i2c/rdacm20.c | 2 +- drivers/media/i2c/rdacm21.c | 2 +- drivers/media/pci/cx23885/cx23885-core.c | 6 +- drivers/media/pci/cx25821/cx25821-core.c | 2 +- drivers/media/platform/amphion/vdec.c | 2 +- drivers/media/platform/aspeed/aspeed-video.c | 4 +- drivers/media/platform/atmel/atmel-sama5d2-isc.c | 7 +- drivers/media/platform/chips-media/coda-common.c | 35 +- .../platform/mediatek/vcodec/mtk_vcodec_dec.c | 13 +- .../platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 6 +- drivers/media/platform/nxp/imx-mipi-csis.c | 561 ++++++++------- drivers/media/platform/qcom/venus/helpers.c | 34 +- drivers/media/platform/qcom/venus/hfi.c | 3 + drivers/media/platform/renesas/vsp1/vsp1_rpf.c | 6 +- drivers/media/platform/rockchip/rga/rga.c | 6 +- .../media/platform/samsung/exynos4-is/fimc-is.c | 6 +- .../platform/samsung/exynos4-is/fimc-isp-video.h | 2 +- drivers/media/platform/st/sti/delta/delta-v4l2.c | 6 +- drivers/media/radio/Kconfig | 4 +- drivers/media/rc/bpf-lirc.c | 8 +- drivers/media/rc/imon.c | 99 ++- drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 7 +- drivers/media/usb/uvc/uvc_v4l2.c | 20 +- drivers/memory/samsung/exynos5422-dmc.c | 5 +- drivers/mfd/davinci_voicecodec.c | 6 +- drivers/mfd/ipaq-micro.c | 2 +- drivers/misc/fastrpc.c | 9 +- drivers/misc/ocxl/file.c | 2 + drivers/mmc/core/block.c | 8 +- drivers/mmc/host/jz4740_mmc.c | 20 + drivers/mmc/host/sdhci_am654.c | 23 +- drivers/mtd/chips/cfi_cmdset_0002.c | 103 ++- drivers/mtd/mtdblock.c | 8 +- drivers/mtd/nand/raw/cadence-nand-controller.c | 5 +- drivers/mtd/nand/raw/denali_pci.c | 15 +- drivers/mtd/nand/raw/intel-nand-controller.c | 2 +- drivers/mtd/nand/spi/gigadevice.c | 10 +- drivers/mtd/spi-nor/core.c | 9 + drivers/net/amt.c | 11 +- drivers/net/bonding/bond_main.c | 15 +- drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 2 +- drivers/net/can/xilinx_can.c | 4 +- drivers/net/dsa/Kconfig | 3 +- drivers/net/dsa/mt7530.c | 14 +- drivers/net/dsa/qca8k.c | 7 +- drivers/net/ethernet/broadcom/Makefile | 5 + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 56 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h | 2 + drivers/net/ethernet/cadence/macb_main.c | 42 +- drivers/net/ethernet/cadence/macb_ptp.c | 4 +- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 12 +- drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 2 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 2 +- drivers/net/ethernet/intel/ice/ice_devlink.c | 5 +- drivers/net/ethernet/intel/ice/ice_repr.c | 7 +- drivers/net/ethernet/intel/ice/ice_sriov.c | 32 +- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 28 +- drivers/net/ethernet/intel/ice/ice_virtchnl.c | 5 + drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c | 7 +- drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 + .../ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 9 + drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 10 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 10 +- drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h | 1 + drivers/net/ethernet/mellanox/mlx5/core/main.c | 23 +- .../net/ethernet/mellanox/mlx5/core/mlx5_core.h | 2 +- drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c | 13 - .../net/ethernet/mellanox/mlxsw/spectrum_trap.c | 2 +- drivers/net/ethernet/sfc/ef10.c | 2 +- .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 13 +- drivers/net/ethernet/ti/Kconfig | 1 + drivers/net/ethernet/xscale/ptp_ixp46x.c | 2 +- drivers/net/hyperv/netvsc_drv.c | 5 +- drivers/net/ipa/ipa_endpoint.c | 41 +- drivers/net/macsec.c | 7 + drivers/net/phy/micrel.c | 11 +- drivers/net/usb/asix_devices.c | 6 +- drivers/net/usb/smsc95xx.c | 3 +- drivers/net/usb/usbnet.c | 6 +- drivers/net/wireless/ath/ath10k/mac.c | 20 +- drivers/net/wireless/ath/ath11k/mac.c | 16 +- drivers/net/wireless/ath/ath11k/pci.c | 12 +- drivers/net/wireless/ath/ath11k/spectral.c | 17 +- drivers/net/wireless/ath/ath11k/wmi.c | 11 +- drivers/net/wireless/ath/ath11k/wmi.h | 12 +- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 +- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 + drivers/net/wireless/ath/carl9170/tx.c | 3 + drivers/net/wireless/broadcom/b43/phy_n.c | 2 +- drivers/net/wireless/broadcom/b43legacy/phy.c | 2 +- drivers/net/wireless/intel/ipw2x00/libipw_tx.c | 2 +- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 3 + drivers/net/wireless/intel/iwlwifi/mei/main.c | 3 + drivers/net/wireless/intel/iwlwifi/mvm/power.c | 3 + drivers/net/wireless/marvell/mwifiex/11h.c | 2 + drivers/net/wireless/mediatek/mt76/agg-rx.c | 5 +- drivers/net/wireless/mediatek/mt76/mac80211.c | 8 +- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/debugfs.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c | 2 + drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 35 +- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 20 +- drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/soc.c | 2 + drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 6 +- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 6 +- drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 10 +- drivers/net/wireless/mediatek/mt76/tx.c | 11 +- drivers/net/wireless/microchip/wilc1000/mon.c | 4 +- drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 8 +- drivers/net/wireless/realtek/rtlwifi/usb.c | 2 +- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 4 + drivers/net/wireless/realtek/rtw88/rx.c | 3 +- drivers/net/wireless/realtek/rtw89/cam.c | 14 +- drivers/net/wireless/realtek/rtw89/fw.c | 2 +- drivers/net/wireless/realtek/rtw89/phy.c | 5 + drivers/net/wireless/realtek/rtw89/ser.c | 21 + drivers/net/wireless/ti/wl1251/event.c | 22 +- drivers/net/wireless/ti/wl1251/io.c | 20 +- drivers/net/wireless/ti/wl1251/tx.c | 15 +- drivers/nfc/st21nfca/se.c | 17 +- drivers/nfc/st21nfca/st21nfca.h | 1 + drivers/nvdimm/core.c | 9 - drivers/nvdimm/pmem.c | 30 +- drivers/nvdimm/security.c | 5 - drivers/nvme/host/core.c | 21 +- drivers/nvme/host/pci.c | 1 + drivers/of/fdt.c | 3 + drivers/of/kexec.c | 9 + drivers/of/overlay.c | 4 +- drivers/opp/of.c | 2 +- drivers/pci/controller/cadence/pci-j721e.c | 3 + drivers/pci/controller/cadence/pcie-cadence-ep.c | 21 +- drivers/pci/controller/cadence/pcie-cadence.h | 3 + drivers/pci/controller/dwc/pci-imx6.c | 23 +- drivers/pci/controller/dwc/pcie-designware-host.c | 3 +- drivers/pci/controller/dwc/pcie-qcom.c | 15 +- drivers/pci/controller/pcie-mediatek-gen3.c | 8 + drivers/pci/controller/pcie-mediatek.c | 1 + drivers/pci/controller/pcie-microchip-host.c | 16 +- drivers/pci/controller/pcie-rockchip-ep.c | 3 +- drivers/pci/pci-acpi.c | 41 +- drivers/pci/pci.c | 12 +- drivers/pci/pcie/aer.c | 7 +- drivers/pci/quirks.c | 47 ++ drivers/phy/qualcomm/phy-qcom-qmp.c | 11 +- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 18 + drivers/pinctrl/mediatek/Kconfig | 1 + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 2 +- drivers/pinctrl/pinctrl-apple-gpio.c | 1 + drivers/pinctrl/pinctrl-rockchip.c | 54 +- drivers/pinctrl/pinctrl-rockchip.h | 7 +- drivers/pinctrl/renesas/core.c | 7 +- drivers/pinctrl/renesas/pfc-r8a779a0.c | 29 + drivers/pinctrl/renesas/pfc-r8a779f0.c | 21 + drivers/pinctrl/renesas/pinctrl-rzn1.c | 10 +- drivers/platform/chrome/cros_ec.c | 16 +- drivers/platform/chrome/cros_ec_chardev.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 50 +- drivers/platform/mips/cpu_hwmon.c | 127 ++-- drivers/platform/x86/intel/chtwc_int33fe.c | 2 + drivers/platform/x86/intel/hid.c | 2 +- drivers/regulator/core.c | 7 +- drivers/regulator/da9121-regulator.c | 2 + drivers/regulator/pfuze100-regulator.c | 2 + drivers/regulator/qcom_smd-regulator.c | 35 +- drivers/regulator/scmi-regulator.c | 2 +- drivers/s390/cio/chsc.c | 4 +- drivers/scsi/dc395x.c | 15 +- drivers/scsi/fcoe/fcoe_ctlr.c | 2 +- drivers/scsi/hisi_sas/hisi_sas_main.c | 49 +- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 +- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 112 +-- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 + drivers/scsi/lpfc/lpfc_init.c | 51 +- drivers/scsi/lpfc/lpfc_logmsg.h | 6 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 10 +- drivers/scsi/lpfc/lpfc_scsi.c | 37 +- drivers/scsi/lpfc/lpfc_sli.c | 48 +- drivers/scsi/megaraid.c | 2 +- drivers/scsi/ufs/ti-j721e-ufs.c | 6 +- drivers/scsi/ufs/ufs-qcom.c | 14 +- drivers/scsi/ufs/ufshcd.c | 7 +- drivers/soc/bcm/bcm63xx/bcm-pmb.c | 3 + drivers/soc/qcom/llcc-qcom.c | 1 + drivers/soc/qcom/smp2p.c | 1 + drivers/soc/qcom/smsm.c | 1 + drivers/soc/ti/ti_sci_pm_domains.c | 2 + drivers/spi/spi-cadence-quadspi.c | 2 +- drivers/spi/spi-fsl-qspi.c | 4 + drivers/spi/spi-img-spfi.c | 2 +- drivers/spi/spi-rockchip.c | 8 + drivers/spi/spi-rspi.c | 15 +- drivers/spi/spi-stm32-qspi.c | 3 +- drivers/spi/spi-ti-qspi.c | 5 +- drivers/staging/media/hantro/hantro_drv.c | 17 +- drivers/staging/media/hantro/hantro_g2_hevc_dec.c | 11 +- drivers/staging/media/hantro/hantro_h264.c | 2 - drivers/staging/media/hantro/hantro_v4l2.c | 67 +- drivers/staging/media/rkvdec/rkvdec-h264.c | 37 +- drivers/staging/media/rkvdec/rkvdec.c | 6 - drivers/staging/r8188eu/os_dep/ioctl_linux.c | 92 +-- drivers/target/target_core_device.c | 1 - drivers/target/target_core_user.c | 50 +- drivers/thermal/broadcom/bcm2711_thermal.c | 5 +- drivers/thermal/broadcom/sr-thermal.c | 3 + drivers/thermal/devfreq_cooling.c | 25 +- drivers/thermal/imx_sc_thermal.c | 6 +- drivers/thermal/thermal_core.c | 1 + drivers/tty/goldfish.c | 20 +- drivers/tty/n_gsm.c | 31 +- drivers/tty/serial/pch_uart.c | 27 +- drivers/tty/tty_buffer.c | 3 +- drivers/usb/core/hcd.c | 29 +- drivers/usb/core/quirks.c | 3 + drivers/usb/dwc3/gadget.c | 6 +- drivers/usb/host/xhci-pci.c | 2 + drivers/usb/host/xhci.c | 2 + drivers/usb/isp1760/isp1760-core.c | 8 + drivers/usb/serial/option.c | 2 + drivers/usb/serial/pl2303.c | 3 + drivers/vdpa/vdpa_sim/vdpa_sim.c | 5 +- drivers/video/console/sticon.c | 5 +- drivers/video/console/sticore.c | 32 +- drivers/video/fbdev/amba-clcd.c | 5 +- drivers/video/fbdev/core/fb_defio.c | 9 +- drivers/video/fbdev/core/fbcon.c | 5 +- drivers/video/fbdev/sticore.h | 3 + drivers/video/fbdev/stifb.c | 4 +- drivers/video/fbdev/vesafb.c | 5 +- fs/afs/misc.c | 5 +- fs/afs/rotate.c | 4 + fs/afs/rxrpc.c | 8 +- fs/afs/write.c | 1 + fs/binfmt_flat.c | 27 +- fs/btrfs/block-group.c | 8 + fs/btrfs/block-group.h | 2 + fs/btrfs/disk-io.c | 4 +- fs/btrfs/extent_io.c | 27 +- fs/btrfs/extent_io.h | 1 - fs/btrfs/inode.c | 81 ++- fs/btrfs/ioctl.c | 49 +- fs/btrfs/volumes.c | 8 +- fs/btrfs/zoned.c | 44 +- fs/btrfs/zoned.h | 5 + fs/ceph/mds_client.c | 14 +- fs/cifs/cifsfs.c | 10 +- fs/cifs/cifsglob.h | 15 +- fs/cifs/connect.c | 67 +- fs/cifs/dfs_cache.c | 6 +- fs/cifs/fs_context.c | 29 +- fs/cifs/fs_context.h | 2 +- fs/cifs/misc.c | 7 +- fs/cifs/sess.c | 6 +- fs/cifs/smb2inode.c | 2 - fs/cifs/smb2ops.c | 9 +- fs/cifs/smb2pdu.c | 3 +- fs/cifs/smb2transport.c | 3 +- fs/dax.c | 3 +- fs/dlm/lock.c | 15 +- fs/dlm/lowcomms.c | 2 +- fs/dlm/plock.c | 12 +- fs/erofs/decompressor.c | 5 +- fs/exec.c | 6 +- fs/exportfs/expfs.c | 5 +- fs/ext4/ext4.h | 6 - fs/ext4/extents.c | 20 +- fs/ext4/inline.c | 12 + fs/ext4/inode.c | 13 +- fs/ext4/mballoc.c | 18 +- fs/ext4/namei.c | 84 ++- fs/ext4/super.c | 87 ++- fs/f2fs/dir.c | 3 +- fs/f2fs/f2fs.h | 29 +- fs/f2fs/file.c | 20 +- fs/f2fs/hash.c | 11 +- fs/f2fs/inline.c | 29 +- fs/f2fs/inode.c | 19 +- fs/f2fs/namei.c | 7 + fs/f2fs/segment.c | 42 +- fs/f2fs/segment.h | 33 +- fs/f2fs/super.c | 6 +- fs/fat/fatent.c | 7 +- fs/fs-writeback.c | 13 +- fs/gfs2/quota.c | 32 +- fs/hugetlbfs/inode.c | 4 +- fs/io_uring.c | 7 +- fs/iomap/buffered-io.c | 3 +- fs/jfs/jfs_dmap.c | 3 +- fs/ksmbd/connection.c | 2 +- fs/ksmbd/smb2misc.c | 2 +- fs/ksmbd/smb_common.c | 4 +- fs/namei.c | 70 +- fs/namespace.c | 5 +- fs/nfs/file.c | 50 +- fs/nfs/fscache.c | 7 +- fs/nfs/nfs4namespace.c | 9 +- fs/nfs/nfs4proc.c | 41 +- fs/nfs/nfs4state.c | 9 +- fs/nfs/nfs4xdr.c | 4 +- fs/nfs/pagelist.c | 3 + fs/nfs/pnfs.c | 2 + fs/nfs/unlink.c | 8 + fs/nfs/write.c | 54 +- fs/nfsd/nfscache.c | 2 +- fs/notify/fanotify/fanotify_user.c | 4 +- fs/notify/fdinfo.c | 11 +- fs/notify/inotify/inotify.h | 12 + fs/notify/inotify/inotify_user.c | 2 +- fs/notify/mark.c | 6 +- fs/ntfs3/file.c | 12 +- fs/ntfs3/frecord.c | 10 +- fs/ntfs3/fslog.c | 12 +- fs/ntfs3/inode.c | 9 +- fs/ntfs3/xattr.c | 112 ++- fs/ocfs2/dlmfs/userdlm.c | 16 +- fs/ocfs2/inode.c | 4 +- fs/ocfs2/journal.c | 33 +- fs/ocfs2/journal.h | 2 + fs/ocfs2/super.c | 15 + fs/proc/generic.c | 3 + fs/proc/proc_net.c | 3 + fs/seq_file.c | 32 + include/drm/drm_edid.h | 6 +- include/drm/drm_format_helper.h | 5 +- include/linux/blk_types.h | 5 +- include/linux/bpf.h | 119 +--- include/linux/compat.h | 1 + include/linux/efi.h | 2 + include/linux/fwnode.h | 10 +- include/linux/goldfish.h | 15 +- include/linux/gpio/driver.h | 12 + include/linux/ipmi_smi.h | 6 + include/linux/kexec.h | 46 +- include/linux/kprobes.h | 2 +- include/linux/linkage.h | 15 +- include/linux/list.h | 16 +- include/linux/mailbox_controller.h | 1 + include/linux/module.h | 3 +- include/linux/mtd/cfi.h | 1 + include/linux/namei.h | 6 + include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_xdr.h | 2 +- include/linux/nodemask.h | 13 +- include/linux/platform_data/cros_ec_proto.h | 3 + include/linux/ptp_classify.h | 3 + include/linux/ptrace.h | 7 - include/linux/sched/signal.h | 2 +- include/linux/sched/task.h | 2 + include/linux/seq_file.h | 4 + include/linux/set_memory.h | 10 +- include/linux/usb/hcd.h | 2 + include/net/bluetooth/hci.h | 9 + include/net/bluetooth/hci_core.h | 8 +- include/net/if_inet6.h | 8 + include/net/ip.h | 2 +- include/net/sock.h | 5 +- include/scsi/libfcoe.h | 3 +- include/scsi/libiscsi.h | 6 +- include/sound/cs35l41.h | 1 - include/sound/jack.h | 1 + include/trace/events/rxrpc.h | 2 +- include/trace/events/vmscan.h | 4 +- include/uapi/asm-generic/siginfo.h | 7 + include/uapi/linux/android/binder.h | 2 +- include/uapi/linux/landlock.h | 9 +- include/uapi/linux/lirc.h | 7 + include/uapi/linux/types.h | 3 + init/Kconfig | 5 + init/main.c | 2 +- ipc/mqueue.c | 14 + kernel/bpf/cgroup.c | 124 +++- kernel/dma/debug.c | 2 +- kernel/dma/direct.c | 31 +- kernel/events/core.c | 4 +- kernel/fork.c | 22 +- kernel/kexec_file.c | 34 - kernel/kprobes.c | 144 ++-- kernel/module.c | 4 + kernel/power/energy_model.c | 2 + kernel/printk/printk.c | 61 +- kernel/ptrace.c | 5 +- kernel/rcu/Kconfig | 1 + kernel/rcu/tasks.h | 5 +- kernel/scftorture.c | 5 +- kernel/sched/core.c | 6 +- kernel/sched/deadline.c | 5 +- kernel/sched/fair.c | 8 +- kernel/sched/pelt.h | 4 +- kernel/sched/psi.c | 15 +- kernel/sched/rt.c | 5 +- kernel/sched/sched.h | 32 +- kernel/signal.c | 18 +- kernel/trace/bpf_trace.c | 5 +- kernel/trace/ftrace.c | 5 +- kernel/trace/trace.c | 6 +- kernel/trace/trace_boot.c | 2 +- kernel/trace/trace_events.c | 13 +- kernel/trace/trace_events_hist.c | 3 + kernel/trace/trace_osnoise.c | 9 +- kernel/trace/trace_selftest.c | 3 + kernel/umh.c | 6 +- lib/kunit/debugfs.c | 2 +- lib/kunit/executor.c | 32 +- lib/kunit/executor_test.c | 4 +- lib/string_helpers.c | 3 + mm/cma.c | 4 +- mm/compaction.c | 2 + mm/hugetlb.c | 9 +- mm/memremap.c | 2 +- mm/page_alloc.c | 4 +- mm/page_owner.c | 2 +- net/bluetooth/hci_conn.c | 7 +- net/bluetooth/hci_event.c | 35 +- net/bluetooth/hci_request.c | 2 + net/bluetooth/sco.c | 23 +- net/core/dev.c | 8 +- net/ipv4/tcp_input.c | 28 +- net/ipv6/addrconf.c | 33 +- net/ipv6/datagram.c | 6 +- net/ipv6/udp.c | 11 +- net/mac80211/chan.c | 7 +- net/mac80211/ieee80211_i.h | 5 + net/mac80211/rc80211_minstrel_ht.c | 3 + net/mac80211/scan.c | 20 + net/mptcp/pm.c | 19 +- net/mptcp/pm_netlink.c | 2 + net/mptcp/protocol.c | 18 +- net/mptcp/protocol.h | 1 + net/nfc/core.c | 1 + net/rxrpc/ar-internal.h | 15 +- net/rxrpc/call_accept.c | 6 +- net/rxrpc/call_event.c | 7 +- net/rxrpc/call_object.c | 18 +- net/rxrpc/conn_object.c | 2 +- net/rxrpc/input.c | 58 +- net/rxrpc/net_ns.c | 2 +- net/rxrpc/output.c | 20 +- net/rxrpc/proc.c | 10 +- net/rxrpc/recvmsg.c | 8 +- net/rxrpc/sendmsg.c | 6 + net/rxrpc/sysctl.c | 4 +- net/sctp/input.c | 4 +- net/smc/af_smc.c | 2 +- net/wireless/nl80211.c | 4 +- net/wireless/reg.c | 4 + samples/bpf/Makefile | 9 +- samples/landlock/sandboxer.c | 104 +-- scripts/faddr2line | 150 ++-- security/integrity/ima/Kconfig | 14 +- .../integrity/platform_certs/keyring_handler.h | 8 + security/integrity/platform_certs/load_uefi.c | 33 + security/landlock/cred.c | 4 +- security/landlock/cred.h | 8 +- security/landlock/fs.c | 191 ++++-- security/landlock/fs.h | 11 +- security/landlock/limits.h | 8 +- security/landlock/object.c | 6 +- security/landlock/object.h | 6 +- security/landlock/ptrace.c | 10 +- security/landlock/ruleset.c | 84 +-- security/landlock/ruleset.h | 35 +- security/landlock/syscalls.c | 95 +-- sound/core/jack.c | 34 +- sound/core/pcm_memory.c | 3 +- sound/pci/hda/patch_realtek.c | 21 +- sound/soc/amd/yc/acp6x-mach.c | 29 +- sound/soc/atmel/atmel-classd.c | 1 - sound/soc/atmel/atmel-pdmic.c | 1 - sound/soc/codecs/Kconfig | 2 - sound/soc/codecs/cs35l41-lib.c | 14 +- sound/soc/codecs/lpass-macro-common.c | 35 +- sound/soc/codecs/max98090.c | 6 +- sound/soc/codecs/rk3328_codec.c | 2 +- sound/soc/codecs/rt5514.c | 2 +- sound/soc/codecs/rt5645.c | 7 +- sound/soc/codecs/tscs454.c | 12 +- sound/soc/codecs/wm2000.c | 6 +- sound/soc/fsl/imx-hdmi.c | 1 + sound/soc/fsl/imx-sgtl5000.c | 14 +- sound/soc/intel/boards/bytcr_rt5640.c | 12 + sound/soc/intel/boards/sof_ssp_amp.c | 16 +- sound/soc/mediatek/mt2701/mt2701-wm8960.c | 9 +- sound/soc/mediatek/mt8173/mt8173-max98090.c | 5 +- sound/soc/mxs/mxs-saif.c | 1 + sound/soc/samsung/aries_wm8994.c | 2 +- sound/soc/sh/rcar/core.c | 15 +- sound/soc/sh/rcar/dma.c | 9 +- sound/soc/sh/rcar/rsnd.h | 2 +- sound/soc/sh/rcar/src.c | 7 +- sound/soc/sh/rcar/ssi.c | 14 +- sound/soc/sh/rcar/ssiu.c | 11 +- sound/soc/sh/rz-ssi.c | 22 +- sound/soc/soc-dapm.c | 2 - sound/soc/sof/amd/pci-rn.c | 1 + sound/soc/sof/ipc3-topology.c | 40 +- sound/soc/ti/j721e-evm.c | 44 +- sound/usb/implicit.c | 10 +- sound/usb/midi.c | 3 + sound/usb/quirks.c | 6 + sound/usb/usbaudio.h | 6 + .../test-libbpf-btf__load_from_kernel_by_id.c | 5 +- tools/lib/bpf/libbpf.c | 22 +- tools/objtool/check.c | 9 +- tools/objtool/elf.c | 200 ++++-- tools/objtool/include/objtool/elf.h | 4 +- tools/perf/Makefile.config | 39 +- tools/perf/arch/x86/util/evlist.c | 2 +- tools/perf/arch/x86/util/evsel.c | 12 + tools/perf/builtin-c2c.c | 6 +- tools/perf/builtin-stat.c | 7 +- tools/perf/pmu-events/jevents.c | 2 +- tools/perf/util/data.h | 1 + tools/perf/util/evlist.c | 12 +- tools/perf/util/evsel.c | 19 + tools/perf/util/evsel.h | 3 + tools/power/x86/turbostat/turbostat.c | 1 + tools/testing/kunit/kunit_parser.py | 7 +- .../test_is_test_passed-no_tests_no_plan.log | 2 +- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/arm64/bti/Makefile | 4 +- tools/testing/selftests/bpf/Makefile | 12 +- .../selftests/bpf/prog_tests/trampoline_count.c | 134 ++-- .../bpf/progs/btf_dump_test_case_syntax.c | 2 +- tools/testing/selftests/bpf/progs/profiler.inc.h | 5 +- .../selftests/bpf/progs/test_trampoline_count.c | 16 +- .../selftests/bpf/test_bpftool_synctypes.py | 2 +- tools/testing/selftests/bpf/trace_helpers.c | 9 +- tools/testing/selftests/cgroup/test_stress.sh | 2 +- tools/testing/selftests/landlock/base_test.c | 177 +++-- tools/testing/selftests/landlock/common.h | 66 +- tools/testing/selftests/landlock/fs_test.c | 753 ++++++++++++++------- tools/testing/selftests/landlock/ptrace_test.c | 40 +- tools/testing/selftests/resctrl/fill_buf.c | 4 +- tools/tracing/rtla/Makefile | 5 +- tools/tracing/rtla/README.txt | 13 +- tools/tracing/rtla/src/osnoise_hist.c | 5 +- tools/tracing/rtla/src/osnoise_top.c | 9 +- tools/tracing/rtla/src/timerlat_hist.c | 11 +- tools/tracing/rtla/src/timerlat_top.c | 11 +- tools/tracing/rtla/src/utils.c | 108 ++- tools/tracing/rtla/src/utils.h | 3 +- 951 files changed, 9396 insertions(+), 5279 deletions(-)
From: Stephen Boyd swboyd@chromium.org
commit 73e2d827a501d48dceeb5b9b267a4cd283d6b1ae upstream.
A static key warning splat appears during early boot on arm64 systems that credit randomness from devicetrees that contain an "rng-seed" property. This is because setup_machine_fdt() is called before jump_label_init() during setup_arch(). Let's swap the order of these two calls so that jump labels are initialized before the devicetree is unflattened and the rng seed is credited.
static_key_enable_cpuslocked(): static key '0xffffffe51c6fcfc0' used before call to jump_label_init() WARNING: CPU: 0 PID: 0 at kernel/jump_label.c:166 static_key_enable_cpuslocked+0xb0/0xb8 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0+ #224 44b43e377bfc84bc99bb5ab885ff694984ee09ff pstate: 600001c9 (nZCv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : static_key_enable_cpuslocked+0xb0/0xb8 lr : static_key_enable_cpuslocked+0xb0/0xb8 sp : ffffffe51c393cf0 x29: ffffffe51c393cf0 x28: 000000008185054c x27: 00000000f1042f10 x26: 0000000000000000 x25: 00000000f10302b2 x24: 0000002513200000 x23: 0000002513200000 x22: ffffffe51c1c9000 x21: fffffffdfdc00000 x20: ffffffe51c2f0831 x19: ffffffe51c6fcfc0 x18: 00000000ffff1020 x17: 00000000e1e2ac90 x16: 00000000000000e0 x15: ffffffe51b710708 x14: 0000000000000066 x13: 0000000000000018 x12: 0000000000000000 x11: 0000000000000000 x10: 00000000ffffffff x9 : 0000000000000000 x8 : 0000000000000000 x7 : 61632065726f6665 x6 : 6220646573752027 x5 : ffffffe51c641d25 x4 : ffffffe51c13142c x3 : ffff0a00ffffff05 x2 : 40000000ffffe003 x1 : 00000000000001c0 x0 : 0000000000000065 Call trace: static_key_enable_cpuslocked+0xb0/0xb8 static_key_enable+0x2c/0x40 crng_set_ready+0x24/0x30 execute_in_process_context+0x80/0x90 _credit_init_bits+0x100/0x154 add_bootloader_randomness+0x64/0x78 early_init_dt_scan_chosen+0x140/0x184 early_init_dt_scan_nodes+0x28/0x4c early_init_dt_scan+0x40/0x44 setup_machine_fdt+0x7c/0x120 setup_arch+0x74/0x1d8 start_kernel+0x84/0x44c __primary_switched+0xc0/0xc8 ---[ end trace 0000000000000000 ]--- random: crng init done Machine model: Google Lazor (rev1 - 2) with LTE
Cc: Hsin-Yi Wang hsinyi@chromium.org Cc: Douglas Anderson dianders@chromium.org Cc: Ard Biesheuvel ardb@kernel.org Cc: Steven Rostedt rostedt@goodmis.org Cc: Jason A. Donenfeld Jason@zx2c4.com Cc: Dominik Brodowski linux@dominikbrodowski.net Fixes: f5bda35fba61 ("random: use static branch for crng_ready()") Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Jason A. Donenfeld Jason@zx2c4.com Link: https://lore.kernel.org/r/20220602022109.780348-1-swboyd@chromium.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/kernel/setup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -314,13 +314,14 @@ void __init __no_sanitize_address setup_ early_fixmap_init(); early_ioremap_init();
- setup_machine_fdt(__fdt_pointer); - /* * Initialise the static keys early as they may be enabled by the - * cpufeature code and early parameters. + * cpufeature code, early parameters, and DT setup. */ jump_label_init(); + + setup_machine_fdt(__fdt_pointer); + parse_early_param();
/*
On Tue, Jun 07, 2022 at 06:51:59PM +0200, Greg Kroah-Hartman wrote:
From: Stephen Boyd swboyd@chromium.org
commit 73e2d827a501d48dceeb5b9b267a4cd283d6b1ae upstream.
A static key warning splat appears during early boot on arm64 systems that credit randomness from devicetrees that contain an "rng-seed" property. This is because setup_machine_fdt() is called before jump_label_init() during setup_arch(). Let's swap the order of these two calls so that jump labels are initialized before the devicetree is unflattened and the rng seed is credited.
static_key_enable_cpuslocked(): static key '0xffffffe51c6fcfc0' used before call to jump_label_init() WARNING: CPU: 0 PID: 0 at kernel/jump_label.c:166 static_key_enable_cpuslocked+0xb0/0xb8 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0+ #224 44b43e377bfc84bc99bb5ab885ff694984ee09ff pstate: 600001c9 (nZCv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : static_key_enable_cpuslocked+0xb0/0xb8 lr : static_key_enable_cpuslocked+0xb0/0xb8 sp : ffffffe51c393cf0 x29: ffffffe51c393cf0 x28: 000000008185054c x27: 00000000f1042f10 x26: 0000000000000000 x25: 00000000f10302b2 x24: 0000002513200000 x23: 0000002513200000 x22: ffffffe51c1c9000 x21: fffffffdfdc00000 x20: ffffffe51c2f0831 x19: ffffffe51c6fcfc0 x18: 00000000ffff1020 x17: 00000000e1e2ac90 x16: 00000000000000e0 x15: ffffffe51b710708 x14: 0000000000000066 x13: 0000000000000018 x12: 0000000000000000 x11: 0000000000000000 x10: 00000000ffffffff x9 : 0000000000000000 x8 : 0000000000000000 x7 : 61632065726f6665 x6 : 6220646573752027 x5 : ffffffe51c641d25 x4 : ffffffe51c13142c x3 : ffff0a00ffffff05 x2 : 40000000ffffe003 x1 : 00000000000001c0 x0 : 0000000000000065 Call trace: static_key_enable_cpuslocked+0xb0/0xb8 static_key_enable+0x2c/0x40 crng_set_ready+0x24/0x30 execute_in_process_context+0x80/0x90 _credit_init_bits+0x100/0x154 add_bootloader_randomness+0x64/0x78 early_init_dt_scan_chosen+0x140/0x184 early_init_dt_scan_nodes+0x28/0x4c early_init_dt_scan+0x40/0x44 setup_machine_fdt+0x7c/0x120 setup_arch+0x74/0x1d8 start_kernel+0x84/0x44c __primary_switched+0xc0/0xc8 ---[ end trace 0000000000000000 ]--- random: crng init done Machine model: Google Lazor (rev1 - 2) with LTE
Cc: Hsin-Yi Wang hsinyi@chromium.org Cc: Douglas Anderson dianders@chromium.org Cc: Ard Biesheuvel ardb@kernel.org Cc: Steven Rostedt rostedt@goodmis.org Cc: Jason A. Donenfeld Jason@zx2c4.com Cc: Dominik Brodowski linux@dominikbrodowski.net Fixes: f5bda35fba61 ("random: use static branch for crng_ready()") Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Jason A. Donenfeld Jason@zx2c4.com Link: https://lore.kernel.org/r/20220602022109.780348-1-swboyd@chromium.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Please drop this patch from 5.18 stable (I think I gave the details on the 5.10 reply).
Thanks.
On Wed, Jun 08, 2022 at 10:11:37AM +0100, Catalin Marinas wrote:
On Tue, Jun 07, 2022 at 06:51:59PM +0200, Greg Kroah-Hartman wrote:
From: Stephen Boyd swboyd@chromium.org
commit 73e2d827a501d48dceeb5b9b267a4cd283d6b1ae upstream.
A static key warning splat appears during early boot on arm64 systems that credit randomness from devicetrees that contain an "rng-seed" property. This is because setup_machine_fdt() is called before jump_label_init() during setup_arch(). Let's swap the order of these two calls so that jump labels are initialized before the devicetree is unflattened and the rng seed is credited.
static_key_enable_cpuslocked(): static key '0xffffffe51c6fcfc0' used before call to jump_label_init() WARNING: CPU: 0 PID: 0 at kernel/jump_label.c:166 static_key_enable_cpuslocked+0xb0/0xb8 Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0+ #224 44b43e377bfc84bc99bb5ab885ff694984ee09ff pstate: 600001c9 (nZCv dAIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : static_key_enable_cpuslocked+0xb0/0xb8 lr : static_key_enable_cpuslocked+0xb0/0xb8 sp : ffffffe51c393cf0 x29: ffffffe51c393cf0 x28: 000000008185054c x27: 00000000f1042f10 x26: 0000000000000000 x25: 00000000f10302b2 x24: 0000002513200000 x23: 0000002513200000 x22: ffffffe51c1c9000 x21: fffffffdfdc00000 x20: ffffffe51c2f0831 x19: ffffffe51c6fcfc0 x18: 00000000ffff1020 x17: 00000000e1e2ac90 x16: 00000000000000e0 x15: ffffffe51b710708 x14: 0000000000000066 x13: 0000000000000018 x12: 0000000000000000 x11: 0000000000000000 x10: 00000000ffffffff x9 : 0000000000000000 x8 : 0000000000000000 x7 : 61632065726f6665 x6 : 6220646573752027 x5 : ffffffe51c641d25 x4 : ffffffe51c13142c x3 : ffff0a00ffffff05 x2 : 40000000ffffe003 x1 : 00000000000001c0 x0 : 0000000000000065 Call trace: static_key_enable_cpuslocked+0xb0/0xb8 static_key_enable+0x2c/0x40 crng_set_ready+0x24/0x30 execute_in_process_context+0x80/0x90 _credit_init_bits+0x100/0x154 add_bootloader_randomness+0x64/0x78 early_init_dt_scan_chosen+0x140/0x184 early_init_dt_scan_nodes+0x28/0x4c early_init_dt_scan+0x40/0x44 setup_machine_fdt+0x7c/0x120 setup_arch+0x74/0x1d8 start_kernel+0x84/0x44c __primary_switched+0xc0/0xc8 ---[ end trace 0000000000000000 ]--- random: crng init done Machine model: Google Lazor (rev1 - 2) with LTE
Cc: Hsin-Yi Wang hsinyi@chromium.org Cc: Douglas Anderson dianders@chromium.org Cc: Ard Biesheuvel ardb@kernel.org Cc: Steven Rostedt rostedt@goodmis.org Cc: Jason A. Donenfeld Jason@zx2c4.com Cc: Dominik Brodowski linux@dominikbrodowski.net Fixes: f5bda35fba61 ("random: use static branch for crng_ready()") Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Jason A. Donenfeld Jason@zx2c4.com Link: https://lore.kernel.org/r/20220602022109.780348-1-swboyd@chromium.org Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Please drop this patch from 5.18 stable (I think I gave the details on the 5.10 reply).
Dropped from all stable queues now, thanks.
greg k-h
From: Niklas Cassel niklas.cassel@wdc.com
commit 6045ab5fea4c849153ebeb0acb532da5f29d69c4 upstream.
bFLT binaries are usually created using elf2flt.
The linker script used by elf2flt has defined the .data section like the following for the last 19 years:
.data : { _sdata = . ; __data_start = . ; data_start = . ; *(.got.plt) *(.got) FILL(0) ; . = ALIGN(0x20) ; LONG(-1) . = ALIGN(0x20) ; ... }
It places the .got.plt input section before the .got input section. The same is true for the default linker script (ld --verbose) on most architectures except x86/x86-64.
The binfmt_flat loader should relocate all GOT entries until it encounters a -1 (the LONG(-1) in the linker script).
The problem is that the .got.plt input section starts with a GOTPLT header (which has size 16 bytes on elf64-riscv and 8 bytes on elf32-riscv), where the first word is set to -1. See the binutils implementation for riscv [1].
This causes the binfmt_flat loader to stop relocating GOT entries prematurely and thus causes the application to crash when running.
Fix this by skipping the whole GOTPLT header, since the whole GOTPLT header is reserved for the dynamic linker.
The GOTPLT header will only be skipped for bFLT binaries with flag FLAT_FLAG_GOTPIC set. This flag is unconditionally set by elf2flt if the supplied ELF binary has the symbol _GLOBAL_OFFSET_TABLE_ defined. ELF binaries without a .got input section should thus remain unaffected.
Tested on RISC-V Canaan Kendryte K210 and RISC-V QEMU nommu_virt_defconfig.
[1] https://sourceware.org/git/?p=binutils-gdb.git%3Ba=blob%3Bf=bfd/elfnn-riscv....
Cc: stable@vger.kernel.org Signed-off-by: Niklas Cassel niklas.cassel@wdc.com Reviewed-by: Damien Le Moal damien.lemoal@opensource.wdc.com Link: https://lore.kernel.org/r/20220414091018.896737-1-niklas.cassel@wdc.com Fixed-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/lkml/202204182333.OIUOotK8-lkp@intel.com Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/binfmt_flat.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
--- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -440,6 +440,30 @@ static void old_reloc(unsigned long rl)
/****************************************************************************/
+static inline u32 __user *skip_got_header(u32 __user *rp) +{ + if (IS_ENABLED(CONFIG_RISCV)) { + /* + * RISC-V has a 16 byte GOT PLT header for elf64-riscv + * and 8 byte GOT PLT header for elf32-riscv. + * Skip the whole GOT PLT header, since it is reserved + * for the dynamic linker (ld.so). + */ + u32 rp_val0, rp_val1; + + if (get_user(rp_val0, rp)) + return rp; + if (get_user(rp_val1, rp + 1)) + return rp; + + if (rp_val0 == 0xffffffff && rp_val1 == 0xffffffff) + rp += 4; + else if (rp_val0 == 0xffffffff) + rp += 2; + } + return rp; +} + static int load_flat_file(struct linux_binprm *bprm, struct lib_info *libinfo, int id, unsigned long *extra_stack) { @@ -789,7 +813,8 @@ static int load_flat_file(struct linux_b * image. */ if (flags & FLAT_FLAG_GOTPIC) { - for (rp = (u32 __user *)datapos; ; rp++) { + rp = skip_got_header((u32 __user *) datapos); + for (; ; rp++) { u32 addr, rp_val; if (get_user(rp_val, rp)) return -EFAULT;
From: Mikulas Patocka mpatocka@redhat.com
commit 6ba688364856ad083be537f08e86ba97f433d405 upstream.
With the kernel 5.18, the system will hang on boot if it is compiled with CONFIG_SCHED_MC. The last printed message is "Brought up 1 node, 1 CPU".
The crash happens in sd_init tl->mask (which is cpu_coregroup_mask) returns an empty mask. This happens because cpu_topology[0].core_sibling is empty. Consequently, sd_span is set to an empty mask sd_id = cpumask_first(sd_span) sets sd_id == NR_CPUS (because the mask is empty) sd->shared = *per_cpu_ptr(sdd->sds, sd_id); sets sd->shared to NULL because sd_id is out of range atomic_inc(&sd->shared->ref); crashes without printing anything
We can fix it by calling reset_cpu_topology() from init_cpu_topology() - this will initialize the sibling masks on CPUs, so that they're not empty.
This patch also removes the variable "dualcores_found", it is useless, because during boot, init_cpu_topology is called before store_cpu_topology. Thus, set_sched_topology(parisc_mc_topology) is never called. We don't need to call it at all because default_topology in kernel/sched/topology.c contains the same items as parisc_mc_topology.
Note that we should not call store_cpu_topology() from init_per_cpu() because it is called too early in the kernel initialization process and it results in the message "Failure to register CPU0 device". Before this patch, store_cpu_topology() would exit immediatelly because cpuid_topo->core id was uninitialized and it was 0.
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Cc: stable@vger.kernel.org # v5.18 Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/processor.c | 2 -- arch/parisc/kernel/topology.c | 16 +--------------- 2 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 26eb568f8b96..dddaaa6e7a82 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -327,8 +327,6 @@ int init_per_cpu(int cpunum) set_firmware_width(); ret = pdc_coproc_cfg(&coproc_cfg);
- store_cpu_topology(cpunum); - if(ret >= 0 && coproc_cfg.ccr_functional) { mtctl(coproc_cfg.ccr_functional, 10); /* 10 == Coprocessor Control Reg */
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c index 9696e3cb6a2a..b9d845e314f8 100644 --- a/arch/parisc/kernel/topology.c +++ b/arch/parisc/kernel/topology.c @@ -20,8 +20,6 @@
static DEFINE_PER_CPU(struct cpu, cpu_devices);
-static int dualcores_found; - /* * store_cpu_topology is called at boot when only one cpu is running * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, @@ -60,7 +58,6 @@ void store_cpu_topology(unsigned int cpuid) if (p->cpu_loc) { cpuid_topo->core_id++; cpuid_topo->package_id = cpu_topology[cpu].package_id; - dualcores_found = 1; continue; } } @@ -80,22 +77,11 @@ void store_cpu_topology(unsigned int cpuid) cpu_topology[cpuid].package_id); }
-static struct sched_domain_topology_level parisc_mc_topology[] = { -#ifdef CONFIG_SCHED_MC - { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, -#endif - - { cpu_cpu_mask, SD_INIT_NAME(DIE) }, - { NULL, }, -}; - /* * init_cpu_topology is called at boot when only one cpu is running * which prevent simultaneous write access to cpu_topology array */ void __init init_cpu_topology(void) { - /* Set scheduler topology descriptor */ - if (dualcores_found) - set_sched_topology(parisc_mc_topology); + reset_cpu_topology(); }
From: Helge Deller deller@gmx.de
commit cf936af790a3ef5f41ff687ec91bfbffee141278 upstream.
Implement fb_is_primary_device() function, so that fbcon detects if this framebuffer belongs to the default graphics card which was used to start the system.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/include/asm/fb.h | 4 ++++ drivers/video/console/sticore.c | 17 +++++++++++++++++ drivers/video/fbdev/stifb.c | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-)
--- a/arch/parisc/include/asm/fb.h +++ b/arch/parisc/include/asm/fb.h @@ -12,9 +12,13 @@ static inline void fb_pgprotect(struct f pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; }
+#if defined(CONFIG_STI_CONSOLE) || defined(CONFIG_FB_STI) +int fb_is_primary_device(struct fb_info *info); +#else static inline int fb_is_primary_device(struct fb_info *info) { return 0; } +#endif
#endif /* _ASM_FB_H_ */ --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -30,6 +30,7 @@ #include <asm/pdc.h> #include <asm/cacheflush.h> #include <asm/grfioctl.h> +#include <asm/fb.h>
#include "../fbdev/sticore.h"
@@ -1127,6 +1128,22 @@ int sti_call(const struct sti_struct *st return ret; }
+/* check if given fb_info is the primary device */ +int fb_is_primary_device(struct fb_info *info) +{ + struct sti_struct *sti; + + sti = sti_get_rom(0); + + /* if no built-in graphics card found, allow any fb driver as default */ + if (!sti) + return true; + + /* return true if it's the default built-in framebuffer driver */ + return (sti->info == info); +} +EXPORT_SYMBOL(fb_is_primary_device); + MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); MODULE_LICENSE("GPL v2"); --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -1358,11 +1358,11 @@ static int __init stifb_init_fb(struct s goto out_err3; }
+ /* save for primary gfx device detection & unregister_framebuffer() */ + sti->info = info; if (register_framebuffer(&fb->info) < 0) goto out_err4;
- sti->info = info; /* save for unregister_framebuffer() */ - fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", fix->id, var->xres,
From: Helge Deller deller@gmx.de
commit b046f984814af7985f444150ec28716d42d00d9a upstream.
Keep the pa_path (hardware path) of the graphics card in sti_struct and use this info to give more useful info which card is currently being used.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # v5.10+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/console/sticon.c | 5 ++++- drivers/video/console/sticore.c | 15 +++++++-------- drivers/video/fbdev/sticore.h | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-)
--- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -46,6 +46,7 @@ #include <linux/slab.h> #include <linux/font.h> #include <linux/crc32.h> +#include <linux/fb.h>
#include <asm/io.h>
@@ -392,7 +393,9 @@ static int __init sticonsole_init(void) for (i = 0; i < MAX_NR_CONSOLES; i++) font_data[i] = STI_DEF_FONT;
- pr_info("sticon: Initializing STI text console.\n"); + pr_info("sticon: Initializing STI text console on %s at [%s]\n", + sticon_sti->sti_data->inq_outptr.dev_name, + sticon_sti->pa_path); console_lock(); err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, PAGE0->mem_cons.cl_class != CL_DUPLEX); --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -34,7 +34,7 @@
#include "../fbdev/sticore.h"
-#define STI_DRIVERVERSION "Version 0.9b" +#define STI_DRIVERVERSION "Version 0.9c"
static struct sti_struct *default_sti __read_mostly;
@@ -503,7 +503,7 @@ sti_select_fbfont(struct sti_cooked_rom if (!fbfont) return NULL;
- pr_info("STI selected %ux%u framebuffer font %s for sticon\n", + pr_info(" using %ux%u framebuffer font %s\n", fbfont->width, fbfont->height, fbfont->name); bpc = ((fbfont->width+7)/8) * fbfont->height; @@ -947,6 +947,7 @@ out_err:
static void sticore_check_for_default_sti(struct sti_struct *sti, char *path) { + pr_info(" located at [%s]\n", sti->pa_path); if (strcmp (path, default_sti_path) == 0) default_sti = sti; } @@ -958,7 +959,6 @@ static void sticore_check_for_default_st */ static int __init sticore_pa_init(struct parisc_device *dev) { - char pa_path[21]; struct sti_struct *sti = NULL; int hpa = dev->hpa.start;
@@ -971,8 +971,8 @@ static int __init sticore_pa_init(struct if (!sti) return 1;
- print_pa_hwpath(dev, pa_path); - sticore_check_for_default_sti(sti, pa_path); + print_pa_hwpath(dev, sti->pa_path); + sticore_check_for_default_sti(sti, sti->pa_path); return 0; }
@@ -1008,9 +1008,8 @@ static int sticore_pci_init(struct pci_d
sti = sti_try_rom_generic(rom_base, fb_base, pd); if (sti) { - char pa_path[30]; - print_pci_hwpath(pd, pa_path); - sticore_check_for_default_sti(sti, pa_path); + print_pci_hwpath(pd, sti->pa_path); + sticore_check_for_default_sti(sti, sti->pa_path); } if (!sti) { --- a/drivers/video/fbdev/sticore.h +++ b/drivers/video/fbdev/sticore.h @@ -370,6 +370,9 @@ struct sti_struct {
/* pointer to all internal data */ struct sti_all_data *sti_data; + + /* pa_path of this device */ + char pa_path[24]; };
From: Xianting Tian xianting.tian@linux.alibaba.com
commit e61bf5c071148c80d091f8e7220b3b9130780ae3 upstream.
Commit 00ab027a3b82 ("RISC-V: Add kernel image sections to the resource tree") marked IORESOURCE_BUSY for reserved memory, which caused resource map failed in subsequent operations of related driver, so remove the IORESOURCE_BUSY flag. In order to prohibit userland mapping reserved memory, mark IORESOURCE_EXCLUSIVE for it.
The code to reproduce the issue, dts: mem0: memory@a0000000 { reg = <0x0 0xa0000000 0 0x1000000>; no-map; };
&test { status = "okay"; memory-region = <&mem0>; };
code: np = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); ret = of_address_to_resource(np, 0, &r); base = devm_ioremap_resource(&pdev->dev, &r); // base = -EBUSY
Fixes: 00ab027a3b82 ("RISC-V: Add kernel image sections to the resource tree") Reported-by: Huaming Jiang jianghuaming.jhm@alibaba-inc.com Reviewed-by: Guo Ren guoren@kernel.org Reviewed-by: Heiko Stuebner heiko@sntech.de Tested-by: Heiko Stuebner heiko@sntech.de Co-developed-by: Nick Kossifidis mick@ics.forth.gr Signed-off-by: Xianting Tian xianting.tian@linux.alibaba.com Link: https://lore.kernel.org/r/20220518013428.1338983-1-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/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -189,7 +189,7 @@ static void __init init_resources(void) res = &mem_res[res_idx--];
res->name = "Reserved"; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_MEM | IORESOURCE_EXCLUSIVE; res->start = __pfn_to_phys(memblock_region_reserved_base_pfn(region)); res->end = __pfn_to_phys(memblock_region_reserved_end_pfn(region)) - 1;
@@ -214,7 +214,7 @@ static void __init init_resources(void)
if (unlikely(memblock_is_nomap(region))) { res->name = "Reserved"; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + res->flags = IORESOURCE_MEM | IORESOURCE_EXCLUSIVE; } else { res->name = "System RAM"; res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
From: Alexandre Ghiti alexandre.ghiti@canonical.com
commit 35d33c76d68dfacc330a8eb477b51cc647c5a847 upstream.
Because of the stack canary feature that reads from the current task structure the stack canary value, the thread pointer register "tp" must be set before calling any C function from head.S: by chance, setup_vm and all the functions that it calls does not seem to be part of the functions where the canary check is done, but in the following commits, some functions will.
Fixes: f2c9699f65557a31 ("riscv: Add STACKPROTECTOR supported") Signed-off-by: Alexandre Ghiti alexandre.ghiti@canonical.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/kernel/head.S | 1 + 1 file changed, 1 insertion(+)
--- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -297,6 +297,7 @@ clear_bss_done: REG_S a0, (a2)
/* Initialize page tables and relocate to virtual addresses */ + la tp, init_task la sp, init_thread_union + THREAD_SIZE XIP_FIXUP_OFFSET sp #ifdef CONFIG_BUILTIN_DTB
From: Samuel Holland samuel@sholland.org
commit 2273272823db6f67d57761df8116ae32e7f05bed upstream.
irq_work is triggered via an IPI, but the IPI infrastructure is not included in uniprocessor kernels. As a result, irq_work never runs. Fall back to the tick-based irq_work implementation on uniprocessor configurations.
Fixes: 298447928bb1 ("riscv: Support irq_work via self IPIs") Signed-off-by: Samuel Holland samuel@sholland.org Reviewed-by: Heiko Stuebner heiko@sntech.de Link: https://lore.kernel.org/r/20220430030025.58405-1-samuel@sholland.org 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/irq_work.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/riscv/include/asm/irq_work.h +++ b/arch/riscv/include/asm/irq_work.h @@ -4,7 +4,7 @@
static inline bool arch_irq_work_has_interrupt(void) { - return true; + return IS_ENABLED(CONFIG_SMP); } extern void arch_irq_work_raise(void); #endif /* _ASM_RISCV_IRQ_WORK_H */
From: Tobias Klauser tklauser@distanz.ch
commit 02d88b40cb2e9614e0117c3385afdce878f0d377 upstream.
Move the __ARCH_WANT_MEMFD_SECRET define added in commit 7bb7f2ac24a0 ("arch, mm: wire up memfd_secret system call where relevant") to <uapi/asm/unistd.h> so __NR_memfd_secret is defined when including <unistd.h> in userspace.
This allows the memfd_secret selftest to pass on riscv.
Signed-off-by: Tobias Klauser tklauser@distanz.ch Link: https://lore.kernel.org/r/20220505081815.22808-1-tklauser@distanz.ch Fixes: 7bb7f2ac24a0 ("arch, mm: wire up memfd_secret system call where relevant") 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/unistd.h | 1 - arch/riscv/include/uapi/asm/unistd.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-)
--- a/arch/riscv/include/asm/unistd.h +++ b/arch/riscv/include/asm/unistd.h @@ -9,7 +9,6 @@ */
#define __ARCH_WANT_SYS_CLONE -#define __ARCH_WANT_MEMFD_SECRET
#include <uapi/asm/unistd.h>
--- a/arch/riscv/include/uapi/asm/unistd.h +++ b/arch/riscv/include/uapi/asm/unistd.h @@ -21,6 +21,7 @@ #endif /* __LP64__ */
#define __ARCH_WANT_SYS_CLONE3 +#define __ARCH_WANT_MEMFD_SECRET
#include <asm-generic/unistd.h>
From: Nathan Chancellor nathan@kernel.org
commit 61114e734ccb804bc12561ab4020745e02c468c2 upstream.
After commit 49b290e430d3 ("riscv: prevent compressed instructions in alternatives"), builds with LLVM's integrated assembler fail:
In file included from arch/riscv/mm/init.c:10: In file included from ./include/linux/mm.h:29: In file included from ./include/linux/pgtable.h:6: In file included from ./arch/riscv/include/asm/pgtable.h:108: ./arch/riscv/include/asm/tlbflush.h:23:2: error: expected assembly-time absolute expression ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory")); ^ ./arch/riscv/include/asm/errata_list.h:33:5: note: expanded from macro 'ALT_FLUSH_TLB_PAGE' asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \ ^ ./arch/riscv/include/asm/alternative-macros.h:187:2: note: expanded from macro 'ALTERNATIVE' _ALTERNATIVE_CFG(old_content, new_content, vendor_id, errata_id, CONFIG_k) ^ ./arch/riscv/include/asm/alternative-macros.h:113:2: note: expanded from macro '_ALTERNATIVE_CFG' __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k)) ^ ./arch/riscv/include/asm/alternative-macros.h:110:2: note: expanded from macro '__ALTERNATIVE_CFG' ALT_NEW_CONTENT(vendor_id, errata_id, enable, new_c) ^ ./arch/riscv/include/asm/alternative-macros.h:99:3: note: expanded from macro 'ALT_NEW_CONTENT' ".org . - (889b - 888b) + (887b - 886b)\n" \ ^ <inline asm>:26:6: note: instantiated into assembly here .org . - (889b - 888b) + (887b - 886b) ^
This error happens because LLVM's integrated assembler has a one-pass design, which means it cannot figure out the instruction lengths when the .org directive is outside of the subsection that contains the instructions, which was changed by the .option directives added by the above change.
Move the .org directives before the .previous directive so that these directives are always within the same subsection, which resolves the failures and does not introduce any new issues with GNU as. This was done for arm64 in commit 966a0acce2fc ("arm64/alternatives: move length validation inside the subsection") and commit 22315a2296f4 ("arm64: alternatives: Move length validation in alternative_{insn, endif}").
While there is no error from the assembly versions of the macro, they appear to have the same problem so just make the same change there as well so that there are no problems in the future.
Link: https://github.com/ClangBuiltLinux/linux/issues/1640 Reported-by: kernel test robot lkp@intel.com Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Heiko Stuebner heiko@sntech.de Tested-by: Heiko Stuebner heiko@sntech.de Link: https://lore.kernel.org/r/20220516214520.3252074-1-nathan@kernel.org 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/alternative-macros.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/riscv/include/asm/alternative-macros.h +++ b/arch/riscv/include/asm/alternative-macros.h @@ -23,9 +23,9 @@ 888 : \new_c 889 : - .previous .org . - (889b - 888b) + (887b - 886b) .org . - (887b - 886b) + (889b - 888b) + .previous .endif .endm
@@ -60,9 +60,9 @@ "888 :\n" \ new_c "\n" \ "889 :\n" \ - ".previous\n" \ ".org . - (887b - 886b) + (889b - 888b)\n" \ ".org . - (889b - 888b) + (887b - 886b)\n" \ + ".previous\n" \ ".endif\n"
#define __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, enable) \
From: Kailang Yang kailang@realtek.com
commit 60571929d06b028800f27b51a7c81de1144944cf upstream.
Add new type for ALC245.
Signed-off-by: Kailang Yang kailang@realtek.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/cef26a7cd3d146eb96a3994ce79e34d2@realtek.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3131,6 +3131,7 @@ enum { ALC269_TYPE_ALC257, ALC269_TYPE_ALC215, ALC269_TYPE_ALC225, + ALC269_TYPE_ALC245, ALC269_TYPE_ALC287, ALC269_TYPE_ALC294, ALC269_TYPE_ALC300, @@ -3168,6 +3169,7 @@ static int alc269_parse_auto_config(stru case ALC269_TYPE_ALC257: case ALC269_TYPE_ALC215: case ALC269_TYPE_ALC225: + case ALC269_TYPE_ALC245: case ALC269_TYPE_ALC287: case ALC269_TYPE_ALC294: case ALC269_TYPE_ALC300: @@ -3695,7 +3697,8 @@ static void alc225_init(struct hda_codec hda_nid_t hp_pin = alc_get_hp_pin(spec); bool hp1_pin_sense, hp2_pin_sense;
- if (spec->codec_variant != ALC269_TYPE_ALC287) + if (spec->codec_variant != ALC269_TYPE_ALC287 && + spec->codec_variant != ALC269_TYPE_ALC245) /* required only at boot or S3 and S4 resume time */ if (!spec->done_hp_init || is_s3_resume(codec) || @@ -10148,7 +10151,10 @@ static int patch_alc269(struct hda_codec case 0x10ec0245: case 0x10ec0285: case 0x10ec0289: - spec->codec_variant = ALC269_TYPE_ALC215; + if (alc_get_coef0(codec) & 0x0010) + spec->codec_variant = ALC269_TYPE_ALC245; + else + spec->codec_variant = ALC269_TYPE_ALC215; spec->shutup = alc225_shutup; spec->init_hook = alc225_init; spec->gen.mixer_nid = 0;
From: Rik van der Kemp rik@upto11.nl
commit 15dad62f4bdb5dc0f0efde8181d680db9963544c upstream.
The 2022-model XPS 15 appears to use the same 4-speakers-on-ALC289 audio setup as the Dell XPS 15 9510, so requires the same quirk to enable woofer output. Tested on my own 9520.
[ Move the entry to the right position in the SSID order -- tiwai ]
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216035 Cc: stable@vger.kernel.org Signed-off-by: Rik van der Kemp rik@upto11.nl Link: https://lore.kernel.org/r/181056a137b.d14baf90133058.8425453735588429828@upt... 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 @@ -8957,6 +8957,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
From: Marios Levogiannis marios.levogiannis@gmail.com
commit 9bfa7b36343c7d84370bc61c9ed774635b05e4eb upstream.
Set microphone pins 0x18 (rear) and 0x19 (front) to VREF_50 to fix the microphone noise on ASUS TUF B550M-PLUS which uses the ALCS1200A codec. The initial value was VREF_80.
The same issue is also present on Windows using both the default Windows driver and all tested Realtek drivers before version 6.0.9049.1. Comparing Realtek driver 6.0.9049.1 (the first one without the microphone noise) to Realtek driver 6.0.9047.1 (the last one with the microphone noise) revealed that the fix is the result of setting pins 0x18 and 0x19 to VREF_50.
This fix may also work for other boards that have been reported to have the same microphone issue and use the ALC1150 and ALCS1200A codecs, since these codecs are similar and the fix in the Realtek driver on Windows is common for both. However, it is currently enabled only for ASUS TUF B550M-PLUS as this is the only board that could be tested.
Signed-off-by: Marios Levogiannis marios.levogiannis@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220530074131.12258-1-marios.levogiannis@gmail.co... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1981,6 +1981,7 @@ enum { ALC1220_FIXUP_CLEVO_PB51ED_PINS, ALC887_FIXUP_ASUS_AUDIO, ALC887_FIXUP_ASUS_HMIC, + ALCS1200A_FIXUP_MIC_VREF, };
static void alc889_fixup_coef(struct hda_codec *codec, @@ -2526,6 +2527,14 @@ static const struct hda_fixup alc882_fix .chained = true, .chain_id = ALC887_FIXUP_ASUS_AUDIO, }, + [ALCS1200A_FIXUP_MIC_VREF] = { + .type = HDA_FIXUP_PINCTLS, + .v.pins = (const struct hda_pintbl[]) { + { 0x18, PIN_VREF50 }, /* rear mic */ + { 0x19, PIN_VREF50 }, /* front mic */ + {} + } + }, };
static const struct snd_pci_quirk alc882_fixup_tbl[] = { @@ -2563,6 +2572,7 @@ static const struct snd_pci_quirk alc882 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3), + SND_PCI_QUIRK(0x1043, 0x8797, "ASUS TUF B550M-PLUS", ALCS1200A_FIXUP_MIC_VREF), SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP), SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
From: Takashi Iwai tiwai@suse.de
commit 0125de38122f0f66bf61336158d12a1aabfe6425 upstream.
At closing a USB MIDI output substream, there might be still a pending work, which would eventually access the rawmidi runtime object that is being released. For fixing the race, make sure to cancel the pending work at closing.
Reported-by: syzbot+6912c9592caca7ca0e7d@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/000000000000e7e75005dfd07cf6@google.com Link: https://lore.kernel.org/r/20220525131203.11299-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/midi.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -1145,6 +1145,9 @@ static int snd_usbmidi_output_open(struc
static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) { + struct usbmidi_out_port *port = substream->runtime->private_data; + + cancel_work_sync(&port->ep->work); return substream_open(substream, 0, 0); }
From: Johan Hovold johan@kernel.org
commit e82e7c6dde91acd6748d672a44dc1980ce239f86 upstream.
At least one pl2303 device has a bcdUSB of 1.0.1 which most likely was was intended as 1.1.
Allow bcdDevice 1.0.1 but interpret it as 1.1.
Fixes: 1e9faef4d26d ("USB: serial: pl2303: fix HX type detection") Cc: stable@vger.kernel.org # 5.13 Link: https://lore.kernel.org/linux-usb/CAJixRzqf4a9-ZKZDgWxicc_BpfdZVE9qqGmkiO7xE... Reported-by: Gary van der Merwe gary.vandermerwe@fnb.co.za Link: https://lore.kernel.org/r/20220517161736.13313-1-johan@kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/pl2303.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -421,6 +421,9 @@ static int pl2303_detect_type(struct usb bcdUSB = le16_to_cpu(desc->bcdUSB);
switch (bcdUSB) { + case 0x101: + /* USB 1.0.1? Let's assume they meant 1.1... */ + fallthrough; case 0x110: switch (bcdDevice) { case 0x300:
From: Carl Yin(殷张成) carl.yin@quectel.com
commit 33b7af2f459df453feb0d44628d820c47fefe7a8 upstream.
The BG95 modem has 3 USB configurations that are configurable via the AT command AT+QCFGEXT="usbnet",["ecm"|"modem"|"rmnet"] which make the modem enumerate with the following interfaces, respectively:
"modem": Diag + GNSS + Modem + Modem "ecm" : Diag + GNSS + Modem + ECM "rmnet": Diag + GNSS + Modem + QMI Don't support Full QMI messages (e.g WDS_START_NETWORK_INTERFACE)
A detailed description of the USB configuration for each mode follows:
+QCFGEXT: "usbnet","modem" -------------------------- T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0700 Rev= 0.00 S: Manufacturer=Quectel, Incorporated S: Product=Quectel LPWA Module S: SerialNumber=884328a2 C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=fe Prot=ff Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+QCFGEXT: "usbnet","ecm" ------------------------ T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0700 Rev= 0.00 S: Manufacturer=Quectel, Incorporated S: Product=Quectel LPWA Module S: SerialNumber=884328a2 C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA A: FirstIf#= 3 IfCount= 2 Cls=02(comm.) Sub=00 Prot=00 I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms I: If#= 4 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether I:* If#= 4 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
+QCFGEXT: "usbnet","rmnet" -------------------------- T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0700 Rev= 0.00 S: Manufacturer=Quectel, Incorporated S: Product=Quectel LPWA Module S: SerialNumber=884328a2 C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan E: Ad=85(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Signed-off-by: Carl Yin carl.yin@quectel.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1137,6 +1137,8 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0700, 0xff), /* BG95 */ + .driver_info = RSVD(3) | ZLP }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
From: Monish Kumar R monish.kumar.r@intel.com
commit 97fa5887cf283bb75ffff5f6b2c0e71794c02400 upstream.
Add USB_QUIRK_NO_LPM and USB_QUIRK_RESET_RESUME quirks for Dell usb gen 2 device to not fail during enumeration.
Found this bug on own testing
Signed-off-by: Monish Kumar R monish.kumar.r@intel.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20220520130044.17303-1-monish.kumar.r@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -510,6 +510,9 @@ static const struct usb_device_id usb_qu /* DJI CineSSD */ { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
+ /* DELL USB GEN2 */ + { USB_DEVICE(0x413c, 0xb062), .driver_info = USB_QUIRK_NO_LPM | USB_QUIRK_RESET_RESUME }, + /* VCOM device */ { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
From: Linus Walleij linus.walleij@linaro.org
commit 26ae2c942b5702f2e43d36b2a4389cfb7d616b6a upstream.
Running the driver through kasan gives an interesting splat:
BUG: KASAN: global-out-of-bounds in isp1760_register+0x180/0x70c Read of size 20 at addr f1db2e64 by task swapper/0/1 (...) isp1760_register from isp1760_plat_probe+0x1d8/0x220 (...)
This happens because the loop reading the regmap fields for the different ISP1760 variants look like this:
for (i = 0; i < HC_FIELD_MAX; i++) { ... }
Meaning it expects the arrays to be at least HC_FIELD_MAX - 1 long.
However the arrays isp1760_hc_reg_fields[], isp1763_hc_reg_fields[], isp1763_hc_volatile_ranges[] and isp1763_dc_volatile_ranges[] are dynamically sized during compilation.
Fix this by putting an empty assignment to the [HC_FIELD_MAX] and [DC_FIELD_MAX] array member at the end of each array. This will make the array one member longer than it needs to be, but avoids the risk of overwriting whatever is inside [HC_FIELD_MAX - 1] and is simple and intuitive to read. Also add comments explaining what is going on.
Fixes: 1da9e1c06873 ("usb: isp1760: move to regmap for register access") Cc: stable@vger.kernel.org Cc: Rui Miguel Silva rui.silva@linaro.org Cc: Dietmar Eggemann dietmar.eggemann@arm.com Reviewed-by: Rui Miguel Silva rui.silva@linaro.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20220516091424.391209-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/isp1760/isp1760-core.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/drivers/usb/isp1760/isp1760-core.c +++ b/drivers/usb/isp1760/isp1760-core.c @@ -251,6 +251,8 @@ static const struct reg_field isp1760_hc [HW_DM_PULLDOWN] = REG_FIELD(ISP176x_HC_OTG_CTRL, 2, 2), [HW_DP_PULLDOWN] = REG_FIELD(ISP176x_HC_OTG_CTRL, 1, 1), [HW_DP_PULLUP] = REG_FIELD(ISP176x_HC_OTG_CTRL, 0, 0), + /* Make sure the array is sized properly during compilation */ + [HC_FIELD_MAX] = {}, };
static const struct reg_field isp1763_hc_reg_fields[] = { @@ -321,6 +323,8 @@ static const struct reg_field isp1763_hc [HW_DM_PULLDOWN_CLEAR] = REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 2, 2), [HW_DP_PULLDOWN_CLEAR] = REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 1, 1), [HW_DP_PULLUP_CLEAR] = REG_FIELD(ISP1763_HC_OTG_CTRL_CLEAR, 0, 0), + /* Make sure the array is sized properly during compilation */ + [HC_FIELD_MAX] = {}, };
static const struct regmap_range isp1763_hc_volatile_ranges[] = { @@ -405,6 +409,8 @@ static const struct reg_field isp1761_dc [DC_CHIP_ID_HIGH] = REG_FIELD(ISP176x_DC_CHIPID, 16, 31), [DC_CHIP_ID_LOW] = REG_FIELD(ISP176x_DC_CHIPID, 0, 15), [DC_SCRATCH] = REG_FIELD(ISP176x_DC_SCRATCH, 0, 15), + /* Make sure the array is sized properly during compilation */ + [DC_FIELD_MAX] = {}, };
static const struct regmap_range isp1763_dc_volatile_ranges[] = { @@ -458,6 +464,8 @@ static const struct reg_field isp1763_dc [DC_CHIP_ID_HIGH] = REG_FIELD(ISP1763_DC_CHIPID_HIGH, 0, 15), [DC_CHIP_ID_LOW] = REG_FIELD(ISP1763_DC_CHIPID_LOW, 0, 15), [DC_SCRATCH] = REG_FIELD(ISP1763_DC_SCRATCH, 0, 15), + /* Make sure the array is sized properly during compilation */ + [DC_FIELD_MAX] = {}, };
static const struct regmap_config isp1763_dc_regmap_conf = {
From: Albert Wang albertccwang@google.com
commit 3c5880745b4439ac64eccdb040e37fc1cc4c5406 upstream.
When dwc3_gadget_ep_cleanup_completed_requests() called to dwc3_gadget_giveback() where the dwc3 lock is released, other thread is able to execute. In this situation, usb_ep_disable() gets the chance to clear endpoint descriptor pointer which leds to the null pointer dereference problem. So needs to move the null pointer check to a proper place.
Example call stack:
Thread#1: dwc3_thread_interrupt() spin_lock -> dwc3_process_event_buf() -> dwc3_process_event_entry() -> dwc3_endpoint_interrupt() -> dwc3_gadget_endpoint_trbs_complete() -> dwc3_gadget_ep_cleanup_completed_requests() ... -> dwc3_giveback() spin_unlock Thread#2 executes
Thread#2: configfs_composite_disconnect() -> __composite_disconnect() -> ffs_func_disable() -> ffs_func_set_alt() -> ffs_func_eps_disable() -> usb_ep_disable() wait for dwc3 spin_lock Thread#1 released lock clear endpoint.desc
Fixes: 26288448120b ("usb: dwc3: gadget: Fix null pointer exception") Cc: stable stable@kernel.org Signed-off-by: Albert Wang albertccwang@google.com Link: https://lore.kernel.org/r/20220518061315.3359198-1-albertccwang@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3380,14 +3380,14 @@ static bool dwc3_gadget_endpoint_trbs_co struct dwc3 *dwc = dep->dwc; bool no_started_trb = true;
- if (!dep->endpoint.desc) - return no_started_trb; - dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) goto out;
+ if (!dep->endpoint.desc) + return no_started_trb; + if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && list_empty(&dep->started_list) && (list_empty(&dep->pending_list) || status == -EXDEV))
From: Kishon Vijay Abraham I kishon@ti.com
commit a44623d9279086c89f631201d993aa332f7c9e66 upstream.
It has been observed with certain PCIe USB cards (like Inateck connected to AM64 EVM or J7200 EVM) that as soon as the primary roothub is registered, port status change is handled even before xHC is running leading to cold plug USB devices not detected. For such cases, registering both the root hubs along with the second HCD is required. Add support for deferring roothub registration in usb_add_hcd(), so that both primary and secondary roothubs are registered along with the second HCD.
This patch has been added and reverted earier as it triggered a race in usb device enumeration. That race is now fixed in 5.16-rc3, and in stable back to 5.4 commit 6cca13de26ee ("usb: hub: Fix locking issues with address0_mutex") commit 6ae6dc22d2d1 ("usb: hub: Fix usb enumeration issue due to address0 race")
CC: stable@vger.kernel.org # 5.4+ Suggested-by: Mathias Nyman mathias.nyman@linux.intel.com Tested-by: Chris Chiu chris.chiu@canonical.com Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Link: https://lore.kernel.org/r/20220510091630.16564-2-kishon@ti.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/core/hcd.c | 29 +++++++++++++++++++++++------ include/linux/usb/hcd.h | 2 ++ 2 files changed, 25 insertions(+), 6 deletions(-)
--- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2816,6 +2816,7 @@ int usb_add_hcd(struct usb_hcd *hcd, { int retval; struct usb_device *rhdev; + struct usb_hcd *shared_hcd;
if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) { hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev); @@ -2976,13 +2977,26 @@ int usb_add_hcd(struct usb_hcd *hcd, goto err_hcd_driver_start; }
+ /* starting here, usbcore will pay attention to the shared HCD roothub */ + shared_hcd = hcd->shared_hcd; + if (!usb_hcd_is_primary_hcd(hcd) && shared_hcd && HCD_DEFER_RH_REGISTER(shared_hcd)) { + retval = register_root_hub(shared_hcd); + if (retval != 0) + goto err_register_root_hub; + + if (shared_hcd->uses_new_polling && HCD_POLL_RH(shared_hcd)) + usb_hcd_poll_rh_status(shared_hcd); + } + /* starting here, usbcore will pay attention to this root hub */ - retval = register_root_hub(hcd); - if (retval != 0) - goto err_register_root_hub; + if (!HCD_DEFER_RH_REGISTER(hcd)) { + retval = register_root_hub(hcd); + if (retval != 0) + goto err_register_root_hub;
- if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) - usb_hcd_poll_rh_status(hcd); + if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) + usb_hcd_poll_rh_status(hcd); + }
return retval;
@@ -3020,6 +3034,7 @@ EXPORT_SYMBOL_GPL(usb_add_hcd); void usb_remove_hcd(struct usb_hcd *hcd) { struct usb_device *rhdev = hcd->self.root_hub; + bool rh_registered;
dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
@@ -3030,6 +3045,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
dev_dbg(hcd->self.controller, "roothub graceful disconnect\n"); spin_lock_irq (&hcd_root_hub_lock); + rh_registered = hcd->rh_registered; hcd->rh_registered = 0; spin_unlock_irq (&hcd_root_hub_lock);
@@ -3039,7 +3055,8 @@ void usb_remove_hcd(struct usb_hcd *hcd) cancel_work_sync(&hcd->died_work);
mutex_lock(&usb_bus_idr_lock); - usb_disconnect(&rhdev); /* Sets rhdev to NULL */ + if (rh_registered) + usb_disconnect(&rhdev); /* Sets rhdev to NULL */ mutex_unlock(&usb_bus_idr_lock);
/* --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -124,6 +124,7 @@ struct usb_hcd { #define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ #define HCD_FLAG_DEAD 6 /* controller has died? */ #define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ +#define HCD_FLAG_DEFER_RH_REGISTER 8 /* Defer roothub registration */
/* The flags can be tested using these macros; they are likely to * be slightly faster than test_bit(). @@ -134,6 +135,7 @@ struct usb_hcd { #define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING)) #define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING)) #define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD)) +#define HCD_DEFER_RH_REGISTER(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEFER_RH_REGISTER))
/* * Specifies if interfaces are authorized by default
From: Mikulas Patocka mpatocka@redhat.com
commit 724bbe49c5e427cb077357d72d240a649f2e4054 upstream.
The ntfs3 filesystem lacks the 'invalidate_folio' method and it causes memory leak. If you write to the filesystem and then unmount it, the cached written data are not freed and they are permanently leaked. Fixes: 7ba13abbd31e ("fs: Turn block_invalidatepage into block_invalidate_folio")
Reported-by: José Luis Lara Carrascal manualinux@yahoo.es Signed-off-by: Mikulas Patocka mpatocka@redhat.com Acked-by: Matthew Wilcox (Oracle) willy@infradead.org Reviewed-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Cc: stable@vger.kernel.org # v5.18 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/inode.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -1951,6 +1951,7 @@ const struct address_space_operations nt .direct_IO = ntfs_direct_IO, .bmap = ntfs_bmap, .dirty_folio = block_dirty_folio, + .invalidate_folio = block_invalidate_folio, };
const struct address_space_operations ntfs_aops_cmpr = {
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 52e00ea6b26e45fb8159e3b57cdde8d3f9bdd8e9 upstream.
Update valid size if write is still in I/O queue. Fixes xfstest generic/240 Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/inode.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -757,6 +757,7 @@ static ssize_t ntfs_direct_IO(struct kio loff_t vbo = iocb->ki_pos; loff_t end; int wr = iov_iter_rw(iter) & WRITE; + size_t iter_count = iov_iter_count(iter); loff_t valid; ssize_t ret;
@@ -770,10 +771,13 @@ static ssize_t ntfs_direct_IO(struct kio wr ? ntfs_get_block_direct_IO_W : ntfs_get_block_direct_IO_R);
- if (ret <= 0) + if (ret > 0) + end = vbo + ret; + else if (wr && ret == -EIOCBQUEUED) + end = vbo + iter_count; + else goto out;
- end = vbo + ret; valid = ni->i_valid; if (wr) { if (end > valid && !S_ISBLK(inode->i_mode)) {
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 3880f2b816a7e4ca889b7e8a42e6c62c5706ed36 upstream.
Two problems: 1. ntfs3_setattr can't truncate preallocated space; 2. if allocated fragment "cross" valid size, then fragment splits into two parts: - normal part; - unwritten part (here we must return FIEMAP_EXTENT_LAST). Before this commit we returned FIEMAP_EXTENT_LAST for whole fragment. Fixes xfstest generic/092 Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/file.c | 2 +- fs/ntfs3/frecord.c | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-)
--- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -762,7 +762,7 @@ int ntfs3_setattr(struct user_namespace } inode_dio_wait(inode);
- if (attr->ia_size < oldsize) + if (attr->ia_size <= oldsize) err = ntfs_truncate(inode, attr->ia_size); else if (attr->ia_size > oldsize) err = ntfs_extend(inode, attr->ia_size, 0, NULL); --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -1964,10 +1964,8 @@ int ni_fiemap(struct ntfs_inode *ni, str
vcn += clen;
- if (vbo + bytes >= end) { + if (vbo + bytes >= end) bytes = end - vbo; - flags |= FIEMAP_EXTENT_LAST; - }
if (vbo + bytes <= valid) { ; @@ -1977,6 +1975,9 @@ int ni_fiemap(struct ntfs_inode *ni, str /* vbo < valid && valid < vbo + bytes */ u64 dlen = valid - vbo;
+ if (vbo + dlen >= end) + flags |= FIEMAP_EXTENT_LAST; + err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen, flags); if (err < 0) @@ -1995,6 +1996,9 @@ int ni_fiemap(struct ntfs_inode *ni, str flags |= FIEMAP_EXTENT_UNWRITTEN; }
+ if (vbo + bytes >= end) + flags |= FIEMAP_EXTENT_LAST; + err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags); if (err < 0) break;
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit e95113ed4d428219e3395044e29f5713fc446720 upstream.
If size of file was reduced, we still kept allocated blocks. This commit makes ntfs3 work as other fs like btrfs. Link: https://bugzilla.kernel.org/show_bug.cgi?id=214719 Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Reported-by: Ganapathi Kamath hgkamath@hotmail.com Tested-by: Ganapathi Kamath hgkamath@hotmail.com Reviewed-by: Kari Argillander kari.argillander@gmail.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -495,7 +495,7 @@ static int ntfs_truncate(struct inode *i
down_write(&ni->file.run_lock); err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size, - &new_valid, true, NULL); + &new_valid, ni->mi.sbi->options->prealloc, NULL); up_write(&ni->file.run_lock);
if (new_valid < ni->i_valid)
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 114346978cf61de02832cc3cc68432a3de70fb38 upstream.
We must check size before trying to allocate. Size can be set for example by "ulimit -f". Fixes xfstest generic/228 Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Reviewed-by: Kari Argillander kari.argillander@gmail.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -662,7 +662,13 @@ static long ntfs_fallocate(struct file * /* * Normal file: Allocate clusters, do not change 'valid' size. */ - err = ntfs_set_size(inode, max(end, i_size)); + loff_t new_size = max(end, i_size); + + err = inode_newsize_ok(inode, new_size); + if (err) + goto out; + + err = ntfs_set_size(inode, new_size); if (err) goto out;
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 9186d472ee780fabf74424756c4c00545166157e upstream.
ntfs_init_acl sets mode. ntfs_init_acl calls ntfs_set_acl_ex. ntfs_set_acl_ex must not change this mode. Fixes xfstest generic/444 Fixes: be71b5cba2e6 ("fs/ntfs3: Add attrib operations")
Reviewed-by: Joe Perches joe@perches.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/xattr.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -541,7 +541,7 @@ struct posix_acl *ntfs_get_acl(struct in
static noinline int ntfs_set_acl_ex(struct user_namespace *mnt_userns, struct inode *inode, struct posix_acl *acl, - int type) + int type, bool init_acl) { const char *name; size_t size, name_len; @@ -554,8 +554,9 @@ static noinline int ntfs_set_acl_ex(stru
switch (type) { case ACL_TYPE_ACCESS: - if (acl) { - umode_t mode = inode->i_mode; + /* Do not change i_mode if we are in init_acl */ + if (acl && !init_acl) { + umode_t mode;
err = posix_acl_update_mode(mnt_userns, inode, &mode, &acl); @@ -616,7 +617,7 @@ out: int ntfs_set_acl(struct user_namespace *mnt_userns, struct inode *inode, struct posix_acl *acl, int type) { - return ntfs_set_acl_ex(mnt_userns, inode, acl, type); + return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false); }
/* @@ -636,7 +637,7 @@ int ntfs_init_acl(struct user_namespace
if (default_acl) { err = ntfs_set_acl_ex(mnt_userns, inode, default_acl, - ACL_TYPE_DEFAULT); + ACL_TYPE_DEFAULT, true); posix_acl_release(default_acl); } else { inode->i_default_acl = NULL; @@ -647,7 +648,7 @@ int ntfs_init_acl(struct user_namespace else { if (!err) err = ntfs_set_acl_ex(mnt_userns, inode, acl, - ACL_TYPE_ACCESS); + ACL_TYPE_ACCESS, true); posix_acl_release(acl); }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit e589f9b7078e1c0191613cd736f598e81d2390de upstream.
All error handling paths lead to 'out' where many resources are freed.
Do it as well here instead of a direct return, otherwise 'log', 'ra' and 'log->one_page_buf' (at least) will leak.
Fixes: b46acd6a6a62 ("fs/ntfs3: Add NTFS journal") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/fslog.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -4085,8 +4085,10 @@ process_log: if (client == LFS_NO_CLIENT_LE) { /* Insert "NTFS" client LogFile. */ client = ra->client_idx[0]; - if (client == LFS_NO_CLIENT_LE) - return -EINVAL; + if (client == LFS_NO_CLIENT_LE) { + err = -EINVAL; + goto out; + }
t16 = le16_to_cpu(client); cr = ca + t16;
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 2d44667c306e7806848a3478820f87343feb5421 upstream.
Ctime wasn't updated after setfacl command. This commit fixes xfstest generic/307 Fixes: be71b5cba2e6 ("fs/ntfs3: Add attrib operations")
Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/xattr.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -902,6 +902,9 @@ set_new_fa: err = ntfs_set_ea(inode, name, name_len, value, size, flags);
out: + inode->i_ctime = current_time(inode); + mark_inode_dirty(inode); + return err; }
From: Konstantin Komarov almaz.alexandrovich@paragon-software.com
commit 87e21c99bad763524c953ff4d1a61ee19038ddc2 upstream.
Apparently we need to maintain these functions with ntfs_get_acl_ex and ntfs_set_acl_ex. This commit fixes xfstest generic/099 Fixes: 95dd8b2c1ed0 ("fs/ntfs3: Remove unnecessary functions")
Reviewed-by: Kari Argillander kari.argillander@gmail.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/xattr.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-)
--- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -112,7 +112,7 @@ static int ntfs_read_ea(struct ntfs_inod return -ENOMEM;
if (!size) { - ; + /* EA info persists, but xattr is empty. Looks like EA problem. */ } else if (attr_ea->non_res) { struct runs_tree run;
@@ -620,6 +620,67 @@ int ntfs_set_acl(struct user_namespace * return ntfs_set_acl_ex(mnt_userns, inode, acl, type, false); }
+static int ntfs_xattr_get_acl(struct user_namespace *mnt_userns, + struct inode *inode, int type, void *buffer, + size_t size) +{ + struct posix_acl *acl; + int err; + + if (!(inode->i_sb->s_flags & SB_POSIXACL)) { + ntfs_inode_warn(inode, "add mount option "acl" to use acl"); + return -EOPNOTSUPP; + } + + acl = ntfs_get_acl(inode, type, false); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + if (!acl) + return -ENODATA; + + err = posix_acl_to_xattr(mnt_userns, acl, buffer, size); + posix_acl_release(acl); + + return err; +} + +static int ntfs_xattr_set_acl(struct user_namespace *mnt_userns, + struct inode *inode, int type, const void *value, + size_t size) +{ + struct posix_acl *acl; + int err; + + if (!(inode->i_sb->s_flags & SB_POSIXACL)) { + ntfs_inode_warn(inode, "add mount option "acl" to use acl"); + return -EOPNOTSUPP; + } + + if (!inode_owner_or_capable(mnt_userns, inode)) + return -EPERM; + + if (!value) { + acl = NULL; + } else { + acl = posix_acl_from_xattr(mnt_userns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + if (acl) { + err = posix_acl_valid(mnt_userns, acl); + if (err) + goto release_and_out; + } + } + + err = ntfs_set_acl(mnt_userns, inode, acl, type); + +release_and_out: + posix_acl_release(acl); + return err; +} + /* * ntfs_init_acl - Initialize the ACLs of a new inode. * @@ -786,6 +847,23 @@ static int ntfs_getxattr(const struct xa goto out; }
+#ifdef CONFIG_NTFS3_FS_POSIX_ACL + if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 && + !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS, + sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) || + (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 && + !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, + sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) { + /* TODO: init_user_ns? */ + err = ntfs_xattr_get_acl( + &init_user_ns, inode, + name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 + ? ACL_TYPE_ACCESS + : ACL_TYPE_DEFAULT, + buffer, size); + goto out; + } +#endif /* Deal with NTFS extended attribute. */ err = ntfs_get_ea(inode, name, name_len, buffer, size, NULL);
@@ -898,6 +976,22 @@ set_new_fa: goto out; }
+#ifdef CONFIG_NTFS3_FS_POSIX_ACL + if ((name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 && + !memcmp(name, XATTR_NAME_POSIX_ACL_ACCESS, + sizeof(XATTR_NAME_POSIX_ACL_ACCESS))) || + (name_len == sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1 && + !memcmp(name, XATTR_NAME_POSIX_ACL_DEFAULT, + sizeof(XATTR_NAME_POSIX_ACL_DEFAULT)))) { + err = ntfs_xattr_set_acl( + mnt_userns, inode, + name_len == sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1 + ? ACL_TYPE_ACCESS + : ACL_TYPE_DEFAULT, + value, size); + goto out; + } +#endif /* Deal with NTFS extended attribute. */ err = ntfs_set_ea(inode, name, name_len, value, size, flags);
From: Enzo Matsumiya ematsumiya@suse.de
commit 421ef3d56513b2ff02e563623688cb6ab4977c4f upstream.
Also return EOPNOTSUPP if path is remote but nodfs was set.
Fixes: a2809d0e1696 ("cifs: quirk for STATUS_OBJECT_NAME_INVALID returned for non-ASCII dfs refs") Cc: stable@vger.kernel.org Reviewed-by: Paulo Alcantara (SUSE) pc@cjr.nz Signed-off-by: Enzo Matsumiya ematsumiya@suse.de Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/connect.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
--- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3432,6 +3432,7 @@ static int is_path_remote(struct mount_c struct cifs_tcon *tcon = mnt_ctx->tcon; struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; char *full_path; + bool nodfs = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS;
if (!server->ops->is_path_accessible) return -EOPNOTSUPP; @@ -3449,14 +3450,20 @@ static int is_path_remote(struct mount_c rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, full_path); #ifdef CONFIG_CIFS_DFS_UPCALL + if (nodfs) { + if (rc == -EREMOTE) + rc = -EOPNOTSUPP; + goto out; + } + + /* path *might* exist with non-ASCII characters in DFS root + * try again with full path (only if nodfs is not set) */ if (rc == -ENOENT && is_tcon_dfs(tcon)) rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon, cifs_sb, full_path); #endif - if (rc != 0 && rc != -EREMOTE) { - kfree(full_path); - return rc; - } + if (rc != 0 && rc != -EREMOTE) + goto out;
if (rc != -EREMOTE) { rc = cifs_are_all_path_components_accessible(server, xid, tcon, @@ -3468,6 +3475,7 @@ static int is_path_remote(struct mount_c } }
+out: kfree(full_path); return rc; }
From: Paulo Alcantara pc@cjr.nz
commit de3a9e943ddecba8d2ac1dde4cfff538e5c6a7b9 upstream.
Some older servers seem to require the workstation name during ntlmssp to be at most 15 chars (RFC1001 name length), so truncate it before sending when using insecure dialects.
Link: https://lore.kernel.org/r/e6837098-15d9-acb6-7e34-1923cf8c6fe1@winds.org Reported-by: Byron Stanoszek gandalf@winds.org Tested-by: Byron Stanoszek gandalf@winds.org Fixes: 49bd49f983b5 ("cifs: send workstation name during ntlmssp session setup") Cc: stable@vger.kernel.org Signed-off-by: Paulo Alcantara (SUSE) pc@cjr.nz Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/cifsglob.h | 15 ++++++++++++++- fs/cifs/connect.c | 22 ++++------------------ fs/cifs/fs_context.c | 29 ++++------------------------- fs/cifs/fs_context.h | 2 +- fs/cifs/misc.c | 1 - fs/cifs/sess.c | 6 +++--- 6 files changed, 26 insertions(+), 49 deletions(-)
--- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -944,7 +944,7 @@ struct cifs_ses { and after mount option parsing we fill it */ char *domainName; char *password; - char *workstation_name; + char workstation_name[CIFS_MAX_WORKSTATION_LEN]; struct session_key auth_key; struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */ enum securityEnum sectype; /* what security flavor was specified? */ @@ -1979,4 +1979,17 @@ static inline bool cifs_is_referral_serv return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER)); }
+static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses) +{ + if (WARN_ON_ONCE(!ses || !ses->server)) + return 0; + /* + * Make workstation name no more than 15 chars when using insecure dialects as some legacy + * servers do require it during NTLMSSP. + */ + if (ses->server->dialect <= SMB20_PROT_ID) + return min_t(size_t, sizeof(ses->workstation_name), RFC1001_NAME_LEN_WITH_NULL); + return sizeof(ses->workstation_name); +} + #endif /* _CIFS_GLOB_H */ --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2037,18 +2037,7 @@ cifs_set_cifscreds(struct smb3_fs_contex } }
- ctx->workstation_name = kstrdup(ses->workstation_name, GFP_KERNEL); - if (!ctx->workstation_name) { - cifs_dbg(FYI, "Unable to allocate memory for workstation_name\n"); - rc = -ENOMEM; - kfree(ctx->username); - ctx->username = NULL; - kfree_sensitive(ctx->password); - ctx->password = NULL; - kfree(ctx->domainname); - ctx->domainname = NULL; - goto out_key_put; - } + strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name));
out_key_put: up_read(&key->sem); @@ -2157,12 +2146,9 @@ cifs_get_smb_ses(struct TCP_Server_Info if (!ses->domainName) goto get_ses_fail; } - if (ctx->workstation_name) { - ses->workstation_name = kstrdup(ctx->workstation_name, - GFP_KERNEL); - if (!ses->workstation_name) - goto get_ses_fail; - } + + strscpy(ses->workstation_name, ctx->workstation_name, sizeof(ses->workstation_name)); + if (ctx->domainauto) ses->domainAuto = ctx->domainauto; ses->cred_uid = ctx->cred_uid; --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -312,7 +312,6 @@ smb3_fs_context_dup(struct smb3_fs_conte new_ctx->password = NULL; new_ctx->server_hostname = NULL; new_ctx->domainname = NULL; - new_ctx->workstation_name = NULL; new_ctx->UNC = NULL; new_ctx->source = NULL; new_ctx->iocharset = NULL; @@ -327,7 +326,6 @@ smb3_fs_context_dup(struct smb3_fs_conte DUP_CTX_STR(UNC); DUP_CTX_STR(source); DUP_CTX_STR(domainname); - DUP_CTX_STR(workstation_name); DUP_CTX_STR(nodename); DUP_CTX_STR(iocharset);
@@ -766,8 +764,7 @@ static int smb3_verify_reconfigure_ctx(s cifs_errorf(fc, "can not change domainname during remount\n"); return -EINVAL; } - if (new_ctx->workstation_name && - (!old_ctx->workstation_name || strcmp(new_ctx->workstation_name, old_ctx->workstation_name))) { + if (strcmp(new_ctx->workstation_name, old_ctx->workstation_name)) { cifs_errorf(fc, "can not change workstation_name during remount\n"); return -EINVAL; } @@ -814,7 +811,6 @@ static int smb3_reconfigure(struct fs_co STEAL_STRING(cifs_sb, ctx, username); STEAL_STRING(cifs_sb, ctx, password); STEAL_STRING(cifs_sb, ctx, domainname); - STEAL_STRING(cifs_sb, ctx, workstation_name); STEAL_STRING(cifs_sb, ctx, nodename); STEAL_STRING(cifs_sb, ctx, iocharset);
@@ -1467,22 +1463,15 @@ static int smb3_fs_context_parse_param(s
int smb3_init_fs_context(struct fs_context *fc) { - int rc; struct smb3_fs_context *ctx; char *nodename = utsname()->nodename; int i;
ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL); - if (unlikely(!ctx)) { - rc = -ENOMEM; - goto err_exit; - } + if (unlikely(!ctx)) + return -ENOMEM;
- ctx->workstation_name = kstrdup(nodename, GFP_KERNEL); - if (unlikely(!ctx->workstation_name)) { - rc = -ENOMEM; - goto err_exit; - } + strscpy(ctx->workstation_name, nodename, sizeof(ctx->workstation_name));
/* * does not have to be perfect mapping since field is @@ -1555,14 +1544,6 @@ int smb3_init_fs_context(struct fs_conte fc->fs_private = ctx; fc->ops = &smb3_fs_context_ops; return 0; - -err_exit: - if (ctx) { - kfree(ctx->workstation_name); - kfree(ctx); - } - - return rc; }
void @@ -1588,8 +1569,6 @@ smb3_cleanup_fs_context_contents(struct ctx->source = NULL; kfree(ctx->domainname); ctx->domainname = NULL; - kfree(ctx->workstation_name); - ctx->workstation_name = NULL; kfree(ctx->nodename); ctx->nodename = NULL; kfree(ctx->iocharset); --- a/fs/cifs/fs_context.h +++ b/fs/cifs/fs_context.h @@ -170,7 +170,7 @@ struct smb3_fs_context { char *server_hostname; char *UNC; char *nodename; - char *workstation_name; + char workstation_name[CIFS_MAX_WORKSTATION_LEN]; char *iocharset; /* local code page for mapping to and from Unicode */ char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -95,7 +95,6 @@ sesInfoFree(struct cifs_ses *buf_to_free kfree_sensitive(buf_to_free->password); kfree(buf_to_free->user_name); kfree(buf_to_free->domainName); - kfree(buf_to_free->workstation_name); kfree_sensitive(buf_to_free->auth_key.response); kfree(buf_to_free->iface_list); kfree_sensitive(buf_to_free); --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -714,9 +714,9 @@ static int size_of_ntlmssp_blob(struct c else sz += sizeof(__le16);
- if (ses->workstation_name) + if (ses->workstation_name[0]) sz += sizeof(__le16) * strnlen(ses->workstation_name, - CIFS_MAX_WORKSTATION_LEN); + ntlmssp_workstation_name_size(ses)); else sz += sizeof(__le16);
@@ -960,7 +960,7 @@ int build_ntlmssp_auth_blob(unsigned cha
cifs_security_buffer_from_str(&sec_blob->WorkstationName, ses->workstation_name, - CIFS_MAX_WORKSTATION_LEN, + ntlmssp_workstation_name_size(ses), *pbuffer, &tmp, nls_cp);
From: Ronnie Sahlberg lsahlber@redhat.com
commit 8378a51e3f8140f60901fb27208cc7a6e47047b5 upstream.
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=2088799
Cc: stable@vger.kernel.org Signed-off-by: Roberto Bergantinos rbergant@redhat.com Signed-off-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/cifsfs.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -836,7 +836,7 @@ cifs_smb3_do_mount(struct file_system_ty int flags, struct smb3_fs_context *old_ctx) { int rc; - struct super_block *sb; + struct super_block *sb = NULL; struct cifs_sb_info *cifs_sb = NULL; struct cifs_mnt_data mnt_data; struct dentry *root; @@ -932,9 +932,11 @@ out_super: return root; out: if (cifs_sb) { - kfree(cifs_sb->prepath); - smb3_cleanup_fs_context(cifs_sb->ctx); - kfree(cifs_sb); + if (!sb || IS_ERR(sb)) { /* otherwise kill_sb will handle */ + kfree(cifs_sb->prepath); + smb3_cleanup_fs_context(cifs_sb->ctx); + kfree(cifs_sb); + } } return root; }
From: Ronnie Sahlberg lsahlber@redhat.com
commit f66f8b94e7f2f4ac9fffe710be231ca8f25c5057 upstream.
as this is the only way to make sure the region is allocated. Fix the conditional that was wrong and only tried to make already non-sparse files non-sparse.
Cc: stable@vger.kernel.org Signed-off-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -3837,7 +3837,7 @@ static long smb3_simple_falloc(struct fi if (rc) goto out;
- if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0) + if (cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) smb2_set_sparse(xid, tcon, cfile, inode, false);
eof = cpu_to_le64(off + len);
From: Kishon Vijay Abraham I kishon@ti.com
commit b7a4f9b5d0e4b6dd937678c546c0b322dd1a4054 upstream.
Set "HCD_FLAG_DEFER_RH_REGISTER" to hcd->flags in xhci_run() to defer registering primary roothub in usb_add_hcd() if xhci has two roothubs. This will make sure both primary roothub and secondary roothub will be registered along with the second HCD. This is required for cold plugged USB devices to be detected in certain PCIe USB cards (like Inateck USB card connected to AM64 EVM or J7200 EVM).
This patch has been added and reverted earier as it triggered a race in usb device enumeration. That race is now fixed in 5.16-rc3, and in stable back to 5.4 commit 6cca13de26ee ("usb: hub: Fix locking issues with address0_mutex") commit 6ae6dc22d2d1 ("usb: hub: Fix usb enumeration issue due to address0 race")
[minor rebase change, and commit message update -Mathias]
CC: stable@vger.kernel.org # 5.4+ Suggested-by: Mathias Nyman mathias.nyman@linux.intel.com Tested-by: Chris Chiu chris.chiu@canonical.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Link: https://lore.kernel.org/r/20220510091630.16564-3-kishon@ti.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -696,6 +696,8 @@ int xhci_run(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_run for USB2 roothub");
+ set_bit(HCD_FLAG_DEFER_RH_REGISTER, &hcd->flags); + xhci_create_dbc_dev(xhci);
xhci_debugfs_init(xhci);
From: Mathias Nyman mathias.nyman@linux.intel.com
commit 74f55a62c4c354f43a6d75f77dd184c4f57b9a26 upstream.
Alder Lake N TCSS xHCI needs to be runtime suspended whenever possible to allow the TCSS hardware block to enter D3 and thus save energy
Cc: stable@kernel.org Suggested-by: Gopal Vamshi Krishna vamshi.krishna.gopal@intel.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20220511220450.85367-10-mathias.nyman@linux.intel.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-pci.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -59,6 +59,7 @@ #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13 #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e +#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI 0x464e #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 @@ -268,6 +269,7 @@ static void xhci_pci_quirks(struct devic pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_N_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)) xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
From: Michael Niewöhner linux@mniewoehner.de
commit 1620c80bba53af8c547bab34a1d3bc58319fe608 upstream.
intel_hid_dsm_fn_mask is a bit mask containing one bit for each function index. Fix the function index check in intel_hid_evaluate_method accordingly, which was missed in commit 97ab4516205e ("platform/x86: intel-hid: fix _DSM function index handling").
Fixes: 97ab4516205e ("platform/x86: intel-hid: fix _DSM function index handling") Cc: stable@vger.kernel.org Signed-off-by: Michael Niewöhner linux@mniewoehner.de Link: https://lore.kernel.org/r/66f813f5bcc724a0f6dd5adefe6a9728dbe509e3.camel@mni... Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/platform/x86/intel/hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -238,7 +238,7 @@ static bool intel_hid_evaluate_method(ac
method_name = (char *)intel_hid_dsm_fn_to_method[fn_index];
- if (!(intel_hid_dsm_fn_mask & fn_index)) + if (!(intel_hid_dsm_fn_mask & BIT(fn_index))) goto skip_dsm_eval;
obj = acpi_evaluate_dsm_typed(handle, &intel_dsm_guid,
From: Ammar Faizi ammarfaizi2@gnuweeb.org
commit e5f28623ceb103e13fc3d7bd45edf9818b227fd0 upstream.
In mce_threshold_create_device(), if threshold_create_bank() fails, the previously allocated threshold banks array @bp will be leaked because the call to mce_threshold_remove_device() will not free it.
This happens because mce_threshold_remove_device() fetches the pointer through the threshold_banks per-CPU variable but bp is written there only after the bank creation is successful, and not before, when threshold_create_bank() fails.
Add a helper which unwinds all the bank creation work previously done and pass into it the previously allocated threshold banks array for freeing.
[ bp: Massage. ]
Fixes: 6458de97fc15 ("x86/mce/amd: Straighten CPU hotplug path") Co-developed-by: Alviro Iskandar Setiawan alviro.iskandar@gnuweeb.org Signed-off-by: Alviro Iskandar Setiawan alviro.iskandar@gnuweeb.org Co-developed-by: Yazen Ghannam yazen.ghannam@amd.com Signed-off-by: Yazen Ghannam yazen.ghannam@amd.com Signed-off-by: Ammar Faizi ammarfaizi2@gnuweeb.org Signed-off-by: Borislav Petkov bp@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220329104705.65256-3-ammarfaizi2@gnuweeb.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/cpu/mce/amd.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
--- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -1294,10 +1294,23 @@ out_free: kfree(bank); }
+static void __threshold_remove_device(struct threshold_bank **bp) +{ + unsigned int bank, numbanks = this_cpu_read(mce_num_banks); + + for (bank = 0; bank < numbanks; bank++) { + if (!bp[bank]) + continue; + + threshold_remove_bank(bp[bank]); + bp[bank] = NULL; + } + kfree(bp); +} + int mce_threshold_remove_device(unsigned int cpu) { struct threshold_bank **bp = this_cpu_read(threshold_banks); - unsigned int bank, numbanks = this_cpu_read(mce_num_banks);
if (!bp) return 0; @@ -1308,13 +1321,7 @@ int mce_threshold_remove_device(unsigned */ this_cpu_write(threshold_banks, NULL);
- for (bank = 0; bank < numbanks; bank++) { - if (bp[bank]) { - threshold_remove_bank(bp[bank]); - bp[bank] = NULL; - } - } - kfree(bp); + __threshold_remove_device(bp); return 0; }
@@ -1351,15 +1358,14 @@ int mce_threshold_create_device(unsigned if (!(this_cpu_read(bank_map) & (1 << bank))) continue; err = threshold_create_bank(bp, cpu, bank); - if (err) - goto out_err; + if (err) { + __threshold_remove_device(bp); + return err; + } } this_cpu_write(threshold_banks, bp);
if (thresholding_irq_en) mce_threshold_vector = amd_threshold_interrupt; return 0; -out_err: - mce_threshold_remove_device(cpu); - return err; }
From: Kan Liang kan.liang@linux.intel.com
commit 86dca369075b3e310c3c0adb0f81e513c562b5e4 upstream.
According to the latest event list, the event encoding 0x55 INST_DECODED.DECODERS and 0x56 UOPS_DECODED.DEC0 are only available on the first 4 counters. Add them into the event constraints table.
Fixes: 6017608936c1 ("perf/x86/intel: Add Icelake support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Acked-by: Peter Zijlstra peterz@infradead.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220525133952.1660658-1-kan.liang@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/events/intel/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -276,7 +276,7 @@ static struct event_constraint intel_icl INTEL_EVENT_CONSTRAINT_RANGE(0x03, 0x0a, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0x1f, 0x28, 0xf), INTEL_EVENT_CONSTRAINT(0x32, 0xf), /* SW_PREFETCH_ACCESS.* */ - INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x54, 0xf), + INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x56, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0x60, 0x8b, 0xf), INTEL_UEVENT_CONSTRAINT(0x04a3, 0xff), /* CYCLE_ACTIVITY.STALLS_TOTAL */ INTEL_UEVENT_CONSTRAINT(0x10a3, 0xff), /* CYCLE_ACTIVITY.CYCLES_MEM_ANY */
From: Baoquan He bhe@redhat.com
commit b3e34a47f98974d0844444c5121aaff123004e57 upstream.
This is reported by kmemleak detector:
unreferenced object 0xffffc900002a9000 (size 4096): comm "kexec", pid 14950, jiffies 4295110793 (age 373.951s) hex dump (first 32 bytes): 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 .ELF............ 04 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 ..>............. backtrace: [<0000000016a8ef9f>] __vmalloc_node_range+0x101/0x170 [<000000002b66b6c0>] __vmalloc_node+0xb4/0x160 [<00000000ad40107d>] crash_prepare_elf64_headers+0x8e/0xcd0 [<0000000019afff23>] crash_load_segments+0x260/0x470 [<0000000019ebe95c>] bzImage64_load+0x814/0xad0 [<0000000093e16b05>] arch_kexec_kernel_image_load+0x1be/0x2a0 [<000000009ef2fc88>] kimage_file_alloc_init+0x2ec/0x5a0 [<0000000038f5a97a>] __do_sys_kexec_file_load+0x28d/0x530 [<0000000087c19992>] do_syscall_64+0x3b/0x90 [<0000000066e063a4>] entry_SYSCALL_64_after_hwframe+0x44/0xae
In crash_prepare_elf64_headers(), a buffer is allocated via vmalloc() to store elf headers. While it's not freed back to system correctly when kdump kernel is reloaded or unloaded. Then memory leak is caused. Fix it by introducing x86 specific function arch_kimage_file_post_load_cleanup(), and freeing the buffer there.
And also remove the incorrect elf header buffer freeing code. Before calling arch specific kexec_file loading function, the image instance has been initialized. So 'image->elf_headers' must be NULL. It doesn't make sense to free the elf header buffer in the place.
Three different people have reported three bugs about the memory leak on x86_64 inside Redhat.
Link: https://lkml.kernel.org/r/20220223113225.63106-2-bhe@redhat.com Signed-off-by: Baoquan He bhe@redhat.com Acked-by: Dave Young dyoung@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/machine_kexec_64.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -376,9 +376,6 @@ void machine_kexec(struct kimage *image) #ifdef CONFIG_KEXEC_FILE void *arch_kexec_kernel_image_load(struct kimage *image) { - vfree(image->elf_headers); - image->elf_headers = NULL; - if (!image->fops || !image->fops->load) return ERR_PTR(-ENOEXEC);
@@ -514,6 +511,15 @@ overflow: (int)ELF64_R_TYPE(rel[i].r_info), value); return -ENOEXEC; } + +int arch_kimage_file_post_load_cleanup(struct kimage *image) +{ + vfree(image->elf_headers); + image->elf_headers = NULL; + image->elf_headers_sz = 0; + + return kexec_image_post_load_cleanup_default(image); +} #endif /* CONFIG_KEXEC_FILE */
static int
From: Kristen Carlson Accardi kristen@linux.intel.com
commit 0c9782e204d3cc5625b9e8bf4e8625d38dfe0139 upstream.
When the system runs out of enclave memory, SGX can reclaim EPC pages by swapping to normal RAM. These backing pages are allocated via a per-enclave shared memory area. Since SGX allows unlimited over commit on EPC memory, the reclaimer thread can allocate a large number of backing RAM pages in response to EPC memory pressure.
When the shared memory backing RAM allocation occurs during the reclaimer thread context, the shared memory is charged to the root memory control group, and the shmem usage of the enclave is not properly accounted for, making cgroups ineffective at limiting the amount of RAM an enclave can consume.
For example, when using a cgroup to launch a set of test enclaves, the kernel does not properly account for 50% - 75% of shmem page allocations on average. In the worst case, when nearly all allocations occur during the reclaimer thread, the kernel accounts less than a percent of the amount of shmem used by the enclave's cgroup to the correct cgroup.
SGX stores a list of mm_structs that are associated with an enclave. Pick one of them during reclaim and charge that mm's memcg with the shmem allocation. The one that gets picked is arbitrary, but this list almost always only has one mm. The cases where there is more than one mm with different memcg's are not worth considering.
Create a new function - sgx_encl_alloc_backing(). This function is used whenever a new backing storage page needs to be allocated. Previously the same function was used for page allocation as well as retrieving a previously allocated page. Prior to backing page allocation, if there is a mm_struct associated with the enclave that is requesting the allocation, it is set as the active memory control group.
[ dhansen: - fix merge conflict with ELDU fixes - check against actual ksgxd_tsk, not ->mm ]
Cc: stable@vger.kernel.org Signed-off-by: Kristen Carlson Accardi kristen@linux.intel.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Shakeel Butt shakeelb@google.com Acked-by: Roman Gushchin roman.gushchin@linux.dev Link: https://lkml.kernel.org/r/20220520174248.4918-1-kristen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/cpu/sgx/encl.c | 105 ++++++++++++++++++++++++++++++++++++++++- arch/x86/kernel/cpu/sgx/encl.h | 7 +- arch/x86/kernel/cpu/sgx/main.c | 9 ++- 3 files changed, 115 insertions(+), 6 deletions(-)
--- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -152,7 +152,7 @@ static int __sgx_encl_eldu(struct sgx_en
page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index);
- ret = sgx_encl_get_backing(encl, page_index, &b); + ret = sgx_encl_lookup_backing(encl, page_index, &b); if (ret) return ret;
@@ -718,7 +718,7 @@ static struct page *sgx_encl_get_backing * 0 on success, * -errno otherwise. */ -int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, +static int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, struct sgx_backing *backing) { pgoff_t page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index); @@ -743,6 +743,107 @@ int sgx_encl_get_backing(struct sgx_encl return 0; }
+/* + * When called from ksgxd, returns the mem_cgroup of a struct mm stored + * in the enclave's mm_list. When not called from ksgxd, just returns + * the mem_cgroup of the current task. + */ +static struct mem_cgroup *sgx_encl_get_mem_cgroup(struct sgx_encl *encl) +{ + struct mem_cgroup *memcg = NULL; + struct sgx_encl_mm *encl_mm; + int idx; + + /* + * If called from normal task context, return the mem_cgroup + * of the current task's mm. The remainder of the handling is for + * ksgxd. + */ + if (!current_is_ksgxd()) + return get_mem_cgroup_from_mm(current->mm); + + /* + * Search the enclave's mm_list to find an mm associated with + * this enclave to charge the allocation to. + */ + idx = srcu_read_lock(&encl->srcu); + + list_for_each_entry_rcu(encl_mm, &encl->mm_list, list) { + if (!mmget_not_zero(encl_mm->mm)) + continue; + + memcg = get_mem_cgroup_from_mm(encl_mm->mm); + + mmput_async(encl_mm->mm); + + break; + } + + srcu_read_unlock(&encl->srcu, idx); + + /* + * In the rare case that there isn't an mm associated with + * the enclave, set memcg to the current active mem_cgroup. + * This will be the root mem_cgroup if there is no active + * mem_cgroup. + */ + if (!memcg) + return get_mem_cgroup_from_mm(NULL); + + return memcg; +} + +/** + * sgx_encl_alloc_backing() - allocate a new backing storage page + * @encl: an enclave pointer + * @page_index: enclave page index + * @backing: data for accessing backing storage for the page + * + * When called from ksgxd, sets the active memcg from one of the + * mms in the enclave's mm_list prior to any backing page allocation, + * in order to ensure that shmem page allocations are charged to the + * enclave. + * + * Return: + * 0 on success, + * -errno otherwise. + */ +int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, + struct sgx_backing *backing) +{ + struct mem_cgroup *encl_memcg = sgx_encl_get_mem_cgroup(encl); + struct mem_cgroup *memcg = set_active_memcg(encl_memcg); + int ret; + + ret = sgx_encl_get_backing(encl, page_index, backing); + + set_active_memcg(memcg); + mem_cgroup_put(encl_memcg); + + return ret; +} + +/** + * sgx_encl_lookup_backing() - retrieve an existing backing storage page + * @encl: an enclave pointer + * @page_index: enclave page index + * @backing: data for accessing backing storage for the page + * + * Retrieve a backing page for loading data back into an EPC page with ELDU. + * It is the caller's responsibility to ensure that it is appropriate to use + * sgx_encl_lookup_backing() rather than sgx_encl_alloc_backing(). If lookup is + * not used correctly, this will cause an allocation which is not accounted for. + * + * Return: + * 0 on success, + * -errno otherwise. + */ +int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, + struct sgx_backing *backing) +{ + return sgx_encl_get_backing(encl, page_index, backing); +} + /** * sgx_encl_put_backing() - Unpin the backing storage * @backing: data for accessing backing storage for the page --- a/arch/x86/kernel/cpu/sgx/encl.h +++ b/arch/x86/kernel/cpu/sgx/encl.h @@ -103,10 +103,13 @@ static inline int sgx_encl_find(struct m int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start, unsigned long end, unsigned long vm_flags);
+bool current_is_ksgxd(void); void sgx_encl_release(struct kref *ref); int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm); -int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index, - struct sgx_backing *backing); +int sgx_encl_lookup_backing(struct sgx_encl *encl, unsigned long page_index, + struct sgx_backing *backing); +int sgx_encl_alloc_backing(struct sgx_encl *encl, unsigned long page_index, + struct sgx_backing *backing); void sgx_encl_put_backing(struct sgx_backing *backing); int sgx_encl_test_and_clear_young(struct mm_struct *mm, struct sgx_encl_page *page); --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -313,7 +313,7 @@ static void sgx_reclaimer_write(struct s sgx_encl_put_backing(backing);
if (!encl->secs_child_cnt && test_bit(SGX_ENCL_INITIALIZED, &encl->flags)) { - ret = sgx_encl_get_backing(encl, PFN_DOWN(encl->size), + ret = sgx_encl_alloc_backing(encl, PFN_DOWN(encl->size), &secs_backing); if (ret) goto out; @@ -384,7 +384,7 @@ static void sgx_reclaim_pages(void) page_index = PFN_DOWN(encl_page->desc - encl_page->encl->base);
mutex_lock(&encl_page->encl->lock); - ret = sgx_encl_get_backing(encl_page->encl, page_index, &backing[i]); + ret = sgx_encl_alloc_backing(encl_page->encl, page_index, &backing[i]); if (ret) { mutex_unlock(&encl_page->encl->lock); goto skip; @@ -475,6 +475,11 @@ static bool __init sgx_page_reclaimer_in return true; }
+bool current_is_ksgxd(void) +{ + return current == ksgxd_tsk; +} + static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid) { struct sgx_numa_node *node = &sgx_numa_nodes[nid];
From: Eric W. Biederman ebiederm@xmission.com
commit 343f4c49f2438d8920f1f76fa823ee59b91f02e4 upstream.
If kthread_is_per_cpu runs concurrently with free_kthread_struct the kthread_struct that was just freed may be read from.
This bug was introduced by commit 40966e316f86 ("kthread: Ensure struct kthread is present for all kthreads"). When kthread_struct started to be allocated for all tasks that have PF_KTHREAD set. This in turn required the kthread_struct to be freed in kernel_execve and violated the assumption that kthread_struct will have the same lifetime as the task.
Looking a bit deeper this only applies to callers of kernel_execve which is just the init process and the user mode helper processes. These processes really don't want to be kernel threads but are for historical reasons. Mostly that copy_thread does not know how to take a kernel mode function to the process with for processes without PF_KTHREAD or PF_IO_WORKER set.
Solve this by not allocating kthread_struct for the init process and the user mode helper processes.
This is done by adding a kthread member to struct kernel_clone_args. Setting kthread in fork_idle and kernel_thread. Adding user_mode_thread that works like kernel_thread except it does not set kthread. In fork only allocating the kthread_struct if .kthread is set.
I have looked at kernel/kthread.c and since commit 40966e316f86 ("kthread: Ensure struct kthread is present for all kthreads") there have been no assumptions added that to_kthread or __to_kthread will not return NULL.
There are a few callers of to_kthread or __to_kthread that assume a non-NULL struct kthread pointer will be returned. These functions are kthread_data(), kthread_parmme(), kthread_exit(), kthread(), kthread_park(), kthread_unpark(), kthread_stop(). All of those functions can reasonably expected to be called when it is know that a task is a kthread so that assumption seems reasonable.
Cc: stable@vger.kernel.org Fixes: 40966e316f86 ("kthread: Ensure struct kthread is present for all kthreads") Reported-by: Максим Кутявин maximkabox13@gmail.com Link: https://lkml.kernel.org/r/20220506141512.516114-1-ebiederm@xmission.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/exec.c | 6 ++++-- include/linux/sched/task.h | 2 ++ init/main.c | 2 +- kernel/fork.c | 22 ++++++++++++++++++++-- kernel/umh.c | 6 +++--- 5 files changed, 30 insertions(+), 8 deletions(-)
--- a/fs/exec.c +++ b/fs/exec.c @@ -1308,8 +1308,6 @@ int begin_new_exec(struct linux_binprm * if (retval) goto out_unlock;
- if (me->flags & PF_KTHREAD) - free_kthread_struct(me); me->flags &= ~(PF_RANDOMIZE | PF_FORKNOEXEC | PF_KTHREAD | PF_NOFREEZE | PF_NO_SETAFFINITY); flush_thread(); @@ -1955,6 +1953,10 @@ int kernel_execve(const char *kernel_fil int fd = AT_FDCWD; int retval;
+ if (WARN_ON_ONCE((current->flags & PF_KTHREAD) && + (current->worker_private))) + return -EINVAL; + filename = getname_kernel(kernel_filename); if (IS_ERR(filename)) return PTR_ERR(filename); --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -32,6 +32,7 @@ struct kernel_clone_args { size_t set_tid_size; int cgroup; int io_thread; + int kthread; struct cgroup *cgrp; struct css_set *cset; }; @@ -89,6 +90,7 @@ struct task_struct *create_io_thread(int struct task_struct *fork_idle(int); struct mm_struct *copy_init_mm(void); extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); +extern pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags); extern long kernel_wait4(pid_t, int __user *, int, struct rusage *); int kernel_wait(pid_t pid, int *stat);
--- a/init/main.c +++ b/init/main.c @@ -688,7 +688,7 @@ noinline void __ref rest_init(void) * the init task will end up wanting to create kthreads, which, if * we schedule it before we create kthreadd, will OOPS. */ - pid = kernel_thread(kernel_init, NULL, CLONE_FS); + pid = user_mode_thread(kernel_init, NULL, CLONE_FS); /* * Pin init on the boot CPU. Task migration is not properly working * until sched_init_smp() has been run. It will set the allowed --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2157,7 +2157,7 @@ static __latent_entropy struct task_stru p->io_context = NULL; audit_set_context(p, NULL); cgroup_fork(p); - if (p->flags & PF_KTHREAD) { + if (args->kthread) { if (!set_kthread_struct(p)) goto bad_fork_cleanup_delayacct; } @@ -2548,7 +2548,8 @@ struct task_struct * __init fork_idle(in { struct task_struct *task; struct kernel_clone_args args = { - .flags = CLONE_VM, + .flags = CLONE_VM, + .kthread = 1, };
task = copy_process(&init_struct_pid, 0, cpu_to_node(cpu), &args); @@ -2682,6 +2683,23 @@ pid_t kernel_thread(int (*fn)(void *), v { struct kernel_clone_args args = { .flags = ((lower_32_bits(flags) | CLONE_VM | + CLONE_UNTRACED) & ~CSIGNAL), + .exit_signal = (lower_32_bits(flags) & CSIGNAL), + .stack = (unsigned long)fn, + .stack_size = (unsigned long)arg, + .kthread = 1, + }; + + return kernel_clone(&args); +} + +/* + * Create a user mode thread. + */ +pid_t user_mode_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + struct kernel_clone_args args = { + .flags = ((lower_32_bits(flags) | CLONE_VM | CLONE_UNTRACED) & ~CSIGNAL), .exit_signal = (lower_32_bits(flags) & CSIGNAL), .stack = (unsigned long)fn, --- a/kernel/umh.c +++ b/kernel/umh.c @@ -132,7 +132,7 @@ static void call_usermodehelper_exec_syn
/* If SIGCLD is ignored do_wait won't populate the status. */ kernel_sigaction(SIGCHLD, SIG_DFL); - pid = kernel_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD); + pid = user_mode_thread(call_usermodehelper_exec_async, sub_info, SIGCHLD); if (pid < 0) sub_info->retval = pid; else @@ -171,8 +171,8 @@ static void call_usermodehelper_exec_wor * want to pollute current->children, and we need a parent * that always ignores SIGCHLD to ensure auto-reaping. */ - pid = kernel_thread(call_usermodehelper_exec_async, sub_info, - CLONE_PARENT | SIGCHLD); + pid = user_mode_thread(call_usermodehelper_exec_async, sub_info, + CLONE_PARENT | SIGCHLD); if (pid < 0) { sub_info->retval = pid; umh_complete(sub_info);
From: Eric W. Biederman ebiederm@xmission.com
commit c200e4bb44e80b343c09841e7caaaca0aac5e5fa upstream.
User mode linux is the last user of the PT_DTRACE flag. Using the flag to indicate single stepping is a little confusing and worse changing tsk->ptrace without locking could potentionally cause problems.
So use a thread info flag with a better name instead of flag in tsk->ptrace.
Remove the definition PT_DTRACE as uml is the last user.
Cc: stable@vger.kernel.org Acked-by: Johannes Berg johannes@sipsolutions.net Tested-by: Kees Cook keescook@chromium.org Reviewed-by: Oleg Nesterov oleg@redhat.com Link: https://lkml.kernel.org/r/20220505182645.497868-3-ebiederm@xmission.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/include/asm/thread_info.h | 2 ++ arch/um/kernel/exec.c | 2 +- arch/um/kernel/process.c | 2 +- arch/um/kernel/ptrace.c | 8 ++++---- arch/um/kernel/signal.c | 4 ++-- include/linux/ptrace.h | 1 - 6 files changed, 10 insertions(+), 9 deletions(-)
--- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -60,6 +60,7 @@ static inline struct thread_info *curren #define TIF_RESTORE_SIGMASK 7 #define TIF_NOTIFY_RESUME 8 #define TIF_SECCOMP 9 /* secure computing */ +#define TIF_SINGLESTEP 10 /* single stepping userspace */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) @@ -68,5 +69,6 @@ static inline struct thread_info *curren #define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#endif --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -43,7 +43,7 @@ void start_thread(struct pt_regs *regs, { PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; - current->ptrace &= ~PT_DTRACE; + clear_thread_flag(TIF_SINGLESTEP); #ifdef SUBARCH_EXECVE1 SUBARCH_EXECVE1(regs->regs); #endif --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -335,7 +335,7 @@ int singlestepping(void * t) { struct task_struct *task = t ? t : current;
- if (!(task->ptrace & PT_DTRACE)) + if (!test_thread_flag(TIF_SINGLESTEP)) return 0;
if (task->thread.singlestep_syscall) --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -11,7 +11,7 @@
void user_enable_single_step(struct task_struct *child) { - child->ptrace |= PT_DTRACE; + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING @@ -21,7 +21,7 @@ void user_enable_single_step(struct task
void user_disable_single_step(struct task_struct *child) { - child->ptrace &= ~PT_DTRACE; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->thread.singlestep_syscall = 0;
#ifdef SUBARCH_SET_SINGLESTEPPING @@ -120,7 +120,7 @@ static void send_sigtrap(struct uml_pt_r }
/* - * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and + * XXX Check TIF_SINGLESTEP for singlestepping check and * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check */ int syscall_trace_enter(struct pt_regs *regs) @@ -144,7 +144,7 @@ void syscall_trace_leave(struct pt_regs audit_syscall_exit(regs);
/* Fake a debug trap */ - if (ptraced & PT_DTRACE) + if (test_thread_flag(TIF_SINGLESTEP)) send_sigtrap(®s->regs, 0);
if (!test_thread_flag(TIF_SYSCALL_TRACE)) --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -53,7 +53,7 @@ static void handle_signal(struct ksignal unsigned long sp; int err;
- if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) + if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED)) singlestep = 1;
/* Did we come from a system call? */ @@ -128,7 +128,7 @@ void do_signal(struct pt_regs *regs) * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ - if (current->ptrace & PT_DTRACE) + if (test_thread_flag(TIF_SINGLESTEP)) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs));
--- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -30,7 +30,6 @@ extern int ptrace_access_vm(struct task_
#define PT_SEIZED 0x00010000 /* SEIZE used, enable new behavior */ #define PT_PTRACED 0x00000001 -#define PT_DTRACE 0x00000002 /* delayed trace (used on m68k, i386) */
#define PT_OPT_FLAG_SHIFT 3 /* PT_TRACE_* event enable flags */
From: Eric W. Biederman ebiederm@xmission.com
commit 4a3d2717d140401df7501a95e454180831a0c5af upstream.
xtensa is the last user of the PT_SINGLESTEP flag. Changing tsk->ptrace in user_enable_single_step and user_disable_single_step without locking could potentiallly cause problems.
So use a thread info flag instead of a flag in tsk->ptrace. Use TIF_SINGLESTEP that xtensa already had defined but unused.
Remove the definitions of PT_SINGLESTEP and PT_BLOCKSTEP as they have no more users.
Cc: stable@vger.kernel.org Acked-by: Max Filippov jcmvbkbc@gmail.com Tested-by: Kees Cook keescook@chromium.org Reviewed-by: Oleg Nesterov oleg@redhat.com Link: https://lkml.kernel.org/r/20220505182645.497868-4-ebiederm@xmission.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/xtensa/kernel/ptrace.c | 4 ++-- arch/xtensa/kernel/signal.c | 4 ++-- include/linux/ptrace.h | 6 ------ 3 files changed, 4 insertions(+), 10 deletions(-)
--- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -225,12 +225,12 @@ const struct user_regset_view *task_user
void user_enable_single_step(struct task_struct *child) { - child->ptrace |= PT_SINGLESTEP; + set_tsk_thread_flag(child, TIF_SINGLESTEP); }
void user_disable_single_step(struct task_struct *child) { - child->ptrace &= ~PT_SINGLESTEP; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); }
/* --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -473,7 +473,7 @@ static void do_signal(struct pt_regs *re /* Set up the stack frame */ ret = setup_frame(&ksig, sigmask_to_save(), regs); signal_setup_done(ret, &ksig, 0); - if (current->ptrace & PT_SINGLESTEP) + if (test_thread_flag(TIF_SINGLESTEP)) task_pt_regs(current)->icountlevel = 1;
return; @@ -499,7 +499,7 @@ static void do_signal(struct pt_regs *re /* If there's no signal to deliver, we just restore the saved mask. */ restore_saved_sigmask();
- if (current->ptrace & PT_SINGLESTEP) + if (test_thread_flag(TIF_SINGLESTEP)) task_pt_regs(current)->icountlevel = 1; return; } --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -46,12 +46,6 @@ extern int ptrace_access_vm(struct task_ #define PT_EXITKILL (PTRACE_O_EXITKILL << PT_OPT_FLAG_SHIFT) #define PT_SUSPEND_SECCOMP (PTRACE_O_SUSPEND_SECCOMP << PT_OPT_FLAG_SHIFT)
-/* single stepping state bits (used on ARM and PA-RISC) */ -#define PT_SINGLESTEP_BIT 31 -#define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) -#define PT_BLOCKSTEP_BIT 30 -#define PT_BLOCKSTEP (1<<PT_BLOCKSTEP_BIT) - extern long arch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data); extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
From: Eric W. Biederman ebiederm@xmission.com
commit 6a2d90ba027adba528509ffa27097cffd3879257 upstream.
The current implementation of PTRACE_KILL is buggy and has been for many years as it assumes it's target has stopped in ptrace_stop. At a quick skim it looks like this assumption has existed since ptrace support was added in linux v1.0.
While PTRACE_KILL has been deprecated we can not remove it as a quick search with google code search reveals many existing programs calling it.
When the ptracee is not stopped at ptrace_stop some fields would be set that are ignored except in ptrace_stop. Making the userspace visible behavior of PTRACE_KILL a noop in those case.
As the usual rules are not obeyed it is not clear what the consequences are of calling PTRACE_KILL on a running process. Presumably userspace does not do this as it achieves nothing.
Replace the implementation of PTRACE_KILL with a simple send_sig_info(SIGKILL) followed by a return 0. This changes the observable user space behavior only in that PTRACE_KILL on a process not stopped in ptrace_stop will also kill it. As that has always been the intent of the code this seems like a reasonable change.
Cc: stable@vger.kernel.org Reported-by: Al Viro viro@zeniv.linux.org.uk Suggested-by: Al Viro viro@zeniv.linux.org.uk Tested-by: Kees Cook keescook@chromium.org Reviewed-by: Oleg Nesterov oleg@redhat.com Link: https://lkml.kernel.org/r/20220505182645.497868-7-ebiederm@xmission.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/step.c | 3 +-- kernel/ptrace.c | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-)
--- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -180,8 +180,7 @@ void set_task_blockstep(struct task_stru * * NOTE: this means that set/clear TIF_BLOCKSTEP is only safe if * task is current or it can't be running, otherwise we can race - * with __switch_to_xtra(). We rely on ptrace_freeze_traced() but - * PTRACE_KILL is not safe. + * with __switch_to_xtra(). We rely on ptrace_freeze_traced(). */ local_irq_disable(); debugctl = get_debugctlmsr(); --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -1236,9 +1236,8 @@ int ptrace_request(struct task_struct *c return ptrace_resume(child, request, data);
case PTRACE_KILL: - if (child->exit_state) /* already dead */ - return 0; - return ptrace_resume(child, request, SIGKILL); + send_sig_info(SIGKILL, SEND_SIG_NOINFO, child); + return 0;
#ifdef CONFIG_HAVE_ARCH_TRACEHOOK case PTRACE_GETREGSET:
From: Qu Wenruo wqu@suse.com
commit d5321a0fa8bc49f11bea0b470800962c17d92d8f upstream.
The following error message lack the "0x" obviously:
cannot mount because of unsupported optional features (4000)
Add the prefix to make it less confusing. This can happen on older kernels that try to mount a filesystem with newer features so it makes sense to backport to older trees.
CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Qu Wenruo wqu@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/disk-io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3611,7 +3611,7 @@ int __cold open_ctree(struct super_block ~BTRFS_FEATURE_INCOMPAT_SUPP; if (features) { btrfs_err(fs_info, - "cannot mount because of unsupported optional features (%llx)", + "cannot mount because of unsupported optional features (0x%llx)", features); err = -EINVAL; goto fail_alloc; @@ -3649,7 +3649,7 @@ int __cold open_ctree(struct super_block ~BTRFS_FEATURE_COMPAT_RO_SUPP; if (!sb_rdonly(sb) && features) { btrfs_err(fs_info, - "cannot mount read-write because of unsupported optional features (%llx)", + "cannot mount read-write because of unsupported optional features (0x%llx)", features); err = -EINVAL; goto fail_alloc;
From: Qu Wenruo wqu@suse.com
commit 44e5801fada6925d2bba1987c7b59cbcc9d0d592 upstream.
[BUG] If we hit an error from submit_extent_page() inside __extent_writepage_io(), we could still return 0 to the caller, and even trigger the warning in btrfs_page_assert_not_dirty().
[CAUSE] In __extent_writepage_io(), if we hit an error from submit_extent_page(), we will just clean up the range and continue.
This is completely fine for regular PAGE_SIZE == sectorsize, as we can only hit one sector in one page, thus after the error we're ensured to exit and @ret will be saved.
But for subpage case, we may have other dirty subpage range in the page, and in the next loop, we may succeeded submitting the next range.
In that case, @ret will be overwritten, and we return 0 to the caller, while we have hit some error.
[FIX] Introduce @has_error and @saved_ret to record the first error we hit, so we will never forget what error we hit.
CC: stable@vger.kernel.org # 5.15+ Signed-off-by: Qu Wenruo wqu@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/extent_io.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
--- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3920,10 +3920,12 @@ static noinline_for_stack int __extent_w u64 extent_offset; u64 block_start; struct extent_map *em; + int saved_ret = 0; int ret = 0; int nr = 0; u32 opf = REQ_OP_WRITE; const unsigned int write_flags = wbc_to_write_flags(wbc); + bool has_error = false; bool compressed;
ret = btrfs_writepage_cow_fixup(page); @@ -3973,6 +3975,9 @@ static noinline_for_stack int __extent_w if (IS_ERR(em)) { btrfs_page_set_error(fs_info, page, cur, end - cur + 1); ret = PTR_ERR_OR_ZERO(em); + has_error = true; + if (!saved_ret) + saved_ret = ret; break; }
@@ -4036,6 +4041,10 @@ static noinline_for_stack int __extent_w end_bio_extent_writepage, 0, 0, false); if (ret) { + has_error = true; + if (!saved_ret) + saved_ret = ret; + btrfs_page_set_error(fs_info, page, cur, iosize); if (PageWriteback(page)) btrfs_page_clear_writeback(fs_info, page, cur, @@ -4049,8 +4058,10 @@ static noinline_for_stack int __extent_w * If we finish without problem, we should not only clear page dirty, * but also empty subpage dirty bits */ - if (!ret) + if (!has_error) btrfs_page_assert_not_dirty(fs_info, page); + else + ret = saved_ret; *nr_ret = nr; return ret; }
From: Qu Wenruo wqu@suse.com
commit d201238ccd2f30b9bfcfadaeae0972e3a486a176 upstream.
[BUG] There is a report that a btrfs has a bad super block num devices.
This makes btrfs to reject the fs completely.
BTRFS error (device sdd3): super_num_devices 3 mismatch with num_devices 2 found here BTRFS error (device sdd3): failed to read chunk tree: -22 BTRFS error (device sdd3): open_ctree failed
[CAUSE] During btrfs device removal, chunk tree and super block num devs are updated in two different transactions:
btrfs_rm_device() |- btrfs_rm_dev_item(device) | |- trans = btrfs_start_transaction() | | Now we got transaction X | | | |- btrfs_del_item() | | Now device item is removed from chunk tree | | | |- btrfs_commit_transaction() | Transaction X got committed, super num devs untouched, | but device item removed from chunk tree. | (AKA, super num devs is already incorrect) | |- cur_devices->num_devices--; |- cur_devices->total_devices--; |- btrfs_set_super_num_devices() All those operations are not in transaction X, thus it will only be written back to disk in next transaction.
So after the transaction X in btrfs_rm_dev_item() committed, but before transaction X+1 (which can be minutes away), a power loss happen, then we got the super num mismatch.
This has been fixed by commit bbac58698a55 ("btrfs: remove device item and update super block in the same transaction").
[FIX] Make the super_num_devices check less strict, converting it from a hard error to a warning, and reset the value to a correct one for the current or next transaction commit.
As the number of device items is the critical information where the super block num_devices is only a cached value (and also useful for cross checking), it's safe to automatically update it. Other device related problems like missing device are handled after that and may require other means to resolve, like degraded mount. With this fix, potentially affected filesystems won't fail mount and require the manual repair by btrfs check.
Reported-by: Luca Béla Palkovics luca.bela.palkovics@gmail.com Link: https://lore.kernel.org/linux-btrfs/CA+8xDSpvdm_U0QLBAnrH=zqDq_cWCOH5TiV46CK... CC: stable@vger.kernel.org # 4.14+ 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/volumes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -7671,12 +7671,12 @@ int btrfs_read_chunk_tree(struct btrfs_f * do another round of validation checks. */ if (total_dev != fs_info->fs_devices->total_devices) { - btrfs_err(fs_info, - "super_num_devices %llu mismatch with num_devices %llu found here", + btrfs_warn(fs_info, +"super block num_devices %llu mismatch with DEV_ITEM count %llu, will be repaired on next transaction commit", btrfs_super_num_devices(fs_info->super_copy), total_dev); - ret = -EINVAL; - goto error; + fs_info->fs_devices->total_devices = total_dev; + btrfs_set_super_num_devices(fs_info->super_copy, total_dev); } if (btrfs_super_total_bytes(fs_info->super_copy) < fs_info->fs_devices->total_rw_bytes) {
From: Qu Wenruo wqu@suse.com
commit 10f7f6f879c28f8368d6516ab1ccf3517a1f5d3d upstream.
[BUG] Test case generic/475 have a very high chance (almost 100%) to hit a fs hang, where a data page will never be unlocked and hang all later operations.
[CAUSE] In btrfs_do_readpage(), if we hit an error from submit_extent_page() we will try to do the cleanup for our current io range, and exit.
This works fine for PAGE_SIZE == sectorsize cases, but not for subpage.
For subpage btrfs_do_readpage() will lock the full page first, which can contain several different sectors and extents:
btrfs_do_readpage() |- begin_page_read() | |- btrfs_subpage_start_reader(); | Now the page will have PAGE_SIZE / sectorsize reader pending, | and the page is locked. | |- end_page_read() for different branches | This function will reduce subpage readers, and when readers | reach 0, it will unlock the page.
But when submit_extent_page() failed, we only cleanup the current io range, while the remaining io range will never be cleaned up, and the page remains locked forever.
[FIX] Update the error handling of submit_extent_page() to cleanup all the remaining subpage range before exiting the loop.
Please note that, now submit_extent_page() can only fail due to sanity check in alloc_new_bio().
Thus regular IO errors are impossible to trigger the error path.
CC: stable@vger.kernel.org # 5.15+ Signed-off-by: Qu Wenruo wqu@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/extent_io.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3743,8 +3743,12 @@ int btrfs_do_readpage(struct page *page, this_bio_flag, force_bio_submit); if (ret) { - unlock_extent(tree, cur, cur + iosize - 1); - end_page_read(page, false, cur, iosize); + /* + * We have to unlock the remaining range, or the page + * will never be unlocked. + */ + unlock_extent(tree, cur, end); + end_page_read(page, false, cur, end + 1 - cur); goto out; } cur = cur + iosize;
From: Filipe Manana fdmanana@suse.com
commit f5585f4f0ef5b17026bbd60fbff6fcc91b99d5bf upstream.
When reserving data space for a direct IO write we can end up deadlocking if we have multiple tasks attempting a write to the same file range, there are multiple extents covered by that file range, we are low on available space for data and the writes don't expand the inode's i_size.
The deadlock can happen like this:
1) We have a file with an i_size of 1M, at offset 0 it has an extent with a size of 128K and at offset 128K it has another extent also with a size of 128K;
2) Task A does a direct IO write against file range [0, 256K), and because the write is within the i_size boundary, it takes the inode's lock (VFS level) in shared mode;
3) Task A locks the file range [0, 256K) at btrfs_dio_iomap_begin(), and then gets the extent map for the extent covering the range [0, 128K). At btrfs_get_blocks_direct_write(), it creates an ordered extent for that file range ([0, 128K));
4) Before returning from btrfs_dio_iomap_begin(), it unlocks the file range [0, 256K);
5) Task A executes btrfs_dio_iomap_begin() again, this time for the file range [128K, 256K), and locks the file range [128K, 256K);
6) Task B starts a direct IO write against file range [0, 256K) as well. It also locks the inode in shared mode, as it's within the i_size limit, and then tries to lock file range [0, 256K). It is able to lock the subrange [0, 128K) but then blocks waiting for the range [128K, 256K), as it is currently locked by task A;
7) Task A enters btrfs_get_blocks_direct_write() and tries to reserve data space. Because we are low on available free space, it triggers the async data reclaim task, and waits for it to reserve data space;
8) The async reclaim task decides to wait for all existing ordered extents to complete (through btrfs_wait_ordered_roots()). It finds the ordered extent previously created by task A for the file range [0, 128K) and waits for it to complete;
9) The ordered extent for the file range [0, 128K) can not complete because it blocks at btrfs_finish_ordered_io() when trying to lock the file range [0, 128K).
This results in a deadlock, because:
- task B is holding the file range [0, 128K) locked, waiting for the range [128K, 256K) to be unlocked by task A;
- task A is holding the file range [128K, 256K) locked and it's waiting for the async data reclaim task to satisfy its space reservation request;
- the async data reclaim task is waiting for ordered extent [0, 128K) to complete, but the ordered extent can not complete because the file range [0, 128K) is currently locked by task B, which is waiting on task A to unlock file range [128K, 256K) and task A waiting on the async data reclaim task.
This results in a deadlock between 4 task: task A, task B, the async data reclaim task and the task doing ordered extent completion (a work queue task).
This type of deadlock can sporadically be triggered by the test case generic/300 from fstests, and results in a stack trace like the following:
[12084.033689] INFO: task kworker/u16:7:123749 blocked for more than 241 seconds. [12084.034877] Not tainted 5.18.0-rc2-btrfs-next-115 #1 [12084.035562] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [12084.036548] task:kworker/u16:7 state:D stack: 0 pid:123749 ppid: 2 flags:0x00004000 [12084.036554] Workqueue: btrfs-flush_delalloc btrfs_work_helper [btrfs] [12084.036599] Call Trace: [12084.036601] <TASK> [12084.036606] __schedule+0x3cb/0xed0 [12084.036616] schedule+0x4e/0xb0 [12084.036620] btrfs_start_ordered_extent+0x109/0x1c0 [btrfs] [12084.036651] ? prepare_to_wait_exclusive+0xc0/0xc0 [12084.036659] btrfs_run_ordered_extent_work+0x1a/0x30 [btrfs] [12084.036688] btrfs_work_helper+0xf8/0x400 [btrfs] [12084.036719] ? lock_is_held_type+0xe8/0x140 [12084.036727] process_one_work+0x252/0x5a0 [12084.036736] ? process_one_work+0x5a0/0x5a0 [12084.036738] worker_thread+0x52/0x3b0 [12084.036743] ? process_one_work+0x5a0/0x5a0 [12084.036745] kthread+0xf2/0x120 [12084.036747] ? kthread_complete_and_exit+0x20/0x20 [12084.036751] ret_from_fork+0x22/0x30 [12084.036765] </TASK> [12084.036769] INFO: task kworker/u16:11:153787 blocked for more than 241 seconds. [12084.037702] Not tainted 5.18.0-rc2-btrfs-next-115 #1 [12084.038540] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [12084.039506] task:kworker/u16:11 state:D stack: 0 pid:153787 ppid: 2 flags:0x00004000 [12084.039511] Workqueue: events_unbound btrfs_async_reclaim_data_space [btrfs] [12084.039551] Call Trace: [12084.039553] <TASK> [12084.039557] __schedule+0x3cb/0xed0 [12084.039566] schedule+0x4e/0xb0 [12084.039569] schedule_timeout+0xed/0x130 [12084.039573] ? mark_held_locks+0x50/0x80 [12084.039578] ? _raw_spin_unlock_irq+0x24/0x50 [12084.039580] ? lockdep_hardirqs_on+0x7d/0x100 [12084.039585] __wait_for_common+0xaf/0x1f0 [12084.039587] ? usleep_range_state+0xb0/0xb0 [12084.039596] btrfs_wait_ordered_extents+0x3d6/0x470 [btrfs] [12084.039636] btrfs_wait_ordered_roots+0x175/0x240 [btrfs] [12084.039670] flush_space+0x25b/0x630 [btrfs] [12084.039712] btrfs_async_reclaim_data_space+0x108/0x1b0 [btrfs] [12084.039747] process_one_work+0x252/0x5a0 [12084.039756] ? process_one_work+0x5a0/0x5a0 [12084.039758] worker_thread+0x52/0x3b0 [12084.039762] ? process_one_work+0x5a0/0x5a0 [12084.039765] kthread+0xf2/0x120 [12084.039766] ? kthread_complete_and_exit+0x20/0x20 [12084.039770] ret_from_fork+0x22/0x30 [12084.039783] </TASK> [12084.039800] INFO: task kworker/u16:17:217907 blocked for more than 241 seconds. [12084.040709] Not tainted 5.18.0-rc2-btrfs-next-115 #1 [12084.041398] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [12084.042404] task:kworker/u16:17 state:D stack: 0 pid:217907 ppid: 2 flags:0x00004000 [12084.042411] Workqueue: btrfs-endio-write btrfs_work_helper [btrfs] [12084.042461] Call Trace: [12084.042463] <TASK> [12084.042471] __schedule+0x3cb/0xed0 [12084.042485] schedule+0x4e/0xb0 [12084.042490] wait_extent_bit.constprop.0+0x1eb/0x260 [btrfs] [12084.042539] ? prepare_to_wait_exclusive+0xc0/0xc0 [12084.042551] lock_extent_bits+0x37/0x90 [btrfs] [12084.042601] btrfs_finish_ordered_io.isra.0+0x3fd/0x960 [btrfs] [12084.042656] ? lock_is_held_type+0xe8/0x140 [12084.042667] btrfs_work_helper+0xf8/0x400 [btrfs] [12084.042716] ? lock_is_held_type+0xe8/0x140 [12084.042727] process_one_work+0x252/0x5a0 [12084.042742] worker_thread+0x52/0x3b0 [12084.042750] ? process_one_work+0x5a0/0x5a0 [12084.042754] kthread+0xf2/0x120 [12084.042757] ? kthread_complete_and_exit+0x20/0x20 [12084.042763] ret_from_fork+0x22/0x30 [12084.042783] </TASK> [12084.042798] INFO: task fio:234517 blocked for more than 241 seconds. [12084.043598] Not tainted 5.18.0-rc2-btrfs-next-115 #1 [12084.044282] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [12084.045244] task:fio state:D stack: 0 pid:234517 ppid:234515 flags:0x00004000 [12084.045248] Call Trace: [12084.045250] <TASK> [12084.045254] __schedule+0x3cb/0xed0 [12084.045263] schedule+0x4e/0xb0 [12084.045266] wait_extent_bit.constprop.0+0x1eb/0x260 [btrfs] [12084.045298] ? prepare_to_wait_exclusive+0xc0/0xc0 [12084.045306] lock_extent_bits+0x37/0x90 [btrfs] [12084.045336] btrfs_dio_iomap_begin+0x336/0xc60 [btrfs] [12084.045370] ? lock_is_held_type+0xe8/0x140 [12084.045378] iomap_iter+0x184/0x4c0 [12084.045383] __iomap_dio_rw+0x2c6/0x8a0 [12084.045406] iomap_dio_rw+0xa/0x30 [12084.045408] btrfs_do_write_iter+0x370/0x5e0 [btrfs] [12084.045440] aio_write+0xfa/0x2c0 [12084.045448] ? __might_fault+0x2a/0x70 [12084.045451] ? kvm_sched_clock_read+0x14/0x40 [12084.045455] ? lock_release+0x153/0x4a0 [12084.045463] io_submit_one+0x615/0x9f0 [12084.045467] ? __might_fault+0x2a/0x70 [12084.045469] ? kvm_sched_clock_read+0x14/0x40 [12084.045478] __x64_sys_io_submit+0x83/0x160 [12084.045483] ? syscall_enter_from_user_mode+0x1d/0x50 [12084.045489] do_syscall_64+0x3b/0x90 [12084.045517] entry_SYSCALL_64_after_hwframe+0x44/0xae [12084.045521] RIP: 0033:0x7fa76511af79 [12084.045525] RSP: 002b:00007ffd6d6b9058 EFLAGS: 00000246 ORIG_RAX: 00000000000000d1 [12084.045530] RAX: ffffffffffffffda RBX: 00007fa75ba6e760 RCX: 00007fa76511af79 [12084.045532] RDX: 0000557b304ff3f0 RSI: 0000000000000001 RDI: 00007fa75ba4c000 [12084.045535] RBP: 00007fa75ba4c000 R08: 00007fa751b76000 R09: 0000000000000330 [12084.045537] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 [12084.045540] R13: 0000000000000000 R14: 0000557b304ff3f0 R15: 0000557b30521eb0 [12084.045561] </TASK>
Fix this issue by always reserving data space before locking a file range at btrfs_dio_iomap_begin(). If we can't reserve the space, then we don't error out immediately - instead after locking the file range, check if we can do a NOCOW write, and if we can we don't error out since we don't need to allocate a data extent, however if we can't NOCOW then error out with -ENOSPC. This also implies that we may end up reserving space when it's not needed because the write will end up being done in NOCOW mode - in that case we just release the space after we noticed we did a NOCOW write - this is the same type of logic that is done in the path for buffered IO writes.
Fixes: f0bfa76a11e93d ("btrfs: fix ENOSPC failure when attempting direct IO write into NOCOW range") CC: stable@vger.kernel.org # 5.17+ Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/inode.c | 81 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 17 deletions(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -64,6 +64,8 @@ struct btrfs_iget_args { struct btrfs_dio_data { ssize_t submitted; struct extent_changeset *data_reserved; + bool data_space_reserved; + bool nocow_done; };
struct btrfs_rename_ctx { @@ -7489,15 +7491,25 @@ static int btrfs_get_blocks_direct_write ret = PTR_ERR(em2); goto out; } + + dio_data->nocow_done = true; } else { /* Our caller expects us to free the input extent map. */ free_extent_map(em); *map = NULL;
- /* We have to COW, so need to reserve metadata and data space. */ - ret = btrfs_delalloc_reserve_space(BTRFS_I(inode), - &dio_data->data_reserved, - start, len); + /* + * If we could not allocate data space before locking the file + * range and we can't do a NOCOW write, then we have to fail. + */ + if (!dio_data->data_space_reserved) + return -ENOSPC; + + /* + * We have to COW and we have already reserved data space before, + * so now we reserve only metadata. + */ + ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len); if (ret < 0) goto out; space_reserved = true; @@ -7510,10 +7522,8 @@ static int btrfs_get_blocks_direct_write *map = em; len = min(len, em->len - (start - em->start)); if (len < prev_len) - btrfs_delalloc_release_space(BTRFS_I(inode), - dio_data->data_reserved, - start + len, prev_len - len, - true); + btrfs_delalloc_release_metadata(BTRFS_I(inode), + prev_len - len, true); }
/* @@ -7531,15 +7541,7 @@ static int btrfs_get_blocks_direct_write out: if (ret && space_reserved) { btrfs_delalloc_release_extents(BTRFS_I(inode), len); - if (can_nocow) { - btrfs_delalloc_release_metadata(BTRFS_I(inode), len, true); - } else { - btrfs_delalloc_release_space(BTRFS_I(inode), - dio_data->data_reserved, - start, len, true); - extent_changeset_free(dio_data->data_reserved); - dio_data->data_reserved = NULL; - } + btrfs_delalloc_release_metadata(BTRFS_I(inode), len, true); } return ret; } @@ -7556,6 +7558,7 @@ static int btrfs_dio_iomap_begin(struct const bool write = !!(flags & IOMAP_WRITE); int ret = 0; u64 len = length; + const u64 data_alloc_len = length; bool unlock_extents = false;
if (!write) @@ -7584,6 +7587,25 @@ static int btrfs_dio_iomap_begin(struct
iomap->private = dio_data;
+ /* + * We always try to allocate data space and must do it before locking + * the file range, to avoid deadlocks with concurrent writes to the same + * range if the range has several extents and the writes don't expand the + * current i_size (the inode lock is taken in shared mode). If we fail to + * allocate data space here we continue and later, after locking the + * file range, we fail with ENOSPC only if we figure out we can not do a + * NOCOW write. + */ + if (write && !(flags & IOMAP_NOWAIT)) { + ret = btrfs_check_data_free_space(BTRFS_I(inode), + &dio_data->data_reserved, + start, data_alloc_len); + if (!ret) + dio_data->data_space_reserved = true; + else if (ret && !(BTRFS_I(inode)->flags & + (BTRFS_INODE_NODATACOW | BTRFS_INODE_PREALLOC))) + goto err; + }
/* * If this errors out it's because we couldn't invalidate pagecache for @@ -7658,6 +7680,24 @@ static int btrfs_dio_iomap_begin(struct unlock_extents = true; /* Recalc len in case the new em is smaller than requested */ len = min(len, em->len - (start - em->start)); + if (dio_data->data_space_reserved) { + u64 release_offset; + u64 release_len = 0; + + if (dio_data->nocow_done) { + release_offset = start; + release_len = data_alloc_len; + } else if (len < data_alloc_len) { + release_offset = start + len; + release_len = data_alloc_len - len; + } + + if (release_len > 0) + btrfs_free_reserved_data_space(BTRFS_I(inode), + dio_data->data_reserved, + release_offset, + release_len); + } } else { /* * We need to unlock only the end area that we aren't using. @@ -7702,6 +7742,13 @@ unlock_err: unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend, &cached_state); err: + if (dio_data->data_space_reserved) { + btrfs_free_reserved_data_space(BTRFS_I(inode), + dio_data->data_reserved, + start, data_alloc_len); + extent_changeset_free(dio_data->data_reserved); + } + kfree(dio_data);
return ret;
From: Naohiro Aota naohiro.aota@wdc.com
commit 56fbb0a4e8b3e929e41cc846e6ef89eb01152201 upstream.
Commit be1a1d7a5d24 ("btrfs: zoned: finish fully written block group") introduced zone finishing code both for data and metadata end_io path. However, the metadata side is not working as it should. First, it compares logical address (eb->start + eb->len) with offset within a block group (cache->zone_capacity) in submit_eb_page(). That essentially disabled zone finishing on metadata end_io path.
Furthermore, fixing the issue above revealed we cannot call btrfs_zone_finish_endio() in end_extent_buffer_writeback(). We cannot call btrfs_lookup_block_group() which require spin lock inside end_io context.
Introduce btrfs_schedule_zone_finish_bg() to wait for the extent buffer writeback and do the zone finish IO in a workqueue.
Also, drop EXTENT_BUFFER_ZONE_FINISH as it is no longer used.
Fixes: be1a1d7a5d24 ("btrfs: zoned: finish fully written block group") CC: stable@vger.kernel.org # 5.16+ Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.h | 2 ++ fs/btrfs/extent_io.c | 6 +----- fs/btrfs/extent_io.h | 1 - fs/btrfs/zoned.c | 31 +++++++++++++++++++++++++++++++ fs/btrfs/zoned.h | 5 +++++ 5 files changed, 39 insertions(+), 6 deletions(-)
--- a/fs/btrfs/block-group.h +++ b/fs/btrfs/block-group.h @@ -212,6 +212,8 @@ struct btrfs_block_group { u64 meta_write_pointer; struct map_lookup *physical_map; struct list_head active_bg_list; + struct work_struct zone_finish_work; + struct extent_buffer *last_eb; };
static inline u64 btrfs_block_group_end(struct btrfs_block_group *block_group) --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4196,9 +4196,6 @@ void wait_on_extent_buffer_writeback(str
static void end_extent_buffer_writeback(struct extent_buffer *eb) { - if (test_bit(EXTENT_BUFFER_ZONE_FINISH, &eb->bflags)) - btrfs_zone_finish_endio(eb->fs_info, eb->start, eb->len); - clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); smp_mb__after_atomic(); wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK); @@ -4818,8 +4815,7 @@ static int submit_eb_page(struct page *p /* * Implies write in zoned mode. Mark the last eb in a block group. */ - if (cache->seq_zone && eb->start + eb->len == cache->zone_capacity) - set_bit(EXTENT_BUFFER_ZONE_FINISH, &eb->bflags); + btrfs_schedule_zone_finish_bg(cache, eb); btrfs_put_block_group(cache); } ret = write_one_eb(eb, wbc, epd); --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -32,7 +32,6 @@ enum { /* write IO error */ EXTENT_BUFFER_WRITE_ERR, EXTENT_BUFFER_NO_CHECK, - EXTENT_BUFFER_ZONE_FINISH, };
/* these are flags for __process_pages_contig */ --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -2046,6 +2046,37 @@ out: btrfs_put_block_group(block_group); }
+static void btrfs_zone_finish_endio_workfn(struct work_struct *work) +{ + struct btrfs_block_group *bg = + container_of(work, struct btrfs_block_group, zone_finish_work); + + wait_on_extent_buffer_writeback(bg->last_eb); + free_extent_buffer(bg->last_eb); + btrfs_zone_finish_endio(bg->fs_info, bg->start, bg->length); + btrfs_put_block_group(bg); +} + +void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg, + struct extent_buffer *eb) +{ + if (!bg->seq_zone || eb->start + eb->len * 2 <= bg->start + bg->zone_capacity) + return; + + if (WARN_ON(bg->zone_finish_work.func == btrfs_zone_finish_endio_workfn)) { + btrfs_err(bg->fs_info, "double scheduling of bg %llu zone finishing", + bg->start); + return; + } + + /* For the work */ + btrfs_get_block_group(bg); + atomic_inc(&eb->refs); + bg->last_eb = eb; + INIT_WORK(&bg->zone_finish_work, btrfs_zone_finish_endio_workfn); + queue_work(system_unbound_wq, &bg->zone_finish_work); +} + void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg) { struct btrfs_fs_info *fs_info = bg->fs_info; --- a/fs/btrfs/zoned.h +++ b/fs/btrfs/zoned.h @@ -76,6 +76,8 @@ int btrfs_zone_finish(struct btrfs_block bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags); void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 length); +void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg, + struct extent_buffer *eb); void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg); void btrfs_free_zone_cache(struct btrfs_fs_info *fs_info); #else /* CONFIG_BLK_DEV_ZONED */ @@ -233,6 +235,9 @@ static inline bool btrfs_can_activate_zo static inline void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 length) { }
+static inline void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg, + struct extent_buffer *eb) { } + static inline void btrfs_clear_data_reloc_bg(struct btrfs_block_group *bg) { }
static inline void btrfs_free_zone_cache(struct btrfs_fs_info *fs_info) { }
From: Naohiro Aota naohiro.aota@wdc.com
commit 74e91b12b11560f01d120751d99d91d54b265d3d upstream.
While the active zones within an active block group are reset, and their active resource is released, the block group itself is kept in the active block group list and marked as active. As a result, the list will contain more than max_active_zones block groups. That itself is not fatal for the device as the zones are properly reset.
However, that inflated list is, of course, strange. Also, a to-appear patch series, which deactivates an active block group on demand, gets confused with the wrong list.
So, fix the issue by finishing the unused block group once it gets read-only, so that we can release the active resource in an early stage.
Fixes: be1a1d7a5d24 ("btrfs: zoned: finish fully written block group") CC: stable@vger.kernel.org # 5.16+ Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/block-group.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -1367,6 +1367,14 @@ void btrfs_delete_unused_bgs(struct btrf goto next; }
+ ret = btrfs_zone_finish(block_group); + if (ret < 0) { + btrfs_dec_block_group_ro(block_group); + if (ret == -EAGAIN) + ret = 0; + goto next; + } + /* * Want to do this before we do anything else so we can recover * properly if we fail to join the transaction.
From: Naohiro Aota naohiro.aota@wdc.com
commit 8b8a53998caefebfe5c8da7a74c2b601caf5dd48 upstream.
Currently, btrfs_zone_finish_endio() finishes a block group only when the written region reaches the end of the block group. We can also finish the block group when no more allocation is possible.
Fixes: be1a1d7a5d24 ("btrfs: zoned: finish fully written block group") CC: stable@vger.kernel.org # 5.16+ Reviewed-by: Pankaj Raghav p.raghav@samsung.com Reviewed-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/zoned.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -2000,6 +2000,7 @@ void btrfs_zone_finish_endio(struct btrf struct btrfs_block_group *block_group; struct map_lookup *map; struct btrfs_device *device; + u64 min_alloc_bytes; u64 physical;
if (!btrfs_is_zoned(fs_info)) @@ -2008,7 +2009,15 @@ void btrfs_zone_finish_endio(struct btrf block_group = btrfs_lookup_block_group(fs_info, logical); ASSERT(block_group);
- if (logical + length < block_group->start + block_group->zone_capacity) + /* No MIXED_BG on zoned btrfs. */ + if (block_group->flags & BTRFS_BLOCK_GROUP_DATA) + min_alloc_bytes = fs_info->sectorsize; + else + min_alloc_bytes = fs_info->nodesize; + + /* Bail out if we can allocate more data from this block group. */ + if (logical + length + min_alloc_bytes <= + block_group->start + block_group->zone_capacity) goto out;
spin_lock(&block_group->lock);
From: Naohiro Aota naohiro.aota@wdc.com
commit aa9ffadfcae33e611d8c2d476bcc2aa0d273b587 upstream.
The block_group->alloc_offset is an offset from the start of the block group. OTOH, the ->meta_write_pointer is an address in the logical space. So, we should compare the alloc_offset shifted with the block_group->start.
Fixes: afba2bc036b0 ("btrfs: zoned: implement active zone tracking") CC: stable@vger.kernel.org # 5.16+ Signed-off-by: Naohiro Aota naohiro.aota@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/zoned.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -1896,7 +1896,7 @@ int btrfs_zone_finish(struct btrfs_block /* Check if we have unwritten allocated space */ if ((block_group->flags & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM)) && - block_group->alloc_offset > block_group->meta_write_pointer) { + block_group->start + block_group->alloc_offset > block_group->meta_write_pointer) { spin_unlock(&block_group->lock); return -EAGAIN; }
From: Tejas Upadhyay tejaskumarx.surendrakumar.upadhyay@intel.com
[ Upstream commit 0a967f5bfd9134b89681cae58deb222e20840e76 ]
The VT-d spec requires (10.4.4 Global Command Register, TE field) that:
Hardware implementations supporting DMA draining must drain any in-flight DMA read/write requests queued within the Root-Complex before completing the translation enable command and reflecting the status of the command through the TES field in the Global Status register.
Unfortunately, some integrated graphic devices fail to do so after some kind of power state transition. As the result, the system might stuck in iommu_disable_translati on(), waiting for the completion of TE transition.
This adds RPLS to a quirk list for those devices and skips TE disabling if the qurik hits.
Link: https://gitlab.freedesktop.org/drm/intel/-/issues/4898 Tested-by: Raviteja Goud Talla ravitejax.goud.talla@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Acked-by: Lu Baolu baolu.lu@linux.intel.com Signed-off-by: Tejas Upadhyay tejaskumarx.surendrakumar.upadhyay@intel.com Reviewed-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20220302043256.191529-1-tejask... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/intel/iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 0ea47e17b379..ba9a63cac47c 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -5031,7 +5031,7 @@ static void quirk_igfx_skip_te_disable(struct pci_dev *dev) ver = (dev->device >> 8) & 0xff; if (ver != 0x45 && ver != 0x46 && ver != 0x4c && ver != 0x4e && ver != 0x8a && ver != 0x98 && - ver != 0x9a) + ver != 0x9a && ver != 0xa7) return;
if (risky_device(dev))
From: Arunpravin Arunpravin.PaneerSelvam@amd.com
[ Upstream commit fc3785fb56a27304c769af730d079f4337d4dc76 ]
pass the correct size value computed using the max_order.
<log snip>
[ 68.124177][ T1] UBSAN: shift-out-of-bounds in include/linux/log2.h:67:13 [ 68.125333][ T1] shift exponent 4294967295 is too large for 32-bit type 'long unsigned int' [ 68.126563][ T1] CPU: 0 PID: 1 Comm: swapper Not tainted 5.17.0-rc2-00311-g39ec47bbfd5d #2 [ 68.127758][ T1] Call Trace: [ 68.128187][ T1] dump_stack_lvl (lib/dump_stack.c:108) [ 68.128793][ T1] dump_stack (lib/dump_stack.c:114) [ 68.129331][ T1] ubsan_epilogue (lib/ubsan.c:152) [ 68.129958][ T1] __ubsan_handle_shift_out_of_bounds.cold (arch/x86/include/asm/smap.h:85)
[ 68.130791][ T1] ? drm_block_alloc+0x28/0x80 [ 68.131582][ T1] ? rcu_read_lock_sched_held (kernel/rcu/update.c:125) [ 68.132215][ T1] ? kmem_cache_alloc (include/trace/events/kmem.h:54 mm/slab.c:3501) [ 68.132878][ T1] ? mark_free+0x2e/0x80 [ 68.133524][ T1] drm_buddy_init.cold (include/linux/log2.h:67 drivers/gpu/drm/drm_buddy.c:131) [ 68.134145][ T1] ? test_drm_cmdline_init (drivers/gpu/drm/selftests/test-drm_buddy.c:87)
[ 68.134770][ T1] igt_buddy_alloc_limit (drivers/gpu/drm/selftests/test-drm_buddy.c:30) [ 68.135472][ T1] ? vprintk_default (kernel/printk/printk.c:2257) [ 68.136057][ T1] ? test_drm_cmdline_init (drivers/gpu/drm/selftests/test-drm_buddy.c:87)
[ 68.136812][ T1] test_drm_buddy_init (drivers/gpu/drm/selftests/drm_selftest.c:77 drivers/gpu/drm/selftests/test-drm_buddy.c:95) [ 68.137475][ T1] do_one_initcall (init/main.c:1300) [ 68.138111][ T1] ? parse_args (kernel/params.c:609 kernel/params.c:146 kernel/params.c:188) [ 68.138717][ T1] do_basic_setup (init/main.c:1372 init/main.c:1389 init/main.c:1408) [ 68.139366][ T1] kernel_init_freeable (init/main.c:1617) [ 68.140040][ T1] ? rest_init (init/main.c:1494) [ 68.140634][ T1] kernel_init (init/main.c:1504) [ 68.141155][ T1] ret_from_fork (arch/x86/entry/entry_32.S:772) [ 68.141607][ T1] ================================================================================ [ 68.146730][ T1] ------------[ cut here ]------------ [ 68.147460][ T1] kernel BUG at drivers/gpu/drm/drm_buddy.c:140! [ 68.148280][ T1] invalid opcode: 0000 [#1] [ 68.148895][ T1] CPU: 0 PID: 1 Comm: swapper Not tainted 5.17.0-rc2-00311-g39ec47bbfd5d #2 [ 68.149896][ T1] EIP: drm_buddy_init (drivers/gpu/drm/drm_buddy.c:140 (discriminator 1))
For more details: https://lists.01.org/hyperkitty/list/lkp@lists.01.org/thread/FDIF3HCILZNN5UQ...
Signed-off-by: Arunpravin Arunpravin.PaneerSelvam@amd.com Reported-by: kernel test robot oliver.sang@intel.com Acked-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20220303201602.2365-1-Arunprav... Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/selftests/test-drm_buddy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/selftests/test-drm_buddy.c b/drivers/gpu/drm/selftests/test-drm_buddy.c index fa997f89522b..913cbd7eae04 100644 --- a/drivers/gpu/drm/selftests/test-drm_buddy.c +++ b/drivers/gpu/drm/selftests/test-drm_buddy.c @@ -902,14 +902,13 @@ static int igt_buddy_alloc_range(void *arg)
static int igt_buddy_alloc_limit(void *arg) { - u64 end, size = U64_MAX, start = 0; + u64 size = U64_MAX, start = 0; struct drm_buddy_block *block; unsigned long flags = 0; LIST_HEAD(allocated); struct drm_buddy mm; int err;
- size = end = round_down(size, 4096); err = drm_buddy_init(&mm, size, PAGE_SIZE); if (err) return err; @@ -921,7 +920,8 @@ static int igt_buddy_alloc_limit(void *arg) goto out_fini; }
- err = drm_buddy_alloc_blocks(&mm, start, end, size, + size = mm.chunk_size << mm.max_order; + err = drm_buddy_alloc_blocks(&mm, start, size, size, PAGE_SIZE, &allocated, flags);
if (unlikely(err))
From: Zack Rusin zackr@vmware.com
[ Upstream commit 8bb75aeb58bd688d70827ae179bd3da57b6d975b ]
The kms code wasn't validating the modifiers and was letting through unsupported formats. rgb8 was never properly supported and has no matching svga screen target format so remove it. This fixes format/modifier failures in kms_addfb_basic from IGT.
Signed-off-by: Zack Rusin zackr@vmware.com Reviewed-by: Martin Krastev krastevm@vmware.com Link: https://patchwork.freedesktop.org/patch/msgid/20220318174332.440068-4-zack@k... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 30 +++++++++++++++-------------- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 1 - 2 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 93431e8f6606..9410152f9d6f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -914,6 +914,15 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, * Sanity checks. */
+ if (!drm_any_plane_has_format(&dev_priv->drm, + mode_cmd->pixel_format, + mode_cmd->modifier[0])) { + drm_dbg(&dev_priv->drm, + "unsupported pixel format %p4cc / modifier 0x%llx\n", + &mode_cmd->pixel_format, mode_cmd->modifier[0]); + return -EINVAL; + } + /* Surface must be marked as a scanout. */ if (unlikely(!surface->metadata.scanout)) return -EINVAL; @@ -1236,20 +1245,13 @@ static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv, return -EINVAL; }
- /* Limited framebuffer color depth support for screen objects */ - if (dev_priv->active_display_unit == vmw_du_screen_object) { - switch (mode_cmd->pixel_format) { - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_ARGB8888: - break; - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_RGB565: - break; - default: - DRM_ERROR("Invalid pixel format: %p4cc\n", - &mode_cmd->pixel_format); - return -EINVAL; - } + if (!drm_any_plane_has_format(&dev_priv->drm, + mode_cmd->pixel_format, + mode_cmd->modifier[0])) { + drm_dbg(&dev_priv->drm, + "unsupported pixel format %p4cc / modifier 0x%llx\n", + &mode_cmd->pixel_format, mode_cmd->modifier[0]); + return -EINVAL; }
vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 4d36e8507380..d9ebd02099a6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -247,7 +247,6 @@ struct vmw_framebuffer_bo { static const uint32_t __maybe_unused vmw_primary_plane_formats[] = { DRM_FORMAT_XRGB1555, DRM_FORMAT_RGB565, - DRM_FORMAT_RGB888, DRM_FORMAT_XRGB8888, DRM_FORMAT_ARGB8888, };
From: Wen Gong quic_wgong@quicinc.com
[ Upstream commit 0d7a8a6204ea9271f1d0a8c66a9fd2f54d2e3cbc ]
When test device recovery with below command, it has warning in message as below. echo assert > /sys/kernel/debug/ath11k/wcn6855\ hw2.0/simulate_fw_crash echo assert > /sys/kernel/debug/ath11k/qca6390\ hw2.0/simulate_fw_crash
warning message: [ 1965.642121] ath11k_pci 0000:06:00.0: simulating firmware assert crash [ 1968.471364] ieee80211 phy0: Hardware restart was requested [ 1968.511305] ------------[ cut here ]------------ [ 1968.511368] WARNING: CPU: 3 PID: 1546 at drivers/bus/mhi/core/pm.c:505 mhi_pm_disable_transition+0xb37/0xda0 [mhi] [ 1968.511443] Modules linked in: ath11k_pci ath11k mac80211 libarc4 cfg80211 qmi_helpers qrtr_mhi mhi qrtr nvme nvme_core [ 1968.511563] CPU: 3 PID: 1546 Comm: kworker/u17:0 Kdump: loaded Tainted: G W 5.17.0-rc3-wt-ath+ #579 [ 1968.511629] Hardware name: Intel(R) Client Systems NUC8i7HVK/NUC8i7HVB, BIOS HNKBLi70.86A.0067.2021.0528.1339 05/28/2021 [ 1968.511704] Workqueue: mhi_hiprio_wq mhi_pm_st_worker [mhi] [ 1968.511787] RIP: 0010:mhi_pm_disable_transition+0xb37/0xda0 [mhi] [ 1968.511870] Code: a9 fe ff ff 4c 89 ff 44 89 04 24 e8 03 46 f6 e5 44 8b 04 24 41 83 f8 01 0f 84 21 fe ff ff e9 4c fd ff ff 0f 0b e9 af f8 ff ff <0f> 0b e9 5c f8 ff ff 48 89 df e8 da 9e ee e3 e9 12 fd ff ff 4c 89 [ 1968.511923] RSP: 0018:ffffc900024efbf0 EFLAGS: 00010286 [ 1968.511969] RAX: 00000000ffffffff RBX: ffff88811d241250 RCX: ffffffffc0176922 [ 1968.512014] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff888118a90a24 [ 1968.512059] RBP: ffff888118a90800 R08: 0000000000000000 R09: ffff888118a90a27 [ 1968.512102] R10: ffffed1023152144 R11: 0000000000000001 R12: ffff888118a908ac [ 1968.512229] R13: ffff888118a90928 R14: dffffc0000000000 R15: ffff888118a90a24 [ 1968.512310] FS: 0000000000000000(0000) GS:ffff888234200000(0000) knlGS:0000000000000000 [ 1968.512405] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1968.512493] CR2: 00007f5538f443a8 CR3: 000000016dc28001 CR4: 00000000003706e0 [ 1968.512587] Call Trace: [ 1968.512672] <TASK> [ 1968.512751] ? _raw_spin_unlock_irq+0x1f/0x40 [ 1968.512859] mhi_pm_st_worker+0x3ac/0x790 [mhi] [ 1968.512959] ? mhi_pm_mission_mode_transition.isra.0+0x7d0/0x7d0 [mhi] [ 1968.513063] process_one_work+0x86a/0x1400 [ 1968.513184] ? pwq_dec_nr_in_flight+0x230/0x230 [ 1968.513312] ? move_linked_works+0x125/0x290 [ 1968.513416] worker_thread+0x6db/0xf60 [ 1968.513536] ? process_one_work+0x1400/0x1400 [ 1968.513627] kthread+0x241/0x2d0 [ 1968.513733] ? kthread_complete_and_exit+0x20/0x20 [ 1968.513821] ret_from_fork+0x22/0x30 [ 1968.513924] </TASK>
Reason is mhi_deassert_dev_wake() from mhi_device_put() is called but mhi_assert_dev_wake() from __mhi_device_get_sync() is not called in progress of recovery. Commit 8e0559921f9a ("bus: mhi: core: Skip device wake in error or shutdown state") add check for the pm_state of mhi in __mhi_device_get_sync(), and the pm_state is not the normal state untill recovery is completed, so it leads the dev_wake is not 0 and above warning print in mhi_pm_disable_transition() while checking mhi_cntrl->dev_wake.
Add check in ath11k_pci_write32()/ath11k_pci_read32() to skip call mhi_device_put() if mhi_device_get_sync() does not really do wake, then the warning gone.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03003-QCAHSPSWPL_V1_V2_SILICONZ_LITE-2
Signed-off-by: Wen Gong quic_wgong@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220228064606.8981-5-quic_wgong@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/pci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c index 903758751c99..8a3ff12057e8 100644 --- a/drivers/net/wireless/ath/ath11k/pci.c +++ b/drivers/net/wireless/ath/ath11k/pci.c @@ -191,6 +191,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 window_start; + int ret = 0;
/* for offset beyond BAR + 4K - 32, may * need to wakeup MHI to access. @@ -198,7 +199,7 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ACCESS_ALWAYS_OFF) - mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
if (offset < WINDOW_START) { iowrite32(value, ab->mem + offset); @@ -222,7 +223,8 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value)
if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + offset >= ACCESS_ALWAYS_OFF && + !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); }
@@ -230,6 +232,7 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) { struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); u32 val, window_start; + int ret = 0;
/* for offset beyond BAR + 4K - 32, may * need to wakeup MHI to access. @@ -237,7 +240,7 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && offset >= ACCESS_ALWAYS_OFF) - mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); + ret = mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev);
if (offset < WINDOW_START) { val = ioread32(ab->mem + offset); @@ -261,7 +264,8 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset)
if (ab->hw_params.wakeup_mhi && test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && - offset >= ACCESS_ALWAYS_OFF) + offset >= ACCESS_ALWAYS_OFF && + !ret) mhi_device_put(ab_pci->mhi_ctrl->mhi_dev);
return val;
From: Liu Zixian liuzixian4@huawei.com
[ Upstream commit 194d250cdc4a40ccbd179afd522a9e9846957402 ]
drm_cvt_mode may return NULL and we should check it.
This bug is found by syzkaller:
FAULT_INJECTION stacktrace: [ 168.567394] FAULT_INJECTION: forcing a failure. name failslab, interval 1, probability 0, space 0, times 1 [ 168.567403] CPU: 1 PID: 6425 Comm: syz Kdump: loaded Not tainted 4.19.90-vhulk2201.1.0.h1035.kasan.eulerosv2r10.aarch64 #1 [ 168.567406] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 [ 168.567408] Call trace: [ 168.567414] dump_backtrace+0x0/0x310 [ 168.567418] show_stack+0x28/0x38 [ 168.567423] dump_stack+0xec/0x15c [ 168.567427] should_fail+0x3ac/0x3d0 [ 168.567437] __should_failslab+0xb8/0x120 [ 168.567441] should_failslab+0x28/0xc0 [ 168.567445] kmem_cache_alloc_trace+0x50/0x640 [ 168.567454] drm_mode_create+0x40/0x90 [ 168.567458] drm_cvt_mode+0x48/0xc78 [ 168.567477] virtio_gpu_conn_get_modes+0xa8/0x140 [virtio_gpu] [ 168.567485] drm_helper_probe_single_connector_modes+0x3a4/0xd80 [ 168.567492] drm_mode_getconnector+0x2e0/0xa70 [ 168.567496] drm_ioctl_kernel+0x11c/0x1d8 [ 168.567514] drm_ioctl+0x558/0x6d0 [ 168.567522] do_vfs_ioctl+0x160/0xf30 [ 168.567525] ksys_ioctl+0x98/0xd8 [ 168.567530] __arm64_sys_ioctl+0x50/0xc8 [ 168.567536] el0_svc_common+0xc8/0x320 [ 168.567540] el0_svc_handler+0xf8/0x160 [ 168.567544] el0_svc+0x10/0x218
KASAN stacktrace: [ 168.567561] BUG: KASAN: null-ptr-deref in virtio_gpu_conn_get_modes+0xb4/0x140 [virtio_gpu] [ 168.567565] Read of size 4 at addr 0000000000000054 by task syz/6425 [ 168.567566] [ 168.567571] CPU: 1 PID: 6425 Comm: syz Kdump: loaded Not tainted 4.19.90-vhulk2201.1.0.h1035.kasan.eulerosv2r10.aarch64 #1 [ 168.567573] Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 [ 168.567575] Call trace: [ 168.567578] dump_backtrace+0x0/0x310 [ 168.567582] show_stack+0x28/0x38 [ 168.567586] dump_stack+0xec/0x15c [ 168.567591] kasan_report+0x244/0x2f0 [ 168.567594] __asan_load4+0x58/0xb0 [ 168.567607] virtio_gpu_conn_get_modes+0xb4/0x140 [virtio_gpu] [ 168.567612] drm_helper_probe_single_connector_modes+0x3a4/0xd80 [ 168.567617] drm_mode_getconnector+0x2e0/0xa70 [ 168.567621] drm_ioctl_kernel+0x11c/0x1d8 [ 168.567624] drm_ioctl+0x558/0x6d0 [ 168.567628] do_vfs_ioctl+0x160/0xf30 [ 168.567632] ksys_ioctl+0x98/0xd8 [ 168.567636] __arm64_sys_ioctl+0x50/0xc8 [ 168.567641] el0_svc_common+0xc8/0x320 [ 168.567645] el0_svc_handler+0xf8/0x160 [ 168.567649] el0_svc+0x10/0x218
Signed-off-by: Liu Zixian liuzixian4@huawei.com Link: http://patchwork.freedesktop.org/patch/msgid/20220322091730.1653-1-liuzixian... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_display.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 5b00310ac4cd..f73352e7b832 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -179,6 +179,8 @@ static int virtio_gpu_conn_get_modes(struct drm_connector *connector) DRM_DEBUG("add mode: %dx%d\n", width, height); mode = drm_cvt_mode(connector->dev, width, height, 60, false, false, false); + if (!mode) + return count; mode->type |= DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, mode); count++;
From: Nikolay Borisov nborisov@suse.com
[ Upstream commit e299bcd4d16ff86f46c48df1062c8aae0eca1ed8 ]
Since commit 6521f8917082 ("namei: prepare for idmapped mounts") vfs_link's prototype was changed, the kprobe definition in profiler selftest in turn wasn't updated. The result is that all argument after the first are now stored in different registers. This means that self-test has been broken ever since. Fix it by updating the kprobe definition accordingly.
Signed-off-by: Nikolay Borisov nborisov@suse.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220331140949.1410056-1-nborisov@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/progs/profiler.inc.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/profiler.inc.h b/tools/testing/selftests/bpf/progs/profiler.inc.h index 4896fdf816f7..92331053dba3 100644 --- a/tools/testing/selftests/bpf/progs/profiler.inc.h +++ b/tools/testing/selftests/bpf/progs/profiler.inc.h @@ -826,8 +826,9 @@ int kprobe_ret__do_filp_open(struct pt_regs* ctx)
SEC("kprobe/vfs_link") int BPF_KPROBE(kprobe__vfs_link, - struct dentry* old_dentry, struct inode* dir, - struct dentry* new_dentry, struct inode** delegated_inode) + struct dentry* old_dentry, struct user_namespace *mnt_userns, + struct inode* dir, struct dentry* new_dentry, + struct inode** delegated_inode) { struct bpf_func_stats_ctx stats_ctx; bpf_stats_enter(&stats_ctx, profiler_bpf_vfs_link);
From: Quentin Monnet quentin@isovalent.com
[ Upstream commit 4eeebce6ac4ad80ee8243bb847c98e0e55848d47 ]
The script for checking that various lists of types in bpftool remain in sync with the UAPI BPF header uses a regex to parse enum bpf_prog_type. If this enum contains a set of values different from the list of program types in bpftool, it complains.
This script should have reported the addition, some time ago, of the new BPF_PROG_TYPE_SYSCALL, which was not reported to bpftool's program types list. It failed to do so, because it failed to parse that new type from the enum. This is because the new value, in the BPF header, has an explicative comment on the same line, and the regex does not support that.
Let's update the script to support parsing enum values when they have comments on the same line.
Signed-off-by: Quentin Monnet quentin@isovalent.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220404140944.64744-1-quentin@isovalent.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_bpftool_synctypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/test_bpftool_synctypes.py b/tools/testing/selftests/bpf/test_bpftool_synctypes.py index 6bf21e47882a..c0e7acd698ed 100755 --- a/tools/testing/selftests/bpf/test_bpftool_synctypes.py +++ b/tools/testing/selftests/bpf/test_bpftool_synctypes.py @@ -180,7 +180,7 @@ class FileExtractor(object): @enum_name: name of the enum to parse """ start_marker = re.compile(f'enum {enum_name} {{\n') - pattern = re.compile('^\s*(BPF_\w+),?$') + pattern = re.compile('^\s*(BPF_\w+),?(\s+/*.**/)?$') end_marker = re.compile('^};') parser = BlockParser(self.reader) parser.search_block(start_marker)
From: Karthikeyan Kathirvel quic_kathirve@quicinc.com
[ Upstream commit 50dc9ce9f80554a88e33b73c30851acf2be36ed3 ]
The maximum number of SSIDs in a for active probe requests is currently reported as 16 (WLAN_SCAN_PARAMS_MAX_SSID) when registering the driver. The scan_req_params structure only has the capacity to hold 10 SSIDs. This leads to a buffer overflow which can be triggered from wpa_supplicant in userspace. When copying the SSIDs into the scan_req_params structure in the ath11k_mac_op_hw_scan route, it can overwrite the extraie pointer.
Firmware supports 16 ssid * 4 bssid, for each ssid 4 bssid combo probe request will be sent, so totally 64 probe requests supported. So set both max ssid and bssid to 16 and 4 respectively. Remove the redundant macros of ssid and bssid.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01300-QCAHKSWPL_SILICONZ-1
Signed-off-by: Karthikeyan Kathirvel quic_kathirve@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220329150221.21907-1-quic_kathirve@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/wmi.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index 587f42307250..b5b72483477d 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -3088,9 +3088,6 @@ enum scan_dwelltime_adaptive_mode { SCAN_DWELL_MODE_STATIC = 4 };
-#define WLAN_SCAN_MAX_NUM_SSID 10 -#define WLAN_SCAN_MAX_NUM_BSSID 10 - #define WLAN_SSID_MAX_LEN 32
struct element_info { @@ -3105,7 +3102,6 @@ struct wlan_ssid {
#define WMI_IE_BITMAP_SIZE 8
-#define WMI_SCAN_MAX_NUM_SSID 0x0A /* prefix used by scan requestor ids on the host */ #define WMI_HOST_SCAN_REQUESTOR_ID_PREFIX 0xA000
@@ -3113,10 +3109,6 @@ struct wlan_ssid { /* host cycles through the lower 12 bits to generate ids */ #define WMI_HOST_SCAN_REQ_ID_PREFIX 0xA000
-#define WLAN_SCAN_PARAMS_MAX_SSID 16 -#define WLAN_SCAN_PARAMS_MAX_BSSID 4 -#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 - /* Values lower than this may be refused by some firmware revisions with a scan * completion with a timedout reason. */ @@ -3312,8 +3304,8 @@ struct scan_req_params { u32 n_probes; u32 *chan_list; u32 notify_scan_events; - struct wlan_ssid ssid[WLAN_SCAN_MAX_NUM_SSID]; - struct wmi_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID]; + struct wlan_ssid ssid[WLAN_SCAN_PARAMS_MAX_SSID]; + struct wmi_mac_addr bssid_list[WLAN_SCAN_PARAMS_MAX_BSSID]; struct element_info extraie; struct element_info htcap; struct element_info vhtcap;
From: Yuntao Wang ytcoode@gmail.com
[ Upstream commit 2d0df01974ce2b59b6f7d5bd3ea58d74f12ddf85 ]
Currently, if sym_cnt > 0, it just returns and does not close file, fix it.
Signed-off-by: Yuntao Wang ytcoode@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220405145711.49543-1-ytcoode@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/trace_helpers.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c index 3d6217e3aff7..9c4be2cdb21a 100644 --- a/tools/testing/selftests/bpf/trace_helpers.c +++ b/tools/testing/selftests/bpf/trace_helpers.c @@ -25,15 +25,12 @@ static int ksym_cmp(const void *p1, const void *p2)
int load_kallsyms(void) { - FILE *f = fopen("/proc/kallsyms", "r"); + FILE *f; char func[256], buf[256]; char symbol; void *addr; int i = 0;
- if (!f) - return -ENOENT; - /* * This is called/used from multiplace places, * load symbols just once. @@ -41,6 +38,10 @@ int load_kallsyms(void) if (sym_cnt) return 0;
+ f = fopen("/proc/kallsyms", "r"); + if (!f) + return -ENOENT; + while (fgets(buf, sizeof(buf), f)) { if (sscanf(buf, "%p %c %s", &addr, &symbol, func) != 3) break;
From: Zong-Zhe Yang kevin_yang@realtek.com
[ Upstream commit b169f877f001a474fb89939842c390518160bcc5 ]
The CAM, meaning address CAM and bssid CAM here, will get leaks during SER (system error recover) L2 reset process and ieee80211_restart_hw() which is called by L2 reset process eventually.
The normal flow would be like -> add interface (acquire 1) -> enter ips (release 1) -> leave ips (acquire 1) -> connection (occupy 1) <(A) 1 leak after L2 reset if non-sec connection>
The ieee80211_restart_hw() flow (under connection) -> ieee80211 reconfig -> add interface (acquire 1) -> leave ips (acquire 1) -> connection (occupy (A) + 2) <(B) 1 more leak>
Originally, CAM is released before HW restart only if connection is under security. Now, release CAM whatever connection it is to fix leak in (A). OTOH, check if CAM is already valid to avoid acquiring multiple times to fix (B).
Besides, if AP mode, release address CAM of all stations before HW restart.
Signed-off-by: Zong-Zhe Yang kevin_yang@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220314071250.40292-2-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw89/cam.c | 14 ++++++++++++-- drivers/net/wireless/realtek/rtw89/ser.c | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 305dbbebff6b..26bef9fdd205 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -421,10 +421,8 @@ static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw, void *data) { struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; - struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false); - rtw89_cam_deinit(rtwdev, rtwvif); }
void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev, @@ -480,6 +478,12 @@ int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev, int i; int ret;
+ if (unlikely(addr_cam->valid)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "addr cam is already valid; skip init\n"); + return 0; + } + ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx); if (ret) { rtw89_err(rtwdev, "failed to get available addr cam\n"); @@ -531,6 +535,12 @@ static int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev, u8 bssid_cam_idx; int ret;
+ if (unlikely(bssid_cam->valid)) { + rtw89_debug(rtwdev, RTW89_DBG_FW, + "bssid cam is already valid; skip init\n"); + return 0; + } + ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx); if (ret) { rtw89_err(rtwdev, "failed to get available bssid cam\n"); diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 837cdc366a61..e86f3d89ef1b 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -220,11 +220,32 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) rtwvif->trigger = false; }
+static void ser_sta_deinit_addr_cam_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw89_dev *rtwdev = (struct rtw89_dev *)data; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + + rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam); +} + +static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) +{ + if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) + ieee80211_iterate_stations_atomic(rtwdev->hw, + ser_sta_deinit_addr_cam_iter, + rtwdev); + + rtw89_cam_deinit(rtwdev, rtwvif); +} + static void ser_reset_mac_binding(struct rtw89_dev *rtwdev) { struct rtw89_vif *rtwvif;
rtw89_cam_reset_keys(rtwdev); + rtw89_for_each_rtwvif(rtwdev, rtwvif) + ser_deinit_cam(rtwdev, rtwvif); + rtw89_core_release_all_bits_map(rtwdev->mac_id_map, RTW89_MAX_MAC_ID_NUM); rtw89_for_each_rtwvif(rtwdev, rtwvif) ser_reset_vif(rtwdev, rtwvif);
From: Po Hao Huang phhuang@realtek.com
[ Upstream commit 65ee4971a262a024e239e5d2b7f4dee1b3dff40e ]
Without this patch, hw scan won't stay long enough on DFS/passive channels. Found previous logic error and fix it.
Signed-off-by: Po Hao Huang phhuang@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220401055043.12512-5-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw89/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index 6deaf8eec6b4..a9b5315a517e 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -2065,7 +2065,7 @@ static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, ch_info->num_pkt = 0; break; case RTW89_CHAN_DFS: - ch_info->period = min_t(u8, ch_info->period, + ch_info->period = max_t(u8, ch_info->period, RTW89_DFS_CHAN_TIME); ch_info->dwell_time = RTW89_DWELL_TIME; break;
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 3e12968f6d12a34b540c39cbd696a760cc4616f0 ]
cfg80211_ch_switch_notify uses ASSERT_WDEV_LOCK to assert that net_device->ieee80211_ptr->mtx (which is the same as priv->wdev.mtx) is held during the function's execution. mwifiex_dfs_chan_sw_work_queue is one of its callers, which does not hold that lock, therefore violating the assertion. Add a lock around the call.
Disclaimer: I am currently working on a static analyser to detect missing locks. This was a reported case. I manually verified the report by looking at the code, so that I do not send wrong information or patches. After concluding that this seems to be a true positive, I created this patch. However, as I do not in fact have this particular hardware, I was unable to test it.
Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220321225515.32113-1-dossche.niels@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/11h.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c index d2ee6469e67b..3fa25cd64cda 100644 --- a/drivers/net/wireless/marvell/mwifiex/11h.c +++ b/drivers/net/wireless/marvell/mwifiex/11h.c @@ -303,5 +303,7 @@ 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); + mutex_unlock(&priv->wdev.mtx); }
From: Haowen Bai baihaowen@meizu.com
[ Upstream commit 3f6b867559b3d43a7ce1b4799b755e812fc0d503 ]
fix warning reported by smatch: drivers/net/wireless/broadcom/b43legacy/phy.c:1181 b43legacy_phy_lo_b_measure() warn: assigning (-772) to unsigned variable 'fval'
Signed-off-by: Haowen Bai baihaowen@meizu.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/1648203433-8736-1-git-send-email-baihaowen@meizu.c... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/b43legacy/phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43legacy/phy.c b/drivers/net/wireless/broadcom/b43legacy/phy.c index 05404fbd1e70..c1395e622759 100644 --- a/drivers/net/wireless/broadcom/b43legacy/phy.c +++ b/drivers/net/wireless/broadcom/b43legacy/phy.c @@ -1123,7 +1123,7 @@ void b43legacy_phy_lo_b_measure(struct b43legacy_wldev *dev) struct b43legacy_phy *phy = &dev->phy; u16 regstack[12] = { 0 }; u16 mls; - u16 fval; + s16 fval; int i; int j;
From: Haowen Bai baihaowen@meizu.com
[ Upstream commit 11800d893b38e0e12d636c170c1abc19c43c730c ]
fix warning reported by smatch: drivers/net/wireless/broadcom/b43/phy_n.c:585 b43_nphy_adjust_lna_gain_table() warn: assigning (-2) to unsigned variable '*(lna_gain[0])'
Signed-off-by: Haowen Bai baihaowen@meizu.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/1648203315-28093-1-git-send-email-baihaowen@meizu.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/b43/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index cf3ccf4ddfe7..aa5c99465674 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -582,7 +582,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) u16 data[4]; s16 gain[2]; u16 minmax[2]; - static const u16 lna_gain[4] = { -2, 10, 19, 25 }; + static const s16 lna_gain[4] = { -2, 10, 19, 25 };
if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 1);
From: Haowen Bai baihaowen@meizu.com
[ Upstream commit e8366bbabe1d207cf7c5b11ae50e223ae6fc278b ]
crypt and crypt->ops could be null, so we need to checking null before dereference
Signed-off-by: Haowen Bai baihaowen@meizu.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/1648797055-25730-1-git-send-email-baihaowen@meizu.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/ipw2x00/libipw_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c index 36d1e6b2568d..4aec1fce1ae2 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c @@ -383,7 +383,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
/* Each fragment may need to have room for encryption * pre/postfix */ - if (host_encrypt) + if (host_encrypt && crypt && crypt->ops) bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + crypt->ops->extra_mpdu_postfix_len;
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 51454ea42c1ab4e0c2828bb0d4d53957976980de ]
idev->addr_list needs to be protected by idev->lock. However, it is not always possible to do so while iterating and performing actions on inet6_ifaddr instances. For example, multiple functions (like addrconf_{join,leave}_anycast) eventually call down to other functions that acquire the idev->lock. The current code temporarily unlocked the idev->lock during the loops, which can cause race conditions. Moving the locks up is also not an appropriate solution as the ordering of lock acquisition will be inconsistent with for example mc_lock.
This solution adds an additional field to inet6_ifaddr that is used to temporarily add the instances to a temporary list while holding idev->lock. The temporary list can then be traversed without holding idev->lock. This change was done in two places. In addrconf_ifdown, the list_for_each_entry_safe variant of the list loop is also no longer necessary as there is no deletion within that specific loop.
Suggested-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Niels Dossche dossche.niels@gmail.com Acked-by: Paolo Abeni pabeni@redhat.com Link: https://lore.kernel.org/r/20220403231523.45843-1-dossche.niels@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/if_inet6.h | 8 ++++++++ net/ipv6/addrconf.c | 30 ++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 4cfdef6ca4f6..c8490729b4ae 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -64,6 +64,14 @@ struct inet6_ifaddr {
struct hlist_node addr_lst; struct list_head if_list; + /* + * Used to safely traverse idev->addr_list in process context + * if the idev->lock needed to protect idev->addr_list cannot be held. + * In that case, add the items to this list temporarily and iterate + * without holding idev->lock. + * See addrconf_ifdown and dev_forward_change. + */ + struct list_head if_list_aux;
struct list_head tmp_list; struct inet6_ifaddr *ifpub; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b22504176588..1afc4c024981 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -797,6 +797,7 @@ static void dev_forward_change(struct inet6_dev *idev) { struct net_device *dev; struct inet6_ifaddr *ifa; + LIST_HEAD(tmp_addr_list);
if (!idev) return; @@ -815,14 +816,24 @@ static void dev_forward_change(struct inet6_dev *idev) } }
+ read_lock_bh(&idev->lock); list_for_each_entry(ifa, &idev->addr_list, if_list) { if (ifa->flags&IFA_F_TENTATIVE) continue; + list_add_tail(&ifa->if_list_aux, &tmp_addr_list); + } + read_unlock_bh(&idev->lock); + + while (!list_empty(&tmp_addr_list)) { + ifa = list_first_entry(&tmp_addr_list, + struct inet6_ifaddr, if_list_aux); + list_del(&ifa->if_list_aux); if (idev->cnf.forwarding) addrconf_join_anycast(ifa); else addrconf_leave_anycast(ifa); } + inet6_netconf_notify_devconf(dev_net(dev), RTM_NEWNETCONF, NETCONFA_FORWARDING, dev->ifindex, &idev->cnf); @@ -3728,7 +3739,8 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister) unsigned long event = unregister ? NETDEV_UNREGISTER : NETDEV_DOWN; struct net *net = dev_net(dev); struct inet6_dev *idev; - struct inet6_ifaddr *ifa, *tmp; + struct inet6_ifaddr *ifa; + LIST_HEAD(tmp_addr_list); bool keep_addr = false; bool was_ready; int state, i; @@ -3820,16 +3832,23 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister) write_lock_bh(&idev->lock); }
- list_for_each_entry_safe(ifa, tmp, &idev->addr_list, if_list) { + list_for_each_entry(ifa, &idev->addr_list, if_list) + list_add_tail(&ifa->if_list_aux, &tmp_addr_list); + write_unlock_bh(&idev->lock); + + while (!list_empty(&tmp_addr_list)) { struct fib6_info *rt = NULL; bool keep;
+ ifa = list_first_entry(&tmp_addr_list, + struct inet6_ifaddr, if_list_aux); + list_del(&ifa->if_list_aux); + addrconf_del_dad_work(ifa);
keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) && !addr_is_local(&ifa->addr);
- write_unlock_bh(&idev->lock); spin_lock_bh(&ifa->lock);
if (keep) { @@ -3860,15 +3879,14 @@ static int addrconf_ifdown(struct net_device *dev, bool unregister) addrconf_leave_solict(ifa->idev, &ifa->addr); }
- write_lock_bh(&idev->lock); if (!keep) { + write_lock_bh(&idev->lock); list_del_rcu(&ifa->if_list); + write_unlock_bh(&idev->lock); in6_ifa_put(ifa); } }
- write_unlock_bh(&idev->lock); - /* Step 5: Discard anycast and multicast list */ if (unregister) { ipv6_ac_destroy_dev(idev);
From: Daniel Vetter daniel.vetter@ffwll.ch
[ Upstream commit 43553559121ca90965b572cf8a1d6d0fd618b449 ]
This shouldn't be a problem in practice since until we've actually taken over the console there's nothing we've registered with the console/vt subsystem, so the exit/unbind path that check this can't do the wrong thing. But it's confusing, so fix it by moving it a tad later.
Acked-by: Sam Ravnborg sam@ravnborg.org Signed-off-by: Daniel Vetter daniel.vetter@intel.com Cc: Daniel Vetter daniel@ffwll.ch Cc: Du Cheng ducheng2@gmail.com Cc: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Cc: Claudio Suarez cssk@net-c.es Cc: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20220405210335.3434130-14-dani... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/core/fbcon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 2fc1b80a26ad..9a8ae6fa6ecb 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3265,6 +3265,9 @@ static void fbcon_register_existing_fbs(struct work_struct *work)
console_lock();
+ deferred_takeover = false; + logo_shown = FBCON_LOGO_DONTSHOW; + for_each_registered_fb(i) fbcon_fb_registered(registered_fb[i]);
@@ -3282,8 +3285,6 @@ static int fbcon_output_notifier(struct notifier_block *nb, pr_info("fbcon: Taking over console\n");
dummycon_unregister_output_notifier(&fbcon_output_nb); - deferred_takeover = false; - logo_shown = FBCON_LOGO_DONTSHOW;
/* We may get called in atomic context */ schedule_work(&fbcon_deferred_takeover_work);
From: Mike Travis mike.travis@hpe.com
[ Upstream commit bb3ab81bdbd53f88f26ffabc9fb15bd8466486ec ]
The UV5 platform synchronizes the TSCs among all chassis, and will not proceed to OS boot without achieving synchronization. Previous UV platforms provided a register indicating successful synchronization. This is no longer available on UV5. On this platform TSC_ADJUST should not be reset by the kernel.
Signed-off-by: Mike Travis mike.travis@hpe.com Signed-off-by: Steve Wahl steve.wahl@hpe.com Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Dimitri Sivanich dimitri.sivanich@hpe.com Acked-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/20220406195149.228164-3-steve.wahl@hpe.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/apic/x2apic_uv_x.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index f5a48e66e4f5..a6e9c2794ef5 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -199,7 +199,13 @@ static void __init uv_tsc_check_sync(void) int mmr_shift; char *state;
- /* Different returns from different UV BIOS versions */ + /* UV5 guarantees synced TSCs; do not zero TSC_ADJUST */ + if (!is_uv(UV2|UV3|UV4)) { + mark_tsc_async_resets("UV5+"); + return; + } + + /* UV2,3,4, UV BIOS TSC sync state available */ mmr = uv_early_read_mmr(UVH_TSC_SYNC_MMR); mmr_shift = is_uv2_hub() ? UVH_TSC_SYNC_SHIFT_UV2K : UVH_TSC_SYNC_SHIFT;
From: Kirill A. Shutemov kirill.shutemov@linux.intel.com
[ Upstream commit e2efb6359e620521d1e13f69b2257de8ceaa9475 ]
While running inside virtual machine, the kernel can bypass cache flushing. Changing sleep state in a virtual machine doesn't affect the host system sleep state and cannot lead to data loss.
Before entering sleep states, the ACPI code flushes caches to prevent data loss using the WBINVD instruction. This mechanism is required on bare metal.
But, any use WBINVD inside of a guest is worthless. Changing sleep state in a virtual machine doesn't affect the host system sleep state and cannot lead to data loss, so most hypervisors simply ignore it. Despite this, the ACPI code calls WBINVD unconditionally anyway. It's useless, but also normally harmless.
In TDX guests, though, WBINVD stops being harmless; it triggers a virtualization exception (#VE). If the ACPI cache-flushing WBINVD were left in place, TDX guests would need handling to recover from the exception.
Avoid using WBINVD whenever running under a hypervisor. This both removes the useless WBINVDs and saves TDX from implementing WBINVD handling.
Signed-off-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Dan Williams dan.j.williams@intel.com Reviewed-by: Thomas Gleixner tglx@linutronix.de Link: https://lkml.kernel.org/r/20220405232939.73860-30-kirill.shutemov@linux.inte... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/acenv.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/acenv.h b/arch/x86/include/asm/acenv.h index 9aff97f0de7f..d937c55e717e 100644 --- a/arch/x86/include/asm/acenv.h +++ b/arch/x86/include/asm/acenv.h @@ -13,7 +13,19 @@
/* Asm macros */
-#define ACPI_FLUSH_CPU_CACHE() wbinvd() +/* + * ACPI_FLUSH_CPU_CACHE() flushes caches on entering sleep states. + * It is required to prevent data loss. + * + * While running inside virtual machine, the kernel can bypass cache flushing. + * Changing sleep state in a virtual machine doesn't affect the host system + * sleep state and cannot lead to data loss. + */ +#define ACPI_FLUSH_CPU_CACHE() \ +do { \ + if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) \ + wbinvd(); \ +} while (0)
int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock);
From: Runqing Yang rainkin1993@gmail.com
[ Upstream commit d252a4a499a07bec21c65873f605c3a1ef52ffed ]
Background: Libbpf automatically replaces calls to BPF bpf_probe_read_{kernel,user} [_str]() helpers with bpf_probe_read[_str](), if libbpf detects that kernel doesn't support new APIs. Specifically, libbpf invokes the probe_kern_probe_read_kernel function to load a small eBPF program into the kernel in which bpf_probe_read_kernel API is invoked and lets the kernel checks whether the new API is valid. If the loading fails, libbpf considers the new API invalid and replaces it with the old API.
static int probe_kern_probe_read_kernel(void) { struct bpf_insn insns[] = { BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), /* r1 = r10 (fp) */ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), /* r1 += -8 */ BPF_MOV64_IMM(BPF_REG_2, 8), /* r2 = 8 */ BPF_MOV64_IMM(BPF_REG_3, 0), /* r3 = 0 */ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_probe_read_kernel), BPF_EXIT_INSN(), }; int fd, insn_cnt = ARRAY_SIZE(insns);
fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL", insns, insn_cnt, NULL); return probe_fd(fd); }
Bug: On older kernel versions [0], the kernel checks whether the version number provided in the bpf syscall, matches the LINUX_VERSION_CODE. If not matched, the bpf syscall fails. eBPF However, the probe_kern_probe_read_kernel code does not set the kernel version number provided to the bpf syscall, which causes the loading process alwasys fails for old versions. It means that libbpf will replace the new API with the old one even the kernel supports the new one.
Solution: After a discussion in [1], the solution is using BPF_PROG_TYPE_TRACEPOINT program type instead of BPF_PROG_TYPE_KPROBE because kernel does not enfoce version check for tracepoint programs. I test the patch in old kernels (4.18 and 4.19) and it works well.
[0] https://elixir.bootlin.com/linux/v4.19/source/kernel/bpf/syscall.c#L1360 [1] Closes: https://github.com/libbpf/libbpf/issues/473
Signed-off-by: Runqing Yang rainkin1993@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220409144928.27499-1-rainkin1993@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 809fe209cdcc..dabf9a1451c3 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -4587,7 +4587,7 @@ static int probe_kern_probe_read_kernel(void) }; int fd, insn_cnt = ARRAY_SIZE(insns);
- fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL", insns, insn_cnt, NULL); + fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, NULL); return probe_fd(fd); }
From: Peter Seiderer ps.report@gmx.net
[ Upstream commit 5c6dd7bd569b54c0d2904125d7366aa93f077f67 ]
Using an ath9k card the debugfs output of minstrel_ht looks like the following (note the zero values for the first four rates sum-of success/attempts):
best ____________rate__________ ____statistics___ _____last____ ______sum-of________ mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] OFDM 1 DP 6.0M 272 1640 5.2 3.1 53.8 3 0 0 0 0 OFDM 1 C 9.0M 273 1104 7.7 4.6 53.8 4 0 0 0 0 OFDM 1 B 12.0M 274 836 10.0 6.0 53.8 4 0 0 0 0 OFDM 1 A S 18.0M 275 568 14.3 8.5 53.8 5 0 0 0 0 OFDM 1 S 24.0M 276 436 18.1 0.0 0.0 5 0 1 80 1778 OFDM 1 36.0M 277 300 24.9 0.0 0.0 0 0 1 0 107 OFDM 1 S 48.0M 278 236 30.4 0.0 0.0 0 0 0 0 75 OFDM 1 54.0M 279 212 33.0 0.0 0.0 0 0 0 0 72
Total packet count:: ideal 16582 lookaround 885 Average # of aggregated frames per A-MPDU: 1.0
Debugging showed that the rate statistics for the first four rates where stored in the MINSTREL_CCK_GROUP instead of the MINSTREL_OFDM_GROUP because in minstrel_ht_get_stats() the supported check was not honoured as done in various other places, e.g net/mac80211/rc80211_minstrel_ht_debugfs.c:
74 if (!(mi->supported[i] & BIT(j))) 75 continue;
With the patch applied the output looks good:
best ____________rate__________ ____statistics___ _____last____ ______sum-of________ mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts] OFDM 1 D 6.0M 272 1640 5.2 5.2 100.0 3 0 0 1 1 OFDM 1 C 9.0M 273 1104 7.7 7.7 100.0 4 0 0 38 38 OFDM 1 B 12.0M 274 836 10.0 9.9 89.5 4 2 2 372 395 OFDM 1 A P 18.0M 275 568 14.3 14.3 97.2 5 52 53 6956 7181 OFDM 1 S 24.0M 276 436 18.1 0.0 0.0 0 0 1 6 163 OFDM 1 36.0M 277 300 24.9 0.0 0.0 0 0 1 0 35 OFDM 1 S 48.0M 278 236 30.4 0.0 0.0 0 0 0 0 38 OFDM 1 S 54.0M 279 212 33.0 0.0 0.0 0 0 0 0 38
Total packet count:: ideal 7097 lookaround 287 Average # of aggregated frames per A-MPDU: 1.0
Signed-off-by: Peter Seiderer ps.report@gmx.net Link: https://lore.kernel.org/r/20220404165414.1036-1-ps.report@gmx.net Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/rc80211_minstrel_ht.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 9c6ace858107..5a6bf46a4248 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -362,6 +362,9 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
group = MINSTREL_CCK_GROUP; for (idx = 0; idx < ARRAY_SIZE(mp->cck_rates); idx++) { + if (!(mi->supported[group] & BIT(idx))) + continue; + if (rate->idx != mp->cck_rates[idx]) continue;
From: Liviu Dudau liviu.dudau@arm.com
[ Upstream commit c8f76c37cc3668ee45e081e76a15f24a352ebbdd ]
If drm_universal_plane_init() fails early we jump to the common cleanup code that calls komeda_plane_destroy() which in turn could access the uninitalised drm_plane and crash. Return early if an error is detected without going through the common code.
Reported-by: Steven Price steven.price@arm.com Reviewed-by: Steven Price steven.price@arm.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Link: https://lore.kernel.org/dri-devel/20211203100946.2706922-1-liviu.dudau@arm.c... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index d63d83800a8a..d646e3ae1a23 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -275,8 +275,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
komeda_put_fourcc_list(formats);
- if (err) - goto cleanup; + if (err) { + kfree(kplane); + return err; + }
drm_plane_helper_add(plane, &komeda_plane_helper_funcs);
From: Saaem Rizvi syerizvi@amd.com
[ Upstream commit 5d5af34072c8b11f60960c3bea57ff9de5877791 ]
[WHY] Z10 is should not be enabled by default on DCN31.
[HOW] Using DC debug flags to disable Z10 by default on DCN31.
Reviewed-by: Eric Yang Eric.Yang2@amd.com Acked-by: Pavle Kotarac Pavle.Kotarac@amd.com Signed-off-by: Saaem Rizvi syerizvi@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c index 63934ecf6be8..d71e625cc476 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c @@ -1030,6 +1030,7 @@ static const struct dc_debug_options debug_defaults_drv = { .afmt = true, } }, + .disable_z10 = true, .optimize_edp_link_rate = true, .enable_sw_cntl_psr = true, .apply_vendor_specific_lttpr_wa = true,
From: Padmanabha Srinivasaiah treasure4paddy@gmail.com
[ Upstream commit f75fd4b9221d93177c50dcfde671b2e907f53e86 ]
While booting secondary CPUs, cpus_read_[lock/unlock] is not keeping online cpumask stable. The transient online mask results in below calltrace.
[ 0.324121] CPU1: Booted secondary processor 0x0000000001 [0x410fd083] [ 0.346652] Detected PIPT I-cache on CPU2 [ 0.347212] CPU2: Booted secondary processor 0x0000000002 [0x410fd083] [ 0.377255] Detected PIPT I-cache on CPU3 [ 0.377823] CPU3: Booted secondary processor 0x0000000003 [0x410fd083] [ 0.379040] ------------[ cut here ]------------ [ 0.383662] WARNING: CPU: 0 PID: 10 at kernel/workqueue.c:3084 __flush_work+0x12c/0x138 [ 0.384850] Modules linked in: [ 0.385403] CPU: 0 PID: 10 Comm: rcu_tasks_rude_ Not tainted 5.17.0-rc3-v8+ #13 [ 0.386473] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT) [ 0.387289] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 0.388308] pc : __flush_work+0x12c/0x138 [ 0.388970] lr : __flush_work+0x80/0x138 [ 0.389620] sp : ffffffc00aaf3c60 [ 0.390139] x29: ffffffc00aaf3d20 x28: ffffffc009c16af0 x27: ffffff80f761df48 [ 0.391316] x26: 0000000000000004 x25: 0000000000000003 x24: 0000000000000100 [ 0.392493] x23: ffffffffffffffff x22: ffffffc009c16b10 x21: ffffffc009c16b28 [ 0.393668] x20: ffffffc009e53861 x19: ffffff80f77fbf40 x18: 00000000d744fcc9 [ 0.394842] x17: 000000000000000b x16: 00000000000001c2 x15: ffffffc009e57550 [ 0.396016] x14: 0000000000000000 x13: ffffffffffffffff x12: 0000000100000000 [ 0.397190] x11: 0000000000000462 x10: ffffff8040258008 x9 : 0000000100000000 [ 0.398364] x8 : 0000000000000000 x7 : ffffffc0093c8bf4 x6 : 0000000000000000 [ 0.399538] x5 : 0000000000000000 x4 : ffffffc00a976e40 x3 : ffffffc00810444c [ 0.400711] x2 : 0000000000000004 x1 : 0000000000000000 x0 : 0000000000000000 [ 0.401886] Call trace: [ 0.402309] __flush_work+0x12c/0x138 [ 0.402941] schedule_on_each_cpu+0x228/0x278 [ 0.403693] rcu_tasks_rude_wait_gp+0x130/0x144 [ 0.404502] rcu_tasks_kthread+0x220/0x254 [ 0.405264] kthread+0x174/0x1ac [ 0.405837] ret_from_fork+0x10/0x20 [ 0.406456] irq event stamp: 102 [ 0.406966] hardirqs last enabled at (101): [<ffffffc0093c8468>] _raw_spin_unlock_irq+0x78/0xb4 [ 0.408304] hardirqs last disabled at (102): [<ffffffc0093b8270>] el1_dbg+0x24/0x5c [ 0.409410] softirqs last enabled at (54): [<ffffffc0081b80c8>] local_bh_enable+0xc/0x2c [ 0.410645] softirqs last disabled at (50): [<ffffffc0081b809c>] local_bh_disable+0xc/0x2c [ 0.411890] ---[ end trace 0000000000000000 ]--- [ 0.413000] smp: Brought up 1 node, 4 CPUs [ 0.413762] SMP: Total of 4 processors activated. [ 0.414566] CPU features: detected: 32-bit EL0 Support [ 0.415414] CPU features: detected: 32-bit EL1 Support [ 0.416278] CPU features: detected: CRC32 instructions [ 0.447021] Callback from call_rcu_tasks_rude() invoked. [ 0.506693] Callback from call_rcu_tasks() invoked.
This commit therefore fixes this issue by applying a single-CPU optimization to the RCU Tasks Rude grace-period process. The key point here is that the purpose of this RCU flavor is to force a schedule on each online CPU since some past event. But the rcu_tasks_rude_wait_gp() function runs in the context of the RCU Tasks Rude's grace-period kthread, so there must already have been a context switch on the current CPU since the call to either synchronize_rcu_tasks_rude() or call_rcu_tasks_rude(). So if there is only a single CPU online, RCU Tasks Rude's grace-period kthread does not need to anything at all.
It turns out that the rcu_tasks_rude_wait_gp() function's call to schedule_on_each_cpu() causes problems during early boot. During that time, there is only one online CPU, namely the boot CPU. Therefore, applying this single-CPU optimization fixes early-boot instances of this problem.
Link: https://lore.kernel.org/lkml/20220210184319.25009-1-treasure4paddy@gmail.com... Suggested-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Padmanabha Srinivasaiah treasure4paddy@gmail.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tasks.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 99cf3a13954c..b43320b149d2 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -950,6 +950,9 @@ static void rcu_tasks_be_rude(struct work_struct *work) // Wait for one rude RCU-tasks grace period. static void rcu_tasks_rude_wait_gp(struct rcu_tasks *rtp) { + if (num_online_cpus() <= 1) + return; // Fastpath for only one CPU. + rtp->n_ipis += cpumask_weight(cpu_online_mask); schedule_on_each_cpu(rcu_tasks_be_rude); }
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit ab2756ea6b74987849b44ad0e33c3cfec159033b ]
If the cpu_possible_mask is sparse (for example, if bits are set only for CPUs 0, 4, 8, ...), then rcu_tasks_invoke_cbs() will access per-CPU data for a CPU not in cpu_possible_mask. It makes these accesses while doing a workqueue-based binary search for non-empty callback lists. Although this search must pass through CPUs not represented in cpu_possible_mask, it has no need to check the callback list for such CPUs.
This commit therefore changes the rcu_tasks_invoke_cbs() function's binary search so as to only check callback lists for CPUs present in cpu_possible_mask.
Reported-by: Eric Dumazet edumazet@google.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tasks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index b43320b149d2..00ff0896fb00 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -460,7 +460,7 @@ static void rcu_tasks_invoke_cbs(struct rcu_tasks *rtp, struct rcu_tasks_percpu } }
- if (rcu_segcblist_empty(&rtpcp->cblist)) + if (rcu_segcblist_empty(&rtpcp->cblist) || !cpu_possible(cpu)) return; raw_spin_lock_irqsave_rcu_node(rtpcp, flags); rcu_segcblist_advance(&rtpcp->cblist, rcu_seq_current(&rtp->tasks_gp_seq));
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit 46e861be589881e0905b9ade3d8439883858721c ]
The TASKS_RUDE_RCU does not select IRQ_WORK, which can result in build failures for kernels that do not otherwise select IRQ_WORK. This commit therefore causes the TASKS_RUDE_RCU Kconfig option to select IRQ_WORK.
Reported-by: Hyeonggon Yoo 42.hyeyoo@gmail.com Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/kernel/rcu/Kconfig b/kernel/rcu/Kconfig index bf8e341e75b4..f559870fbf8b 100644 --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig @@ -86,6 +86,7 @@ config TASKS_RCU
config TASKS_RUDE_RCU def_bool 0 + select IRQ_WORK help This option enables a task-based RCU implementation that uses only context switch (including preemption) and user-mode
From: Haowen Bai baihaowen@meizu.com
[ Upstream commit b8ff3395fbdf3b79a99d0ef410fc34c51044121e ]
fix warning reported by smatch: 251 drivers/net/ethernet/sfc/ef10.c:2259 efx_ef10_tx_tso_desc() warn: assigning (-208) to unsigned variable 'ip_tot_len'
Signed-off-by: Haowen Bai baihaowen@meizu.com Acked-by: Edward Cree ecree.xilinx@gmail.com Link: https://lore.kernel.org/r/1649640757-30041-1-git-send-email-baihaowen@meizu.... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sfc/ef10.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index f8edb3f1b73a..186cb28c03bd 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -2256,7 +2256,7 @@ int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb, * guaranteed to satisfy the second as we only attempt TSO if * inner_network_header <= 208. */ - ip_tot_len = -EFX_TSO2_MAX_HDRLEN; + ip_tot_len = 0x10000 - EFX_TSO2_MAX_HDRLEN; EFX_WARN_ON_ONCE_PARANOID(mss + EFX_TSO2_MAX_HDRLEN + (tcp->doff << 2u) > ip_tot_len);
From: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com
[ Upstream commit 1b6a6fc5280e97559287b61eade2d4b363e836f2 ]
It is possible when using ASoC that input_dev is unregistered while calling snd_jack_report, which causes NULL pointer dereference. In order to prevent this serialize access to input_dev using mutex lock.
Signed-off-by: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com Reviewed-by: Cezary Rojewski cezary.rojewski@intel.com Link: https://lore.kernel.org/r/20220412091628.3056922-1-amadeuszx.slawinski@linux... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/sound/jack.h | 1 + sound/core/jack.c | 34 +++++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/include/sound/jack.h b/include/sound/jack.h index 1181f536557e..1ed90e2109e9 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -62,6 +62,7 @@ struct snd_jack { const char *id; #ifdef CONFIG_SND_JACK_INPUT_DEV struct input_dev *input_dev; + struct mutex input_dev_lock; int registered; int type; char name[100]; diff --git a/sound/core/jack.c b/sound/core/jack.c index d1e3055f2b6a..88493cc31914 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -42,8 +42,11 @@ static int snd_jack_dev_disconnect(struct snd_device *device) #ifdef CONFIG_SND_JACK_INPUT_DEV struct snd_jack *jack = device->device_data;
- if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return 0; + }
/* If the input device is registered with the input subsystem * then we need to use a different deallocator. */ @@ -52,6 +55,7 @@ static int snd_jack_dev_disconnect(struct snd_device *device) else input_free_device(jack->input_dev); jack->input_dev = NULL; + mutex_unlock(&jack->input_dev_lock); #endif /* CONFIG_SND_JACK_INPUT_DEV */ return 0; } @@ -90,8 +94,11 @@ static int snd_jack_dev_register(struct snd_device *device) snprintf(jack->name, sizeof(jack->name), "%s %s", card->shortname, jack->id);
- if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return 0; + }
jack->input_dev->name = jack->name;
@@ -116,6 +123,7 @@ static int snd_jack_dev_register(struct snd_device *device) if (err == 0) jack->registered = 1;
+ mutex_unlock(&jack->input_dev_lock); return err; } #endif /* CONFIG_SND_JACK_INPUT_DEV */ @@ -517,9 +525,11 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, return -ENOMEM; }
- /* don't creat input device for phantom jack */ - if (!phantom_jack) { #ifdef CONFIG_SND_JACK_INPUT_DEV + mutex_init(&jack->input_dev_lock); + + /* don't create input device for phantom jack */ + if (!phantom_jack) { int i;
jack->input_dev = input_allocate_device(); @@ -537,8 +547,8 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, input_set_capability(jack->input_dev, EV_SW, jack_switch_types[i]);
-#endif /* CONFIG_SND_JACK_INPUT_DEV */ } +#endif /* CONFIG_SND_JACK_INPUT_DEV */
err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); if (err < 0) @@ -578,10 +588,14 @@ EXPORT_SYMBOL(snd_jack_new); void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) { WARN_ON(jack->registered); - if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return; + }
jack->input_dev->dev.parent = parent; + mutex_unlock(&jack->input_dev_lock); } EXPORT_SYMBOL(snd_jack_set_parent);
@@ -629,6 +643,8 @@ EXPORT_SYMBOL(snd_jack_set_key);
/** * snd_jack_report - Report the current status of a jack + * Note: This function uses mutexes and should be called from a + * context which can sleep (such as a workqueue). * * @jack: The jack to report status for * @status: The current status of the jack @@ -654,8 +670,11 @@ void snd_jack_report(struct snd_jack *jack, int status) status & jack_kctl->mask_bits);
#ifdef CONFIG_SND_JACK_INPUT_DEV - if (!jack->input_dev) + mutex_lock(&jack->input_dev_lock); + if (!jack->input_dev) { + mutex_unlock(&jack->input_dev_lock); return; + }
for (i = 0; i < ARRAY_SIZE(jack->key); i++) { int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits); @@ -675,6 +694,7 @@ void snd_jack_report(struct snd_jack *jack, int status) }
input_sync(jack->input_dev); + mutex_unlock(&jack->input_dev_lock); #endif /* CONFIG_SND_JACK_INPUT_DEV */ } EXPORT_SYMBOL(snd_jack_report);
From: Po-Hao Huang phhuang@realtek.com
[ Upstream commit 6723c0cde84fde582a261c186ce84100dcfa0019 ]
We should only fill in frequency reported by firmware during scan. Add this so frames won't be dropped by mac80211 due to frequency mismatch.
Signed-off-by: Po-Hao Huang phhuang@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220407095858.46807-3-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/rx.c b/drivers/net/wireless/realtek/rtw88/rx.c index d2d607e22198..84aedabdf285 100644 --- a/drivers/net/wireless/realtek/rtw88/rx.c +++ b/drivers/net/wireless/realtek/rtw88/rx.c @@ -158,7 +158,8 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, memset(rx_status, 0, sizeof(*rx_status)); rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->band = hw->conf.chandef.chan->band; - if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD)) + if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD) && + test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); if (pkt_stat->crc_err) rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
From: Po-Hao Huang phhuang@realtek.com
[ Upstream commit ece31c93d4d68f7eb8eea4431b052aacdb678de2 ]
RSSI value per frame is reported to mac80211 but not maintained in our own statistics, add it back to help us debug.
Signed-off-by: Po-Hao Huang phhuang@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220407095858.46807-7-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/rtw8821c.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.c b/drivers/net/wireless/realtek/rtw88/rtw8821c.c index 99eee128ae94..ec38a7c84951 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c @@ -512,6 +512,7 @@ static s8 get_cck_rx_pwr(struct rtw_dev *rtwdev, u8 lna_idx, u8 vga_idx) static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; s8 rx_power; u8 lna_idx = 0; u8 vga_idx = 0; @@ -523,6 +524,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status,
pkt_stat->rx_power[RF_PATH_A] = rx_power; pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; pkt_stat->bw = RTW_CHANNEL_WIDTH_20; pkt_stat->signal_power = rx_power; } @@ -530,6 +532,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; u8 rxsc, bw; s8 min_rx_power = -120;
@@ -549,6 +552,7 @@ static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status,
pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; pkt_stat->bw = bw; pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], min_rx_power);
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit 6f381481a5b236cb53d6de2c49c6ef83a4d0f432 ]
The direction field in the DMA config is deprecated. The rspi driver sets {src,dst}_{addr,addr_width} based on the DMA direction and it results in dmaengine_slave_config() failure as RZ DMAC driver validates {src,dst}_addr_width values independent of DMA direction.
This patch fixes the issue by passing both {src,dst}_{addr,addr_width} values independent of DMA direction.
Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Suggested-by: Vinod Koul vkoul@kernel.org Reviewed-by: Vinod Koul vkoul@kernel.org Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Tested-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20220411173115.6619-1-biju.das.jz@bp.renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-rspi.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index bd5708d7e5a1..7a014eeec2d0 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1108,14 +1108,11 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev, }
memset(&cfg, 0, sizeof(cfg)); + cfg.dst_addr = port_addr + RSPI_SPDR; + cfg.src_addr = port_addr + RSPI_SPDR; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; cfg.direction = dir; - if (dir == DMA_MEM_TO_DEV) { - cfg.dst_addr = port_addr; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - } else { - cfg.src_addr = port_addr; - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - }
ret = dmaengine_slave_config(chan, &cfg); if (ret) { @@ -1146,12 +1143,12 @@ static int rspi_request_dma(struct device *dev, struct spi_controller *ctlr, }
ctlr->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id, - res->start + RSPI_SPDR); + res->start); if (!ctlr->dma_tx) return -ENODEV;
ctlr->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id, - res->start + RSPI_SPDR); + res->start); if (!ctlr->dma_rx) { dma_release_channel(ctlr->dma_tx); ctlr->dma_tx = NULL;
From: Len Brown len.brown@intel.com
[ Upstream commit 6397b6418935773a34b533b3348b03f4ce3d7050 ]
ICX (and its duplicates) require special hard-coded DRAM RAPL units, rather than using the generic RAPL energy units.
Reported-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Signed-off-by: Len Brown len.brown@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/power/x86/turbostat/turbostat.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index bc5ae0872fed..babede4486de 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4376,6 +4376,7 @@ static double rapl_dram_energy_units_probe(int model, double rapl_energy_units) case INTEL_FAM6_BROADWELL_X: /* BDX */ case INTEL_FAM6_SKYLAKE_X: /* SKX */ case INTEL_FAM6_XEON_PHI_KNL: /* KNL */ + case INTEL_FAM6_ICELAKE_X: /* ICX */ return (rapl_dram_energy_units = 15.3 / 1000000); default: return (rapl_energy_units);
From: Eric Dumazet edumazet@google.com
[ Upstream commit d9d024f96609016628d750ebc8ee4a6f0d80e6e1 ]
Whenever tcp_validate_incoming() handles a valid RST packet, we should not pretend the packet was dropped.
Create a special section at the end of tcp_validate_incoming() to handle this case.
Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_input.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 60f99e9fb6d1..1f3ce7aea716 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5711,7 +5711,7 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, &tp->last_oow_ack_time)) tcp_send_dupack(sk, skb); } else if (tcp_reset_check(sk, skb)) { - tcp_reset(sk, skb); + goto reset; } goto discard; } @@ -5747,17 +5747,16 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, }
if (rst_seq_match) - tcp_reset(sk, skb); - else { - /* Disable TFO if RST is out-of-order - * and no data has been received - * for current active TFO socket - */ - if (tp->syn_fastopen && !tp->data_segs_in && - sk->sk_state == TCP_ESTABLISHED) - tcp_fastopen_active_disable(sk); - tcp_send_challenge_ack(sk); - } + goto reset; + + /* Disable TFO if RST is out-of-order + * and no data has been received + * for current active TFO socket + */ + if (tp->syn_fastopen && !tp->data_segs_in && + sk->sk_state == TCP_ESTABLISHED) + tcp_fastopen_active_disable(sk); + tcp_send_challenge_ack(sk); goto discard; }
@@ -5782,6 +5781,11 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, discard: tcp_drop(sk, skb); return false; + +reset: + tcp_reset(sk, skb); + __kfree_skb(skb); + return false; }
/*
From: Christoph Hellwig hch@lst.de
[ Upstream commit d2c7f56f8b5256d57f9e3fc7794c31361d43bdd9 ]
Ensure that the lo_device which is stored in the gendisk private data is valid until the gendisk is freed. Currently the loop driver uses a lot of effort to make sure a device is not freed when it is still in use, but to to fix a potential deadlock this will be relaxed a bit soon.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220330052917.2566582-12-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/loop.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a58595f5ee2c..ed7bec11948c 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1768,6 +1768,14 @@ static void lo_release(struct gendisk *disk, fmode_t mode) mutex_unlock(&lo->lo_mutex); }
+static void lo_free_disk(struct gendisk *disk) +{ + struct loop_device *lo = disk->private_data; + + mutex_destroy(&lo->lo_mutex); + kfree(lo); +} + static const struct block_device_operations lo_fops = { .owner = THIS_MODULE, .open = lo_open, @@ -1776,6 +1784,7 @@ static const struct block_device_operations lo_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = lo_compat_ioctl, #endif + .free_disk = lo_free_disk, };
/* @@ -2090,15 +2099,14 @@ static void loop_remove(struct loop_device *lo) { /* Make this loop device unreachable from pathname. */ del_gendisk(lo->lo_disk); - blk_cleanup_disk(lo->lo_disk); + blk_cleanup_queue(lo->lo_disk->queue); blk_mq_free_tag_set(&lo->tag_set);
mutex_lock(&loop_ctl_mutex); idr_remove(&loop_index_idr, lo->lo_number); mutex_unlock(&loop_ctl_mutex); - /* There is no route which can find this loop device. */ - mutex_destroy(&lo->lo_mutex); - kfree(lo); + + put_disk(lo->lo_disk); }
static void loop_probe(dev_t dev)
From: James Smart jsmart2021@gmail.com
[ Upstream commit e294647b1aed4247fe52851f3a3b2b19ae906228 ]
In an attempt to log message 0126 with LOG_TRACE_EVENT, the following hard lockup call trace hangs the system.
Call Trace: _raw_spin_lock_irqsave+0x32/0x40 lpfc_dmp_dbg.part.32+0x28/0x220 [lpfc] lpfc_cmpl_els_fdisc+0x145/0x460 [lpfc] lpfc_sli_cancel_jobs+0x92/0xd0 [lpfc] lpfc_els_flush_cmd+0x43c/0x670 [lpfc] lpfc_els_flush_all_cmd+0x37/0x60 [lpfc] lpfc_sli4_async_event_proc+0x956/0x1720 [lpfc] lpfc_do_work+0x1485/0x1d70 [lpfc] kthread+0x112/0x130 ret_from_fork+0x1f/0x40 Kernel panic - not syncing: Hard LOCKUP
The same CPU tries to claim the phba->port_list_lock twice.
Move the cfg_log_verbose checks as part of the lpfc_printf_vlog() and lpfc_printf_log() macros before calling lpfc_dmp_dbg(). There is no need to take the phba->port_list_lock within lpfc_dmp_dbg().
Link: https://lore.kernel.org/r/20220412222008.126521-3-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_init.c | 29 +---------------------------- drivers/scsi/lpfc/lpfc_logmsg.h | 6 +++--- 2 files changed, 4 insertions(+), 31 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 461d333b1b3a..f9cd4b72d949 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -15700,34 +15700,7 @@ void lpfc_dmp_dbg(struct lpfc_hba *phba) unsigned int temp_idx; int i; int j = 0; - unsigned long rem_nsec, iflags; - bool log_verbose = false; - struct lpfc_vport *port_iterator; - - /* Don't dump messages if we explicitly set log_verbose for the - * physical port or any vport. - */ - if (phba->cfg_log_verbose) - return; - - spin_lock_irqsave(&phba->port_list_lock, iflags); - list_for_each_entry(port_iterator, &phba->port_list, listentry) { - if (port_iterator->load_flag & FC_UNLOADING) - continue; - if (scsi_host_get(lpfc_shost_from_vport(port_iterator))) { - if (port_iterator->cfg_log_verbose) - log_verbose = true; - - scsi_host_put(lpfc_shost_from_vport(port_iterator)); - - if (log_verbose) { - spin_unlock_irqrestore(&phba->port_list_lock, - iflags); - return; - } - } - } - spin_unlock_irqrestore(&phba->port_list_lock, iflags); + unsigned long rem_nsec;
if (atomic_cmpxchg(&phba->dbg_log_dmping, 0, 1) != 0) return; diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index 7d480c798794..a5aafe230c74 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h @@ -73,7 +73,7 @@ do { \ #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ do { \ { if (((mask) & (vport)->cfg_log_verbose) || (level[1] <= '3')) { \ - if ((mask) & LOG_TRACE_EVENT) \ + if ((mask) & LOG_TRACE_EVENT && !(vport)->cfg_log_verbose) \ lpfc_dmp_dbg((vport)->phba); \ dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ fmt, (vport)->phba->brd_no, vport->vpi, ##arg); \ @@ -89,11 +89,11 @@ do { \ (phba)->pport->cfg_log_verbose : \ (phba)->cfg_log_verbose; \ if (((mask) & log_verbose) || (level[1] <= '3')) { \ - if ((mask) & LOG_TRACE_EVENT) \ + if ((mask) & LOG_TRACE_EVENT && !log_verbose) \ lpfc_dmp_dbg(phba); \ dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ fmt, phba->brd_no, ##arg); \ - } else if (!(phba)->cfg_log_verbose)\ + } else if (!log_verbose)\ lpfc_dbg_print(phba, "%d:" fmt, phba->brd_no, ##arg); \ } \ } while (0)
From: James Smart jsmart2021@gmail.com
[ Upstream commit 03cbbd7c2f5ee288f648f4aeedc765a181188553 ]
During stress I/O tests with 500+ vports, hard LOCKUP call traces are observed.
CPU A: native_queued_spin_lock_slowpath+0x192 _raw_spin_lock_irqsave+0x32 lpfc_handle_fcp_err+0x4c6 lpfc_fcp_io_cmd_wqe_cmpl+0x964 lpfc_sli4_fp_handle_cqe+0x266 __lpfc_sli4_process_cq+0x105 __lpfc_sli4_hba_process_cq+0x3c lpfc_cq_poll_hdler+0x16 irq_poll_softirq+0x76 __softirqentry_text_start+0xe4 irq_exit+0xf7 do_IRQ+0x7f
CPU B: native_queued_spin_lock_slowpath+0x5b _raw_spin_lock+0x1c lpfc_abort_handler+0x13e scmd_eh_abort_handler+0x85 process_one_work+0x1a7 worker_thread+0x30 kthread+0x112 ret_from_fork+0x1f
Diagram of lockup:
CPUA CPUB ---- ---- lpfc_cmd->buf_lock phba->hbalock lpfc_cmd->buf_lock phba->hbalock
Fix by reordering the taking of the lpfc_cmd->buf_lock and phba->hbalock in lpfc_abort_handler routine so that it tries to take the lpfc_cmd->buf_lock first before phba->hbalock.
Link: https://lore.kernel.org/r/20220412222008.126521-7-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_scsi.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index ba9dbb51b75f..c4fa7d68fe03 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5864,25 +5864,25 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) if (!lpfc_cmd) return ret;
- spin_lock_irqsave(&phba->hbalock, flags); + /* Guard against IO completion being called at same time */ + spin_lock_irqsave(&lpfc_cmd->buf_lock, flags); + + spin_lock(&phba->hbalock); /* driver queued commands are in process of being flushed */ if (phba->hba_flag & HBA_IOQ_FLUSH) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "3168 SCSI Layer abort requested I/O has been " "flushed by LLD.\n"); ret = FAILED; - goto out_unlock; + goto out_unlock_hba; }
- /* Guard against IO completion being called at same time */ - spin_lock(&lpfc_cmd->buf_lock); - if (!lpfc_cmd->pCmd) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "2873 SCSI Layer I/O Abort Request IO CMPL Status " "x%x ID %d LUN %llu\n", SUCCESS, cmnd->device->id, cmnd->device->lun); - goto out_unlock_buf; + goto out_unlock_hba; }
iocb = &lpfc_cmd->cur_iocbq; @@ -5890,7 +5890,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring; if (!pring_s4) { ret = FAILED; - goto out_unlock_buf; + goto out_unlock_hba; } spin_lock(&pring_s4->ring_lock); } @@ -5923,8 +5923,8 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) "3389 SCSI Layer I/O Abort Request is pending\n"); if (phba->sli_rev == LPFC_SLI_REV4) spin_unlock(&pring_s4->ring_lock); - spin_unlock(&lpfc_cmd->buf_lock); - spin_unlock_irqrestore(&phba->hbalock, flags); + spin_unlock(&phba->hbalock); + spin_unlock_irqrestore(&lpfc_cmd->buf_lock, flags); goto wait_for_cmpl; }
@@ -5945,15 +5945,13 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) if (ret_val != IOCB_SUCCESS) { /* Indicate the IO is not being aborted by the driver. */ lpfc_cmd->waitq = NULL; - spin_unlock(&lpfc_cmd->buf_lock); - spin_unlock_irqrestore(&phba->hbalock, flags); ret = FAILED; - goto out; + goto out_unlock_hba; }
/* no longer need the lock after this point */ - spin_unlock(&lpfc_cmd->buf_lock); - spin_unlock_irqrestore(&phba->hbalock, flags); + spin_unlock(&phba->hbalock); + spin_unlock_irqrestore(&lpfc_cmd->buf_lock, flags);
if (phba->cfg_poll & DISABLE_FCP_RING_INT) lpfc_sli_handle_fast_ring_event(phba, @@ -5988,10 +5986,9 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) out_unlock_ring: if (phba->sli_rev == LPFC_SLI_REV4) spin_unlock(&pring_s4->ring_lock); -out_unlock_buf: - spin_unlock(&lpfc_cmd->buf_lock); -out_unlock: - spin_unlock_irqrestore(&phba->hbalock, flags); +out_unlock_hba: + spin_unlock(&phba->hbalock); + spin_unlock_irqrestore(&lpfc_cmd->buf_lock, flags); out: lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "0749 SCSI Layer I/O Abort Request Status x%x ID %d "
From: James Smart jsmart2021@gmail.com
[ Upstream commit 577a942df3de2666f6947bdd3a5c9e8d30073424 ]
If lpfc_issue_els_flogi() fails and returns non-zero status, the node reference count is decremented to trigger the release of the nodelist structure. However, if there is a prior registration or dev-loss-evt work pending, the node may be released prematurely. When dev-loss-evt completes, the released node is referenced causing a use-after-free null pointer dereference.
Similarly, when processing non-zero ELS PLOGI completion status in lpfc_cmpl_els_plogi(), the ndlp flags are checked for a transport registration before triggering node removal. If dev-loss-evt work is pending, the node may be released prematurely and a subsequent call to lpfc_dev_loss_tmo_handler() results in a use after free ndlp dereference.
Add test for pending dev-loss before decrementing the node reference count for FLOGI, PLOGI, PRLI, and ADISC handling.
Link: https://lore.kernel.org/r/20220412222008.126521-9-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_els.c | 51 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 16 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 872a26376ccb..46a01a51b207 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1532,10 +1532,13 @@ lpfc_initial_flogi(struct lpfc_vport *vport) }
if (lpfc_issue_els_flogi(vport, ndlp, 0)) { - /* This decrement of reference count to node shall kick off - * the release of the node. + /* A node reference should be retained while registered with a + * transport or dev-loss-evt work is pending. + * Otherwise, decrement node reference to trigger release. */ - lpfc_nlp_put(ndlp); + if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) && + !(ndlp->nlp_flag & NLP_IN_DEV_LOSS)) + lpfc_nlp_put(ndlp); return 0; } return 1; @@ -1578,10 +1581,13 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) }
if (lpfc_issue_els_fdisc(vport, ndlp, 0)) { - /* decrement node reference count to trigger the release of - * the node. + /* A node reference should be retained while registered with a + * transport or dev-loss-evt work is pending. + * Otherwise, decrement node reference to trigger release. */ - lpfc_nlp_put(ndlp); + if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) && + !(ndlp->nlp_flag & NLP_IN_DEV_LOSS)) + lpfc_nlp_put(ndlp); return 0; } return 1; @@ -1983,6 +1989,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, int disc; struct serv_parm *sp = NULL; u32 ulp_status, ulp_word4, did, iotag; + bool release_node = false;
/* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; @@ -2071,19 +2078,21 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, spin_unlock_irq(&ndlp->lock); goto out; } - spin_unlock_irq(&ndlp->lock);
/* No PLOGI collision and the node is not registered with the * scsi or nvme transport. It is no longer an active node. Just * start the device remove process. */ if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) { - spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; - spin_unlock_irq(&ndlp->lock); + if (!(ndlp->nlp_flag & NLP_IN_DEV_LOSS)) + release_node = true; + } + spin_unlock_irq(&ndlp->lock); + + if (release_node) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); - } } else { /* Good status, call state machine */ prsp = list_entry(((struct lpfc_dmabuf *) @@ -2294,6 +2303,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, u32 loglevel; u32 ulp_status; u32 ulp_word4; + bool release_node = false;
/* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; @@ -2370,14 +2380,18 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * it is no longer an active node. Otherwise devloss * handles the final cleanup. */ + spin_lock_irq(&ndlp->lock); if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) && !ndlp->fc4_prli_sent) { - spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; - spin_unlock_irq(&ndlp->lock); + if (!(ndlp->nlp_flag & NLP_IN_DEV_LOSS)) + release_node = true; + } + spin_unlock_irq(&ndlp->lock); + + if (release_node) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); - } } else { /* Good status, call state machine. However, if another * PRLI is outstanding, don't call the state machine @@ -2749,6 +2763,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_nodelist *ndlp; int disc; u32 ulp_status, ulp_word4, tmo; + bool release_node = false;
/* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; @@ -2815,13 +2830,17 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * transport, it is no longer an active node. Otherwise * devloss handles the final cleanup. */ + spin_lock_irq(&ndlp->lock); if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) { - spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; - spin_unlock_irq(&ndlp->lock); + if (!(ndlp->nlp_flag & NLP_IN_DEV_LOSS)) + release_node = true; + } + spin_unlock_irq(&ndlp->lock); + + if (release_node) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); - } } else /* Good status, call state machine */ lpfc_disc_state_machine(vport, ndlp, cmdiocb,
From: James Smart jsmart2021@gmail.com
[ Upstream commit 672d1cb40551ea9c95efad43ab6d45e4ab4e015f ]
There is a potential memory leak in lpfc_ignore_els_cmpl() and lpfc_els_rsp_reject() that was allocated from NPIV PLOGI_RJT (lpfc_rcv_plogi()'s login_mbox).
Check if cmdiocb->context_un.mbox was allocated in lpfc_ignore_els_cmpl(), and then free it back to phba->mbox_mem_pool along with mbox->ctx_buf for service parameters.
For lpfc_els_rsp_reject() failure, free both the ctx_buf for service parameters and the login_mbox.
Link: https://lore.kernel.org/r/20220412222008.126521-10-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_nportdisc.c | 10 ++++++++-- drivers/scsi/lpfc/lpfc_sli.c | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index c4e1a07066a2..4b065c51ee1b 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -614,9 +614,15 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, - ndlp, login_mbox); - if (rc) + ndlp, login_mbox); + if (rc) { + mp = (struct lpfc_dmabuf *)login_mbox->ctx_buf; + if (mp) { + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + } mempool_free(login_mbox, phba->mbox_mem_pool); + } return 1; }
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 6adaf79e67cc..09a45f8ecf3f 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12066,6 +12066,8 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, { struct lpfc_nodelist *ndlp = NULL; IOCB_t *irsp; + LPFC_MBOXQ_t *mbox; + struct lpfc_dmabuf *mp; u32 ulp_command, ulp_status, ulp_word4, iotag;
ulp_command = get_job_cmnd(phba, cmdiocb); @@ -12077,6 +12079,21 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } else { irsp = &rspiocb->iocb; iotag = irsp->ulpIoTag; + + /* It is possible a PLOGI_RJT for NPIV ports to get aborted. + * The MBX_REG_LOGIN64 mbox command is freed back to the + * mbox_mem_pool here. + */ + if (cmdiocb->context_un.mbox) { + mbox = cmdiocb->context_un.mbox; + mp = (struct lpfc_dmabuf *)mbox->ctx_buf; + if (mp) { + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + } + mempool_free(mbox, phba->mbox_mem_pool); + cmdiocb->context_un.mbox = NULL; + } }
/* ELS cmd tag <ulpIoTag> completes */
From: James Smart jsmart2021@gmail.com
[ Upstream commit d6d45f67a11136cb88a70a29ab22ea6db8ae6bd5 ]
The following was seen with CMF enabled:
BUG: using smp_processor_id() in preemptible code: systemd-udevd/31711 kernel: caller is lpfc_update_cmf_cmd+0x214/0x420 [lpfc] kernel: CPU: 12 PID: 31711 Comm: systemd-udevd kernel: Call Trace: kernel: <TASK> kernel: dump_stack_lvl+0x44/0x57 kernel: check_preemption_disabled+0xbf/0xe0 kernel: lpfc_update_cmf_cmd+0x214/0x420 [lpfc] kernel: lpfc_nvme_fcp_io_submit+0x23b4/0x4df0 [lpfc]
this_cpu_ptr() calls smp_processor_id() in a preemptible context.
Fix by using per_cpu_ptr() with raw_smp_processor_id() instead.
Link: https://lore.kernel.org/r/20220412222008.126521-16-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c4fa7d68fe03..f617a2ef6b0f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -3835,7 +3835,7 @@ lpfc_update_cmf_cmpl(struct lpfc_hba *phba, else time = div_u64(time + 500, 1000); /* round it */
- cgs = this_cpu_ptr(phba->cmf_stat); + cgs = per_cpu_ptr(phba->cmf_stat, raw_smp_processor_id()); atomic64_add(size, &cgs->rcv_bytes); atomic64_add(time, &cgs->rx_latency); atomic_inc(&cgs->rx_io_cnt); @@ -3879,7 +3879,7 @@ lpfc_update_cmf_cmd(struct lpfc_hba *phba, uint32_t size) atomic_set(&phba->rx_max_read_cnt, size); }
- cgs = this_cpu_ptr(phba->cmf_stat); + cgs = per_cpu_ptr(phba->cmf_stat, raw_smp_processor_id()); atomic64_add(size, &cgs->total_bytes); return 0; }
From: Ulf Hansson ulf.hansson@linaro.org
[ Upstream commit 171b66e2e2e9d80b93c8cff799e6175074b22297 ]
When PSCI OSI mode is supported the syscore flag is set for the CPU devices that becomes attached to their PM domains (genpds). In the suspend-to-idle case, we call dev_pm_genpd_suspend|resume() to allow genpd to properly manage the power-off/on operations (pick an idlestate and manage the on/off notifications).
For suspend-to-ram, dev_pm_genpd_suspend|resume() is currently not being called, which causes a problem that the genpd on/off notifiers do not get sent as expected. This prevents the platform-specific operations from being executed, typically needed just before/after the boot CPU is being turned off/on.
To deal with this problem, let's register a syscore ops for cpuidle-psci when PSCI OSI mode is being used and call dev_pm_genpd_suspend|resume() from them. In this way, genpd regains control of the PM domain topology and then sends the on/off notifications when it's appropriate.
Reported-by: Maulik Shah quic_mkshah@quicinc.com Suggested-by: Maulik Shah quic_mkshah@quicinc.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Tested-by: Maulik Shah quic_mkshah@quicinc.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle-psci.c | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index b51b5df08450..540105ca0781 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -23,6 +23,7 @@ #include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/string.h> +#include <linux/syscore_ops.h>
#include <asm/cpuidle.h>
@@ -131,6 +132,49 @@ static int psci_idle_cpuhp_down(unsigned int cpu) return 0; }
+static void psci_idle_syscore_switch(bool suspend) +{ + bool cleared = false; + struct device *dev; + int cpu; + + for_each_possible_cpu(cpu) { + dev = per_cpu_ptr(&psci_cpuidle_data, cpu)->dev; + + if (dev && suspend) { + dev_pm_genpd_suspend(dev); + } else if (dev) { + dev_pm_genpd_resume(dev); + + /* Account for userspace having offlined a CPU. */ + if (pm_runtime_status_suspended(dev)) + pm_runtime_set_active(dev); + + /* Clear domain state to re-start fresh. */ + if (!cleared) { + psci_set_domain_state(0); + cleared = true; + } + } + } +} + +static int psci_idle_syscore_suspend(void) +{ + psci_idle_syscore_switch(true); + return 0; +} + +static void psci_idle_syscore_resume(void) +{ + psci_idle_syscore_switch(false); +} + +static struct syscore_ops psci_idle_syscore_ops = { + .suspend = psci_idle_syscore_suspend, + .resume = psci_idle_syscore_resume, +}; + static void psci_idle_init_cpuhp(void) { int err; @@ -138,6 +182,8 @@ static void psci_idle_init_cpuhp(void) if (!psci_cpuidle_use_cpuhp) return;
+ register_syscore_ops(&psci_idle_syscore_ops); + err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING, "cpuidle/psci:online", psci_idle_cpuhp_up,
From: Huang Rui ray.huang@amd.com
[ Upstream commit eea5c7b3390c6e006ba4cbd906447dd8cea8cfbf ]
It needs to check if the pp_funcs is initialized while release the context, otherwise it will trigger null pointer panic while the software smu is not enabled.
[ 1109.404555] BUG: kernel NULL pointer dereference, address: 0000000000000078 [ 1109.404609] #PF: supervisor read access in kernel mode [ 1109.404638] #PF: error_code(0x0000) - not-present page [ 1109.404657] PGD 0 P4D 0 [ 1109.404672] Oops: 0000 [#1] PREEMPT SMP NOPTI [ 1109.404701] CPU: 7 PID: 9150 Comm: amdgpu_test Tainted: G OEL 5.16.0-custom #1 [ 1109.404732] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 1109.404765] RIP: 0010:amdgpu_dpm_force_performance_level+0x1d/0x170 [amdgpu] [ 1109.405109] Code: 5d c3 44 8b a3 f0 80 00 00 eb e5 66 90 0f 1f 44 00 00 55 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 08 4c 8b b7 f0 7d 00 00 <49> 83 7e 78 00 0f 84 f2 00 00 00 80 bf 87 80 00 00 00 48 89 fb 0f [ 1109.405176] RSP: 0018:ffffaf3083ad7c20 EFLAGS: 00010282 [ 1109.405203] RAX: 0000000000000000 RBX: ffff9796b1c14600 RCX: 0000000002862007 [ 1109.405229] RDX: ffff97968591c8c0 RSI: 0000000000000001 RDI: ffff9796a3700000 [ 1109.405260] RBP: ffffaf3083ad7c50 R08: ffffffff9897de00 R09: ffff979688d9db60 [ 1109.405286] R10: 0000000000000000 R11: ffff979688d9db90 R12: 0000000000000001 [ 1109.405316] R13: ffff9796a3700000 R14: 0000000000000000 R15: ffff9796a3708fc0 [ 1109.405345] FS: 00007ff055cff180(0000) GS:ffff9796bfdc0000(0000) knlGS:0000000000000000 [ 1109.405378] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1109.405400] CR2: 0000000000000078 CR3: 000000000a394000 CR4: 00000000000506e0 [ 1109.405434] Call Trace: [ 1109.405445] <TASK> [ 1109.405456] ? delete_object_full+0x1d/0x20 [ 1109.405480] amdgpu_ctx_set_stable_pstate+0x7c/0xa0 [amdgpu] [ 1109.405698] amdgpu_ctx_fini.part.0+0xcb/0x100 [amdgpu] [ 1109.405911] amdgpu_ctx_do_release+0x71/0x80 [amdgpu] [ 1109.406121] amdgpu_ctx_ioctl+0x52d/0x550 [amdgpu] [ 1109.406327] ? _raw_spin_unlock+0x1a/0x30 [ 1109.406354] ? drm_gem_handle_delete+0x81/0xb0 [drm] [ 1109.406400] ? amdgpu_ctx_get_entity+0x2c0/0x2c0 [amdgpu] [ 1109.406609] drm_ioctl_kernel+0xb6/0x140 [drm]
Signed-off-by: Huang Rui ray.huang@amd.com Reviewed-by: Aaron Liu aaron.liu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c index 72e7b5d40af6..5472f9936feb 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -790,7 +790,7 @@ int amdgpu_dpm_force_performance_level(struct amdgpu_device *adev, AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK | AMD_DPM_FORCED_LEVEL_PROFILE_PEAK;
- if (!pp_funcs->force_performance_level) + if (!pp_funcs || !pp_funcs->force_performance_level) return 0;
if (adev->pm.dpm.thermal_active)
From: Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp
[ Upstream commit f3fa2becf2fc25b6ac7cf8d8b1a2e4a86b3b72bd ]
In function si_parse_power_table(), array adev->pm.dpm.ps and its member is allocated. If the allocation of each member fails, the array itself is freed and returned with an error code. However, the array is later freed again in si_dpm_fini() function which is called when the function returns an error.
This leads to potential double free of the array adev->pm.dpm.ps, as well as leak of its array members, since the members are not freed in the allocation function and the array is not nulled when freed. In addition adev->pm.dpm.num_ps, which keeps track of the allocated array member, is not updated until the member allocation is successfully finished, this could also lead to either use after free, or uninitialized variable access in si_dpm_fini().
Fix this by postponing the free of the array until si_dpm_fini() and increment adev->pm.dpm.num_ps everytime the array member is allocated.
Signed-off-by: Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index 633dab14f51c..49c398ec0aaf 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -7297,17 +7297,15 @@ static int si_parse_power_table(struct amdgpu_device *adev) if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; - for (i = 0; i < state_array->ucNumEntries; i++) { + for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) { u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; ps = kzalloc(sizeof(struct si_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(adev->pm.dpm.ps); + if (ps == NULL) return -ENOMEM; - } adev->pm.dpm.ps[i].ps_priv = ps; si_parse_pplib_non_clock_info(adev, &adev->pm.dpm.ps[i], non_clock_info, @@ -7329,8 +7327,8 @@ static int si_parse_power_table(struct amdgpu_device *adev) k++; } power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + adev->pm.dpm.num_ps++; } - adev->pm.dpm.num_ps = state_array->ucNumEntries;
/* fill in the vce power states */ for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
[ Upstream commit b1384d4c95088d01f4266237faabf165d3d605fc ]
commit cfb7b8bf1e2d66 ("ASoC: rsnd: tidyup rsnd_ssiu_busif_err_status_clear()") merged duplicate code, but it didn't care about default case, and causes smatch warnings.
smatch warnings: sound/soc/sh/rcar/ssiu.c:112 rsnd_ssiu_busif_err_status_clear() \ error: uninitialized symbol 'offset'. sound/soc/sh/rcar/ssiu.c:114 rsnd_ssiu_busif_err_status_clear() \ error: uninitialized symbol 'shift'.
This patch cares it.
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87r15rgn6p.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sh/rcar/ssiu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 0d8f97633dd2..138f95dd9f4a 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -102,6 +102,8 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod) shift = 1; offset = 1; break; + default: + goto out; }
for (i = 0; i < 4; i++) { @@ -120,7 +122,7 @@ bool rsnd_ssiu_busif_err_status_clear(struct rsnd_mod *mod) } rsnd_mod_write(mod, reg, val); } - +out: return error; }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
[ Upstream commit d09a7db431c65aaa8303eb456439d1831ca2e6b4 ]
Renesas Sound is very complex, and thus it needs to use rsnd_node_fixed_index() to know enabled pin index.
It returns error if strange pin was selected, but some codes didn't check it.
This patch 1) indicates error message, 2) check return value.
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87pmlbgn5t.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sh/rcar/core.c | 15 ++++++++++----- sound/soc/sh/rcar/dma.c | 9 ++++++++- sound/soc/sh/rcar/rsnd.h | 2 +- sound/soc/sh/rcar/src.c | 7 ++++++- sound/soc/sh/rcar/ssi.c | 14 ++++++++++++-- sound/soc/sh/rcar/ssiu.c | 7 ++++++- 6 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 6a8fe0da7670..af8ef2a27d34 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1159,6 +1159,7 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, struct device_node *capture) { struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct device *dev = rsnd_priv_to_dev(priv); struct device_node *np; int i;
@@ -1169,7 +1170,11 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, for_each_child_of_node(node, np) { struct rsnd_mod *mod;
- i = rsnd_node_fixed_index(np, name, i); + i = rsnd_node_fixed_index(dev, np, name, i); + if (i < 0) { + of_node_put(np); + break; + }
mod = mod_get(priv, i);
@@ -1183,7 +1188,7 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, of_node_put(node); }
-int rsnd_node_fixed_index(struct device_node *node, char *name, int idx) +int rsnd_node_fixed_index(struct device *dev, struct device_node *node, char *name, int idx) { char node_name[16];
@@ -1210,6 +1215,8 @@ int rsnd_node_fixed_index(struct device_node *node, char *name, int idx) return idx; }
+ dev_err(dev, "strange node numbering (%s)", + of_node_full_name(node)); return -EINVAL; }
@@ -1221,10 +1228,8 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name
i = 0; for_each_child_of_node(node, np) { - i = rsnd_node_fixed_index(np, name, i); + i = rsnd_node_fixed_index(dev, np, name, i); if (i < 0) { - dev_err(dev, "strange node numbering (%s)", - of_node_full_name(node)); of_node_put(np); return 0; } diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 03e0d4eca781..463ab237d7bd 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -240,12 +240,19 @@ static int rsnd_dmaen_start(struct rsnd_mod *mod, struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node, char *name, struct rsnd_mod *mod, char *x) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); struct dma_chan *chan = NULL; struct device_node *np; int i = 0;
for_each_child_of_node(of_node, np) { - i = rsnd_node_fixed_index(np, name, i); + i = rsnd_node_fixed_index(dev, np, name, i); + if (i < 0) { + chan = NULL; + of_node_put(np); + break; + }
if (i == rsnd_mod_id_raw(mod) && (!chan)) chan = of_dma_request_slave_channel(np, x); diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 6580bab0e229..d9cd190d7e19 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -460,7 +460,7 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, char *name, struct device_node *playback, struct device_node *capture); int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name); -int rsnd_node_fixed_index(struct device_node *node, char *name, int idx); +int rsnd_node_fixed_index(struct device *dev, struct device_node *node, char *name, int idx);
int rsnd_channel_normalization(int chan); #define rsnd_runtime_channel_original(io) \ diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 42a100c6303d..0ea84ae57c6a 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -676,7 +676,12 @@ int rsnd_src_probe(struct rsnd_priv *priv) if (!of_device_is_available(np)) goto skip;
- i = rsnd_node_fixed_index(np, SRC_NAME, i); + i = rsnd_node_fixed_index(dev, np, SRC_NAME, i); + if (i < 0) { + ret = -EINVAL; + of_node_put(np); + goto rsnd_src_probe_done; + }
src = rsnd_src_get(priv, i);
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 87e606f688d3..43c5e27dc5c8 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -1105,6 +1105,7 @@ void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, struct device_node *capture) { struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct device *dev = rsnd_priv_to_dev(priv); struct device_node *node; struct device_node *np; int i; @@ -1117,7 +1118,11 @@ void rsnd_parse_connect_ssi(struct rsnd_dai *rdai, for_each_child_of_node(node, np) { struct rsnd_mod *mod;
- i = rsnd_node_fixed_index(np, SSI_NAME, i); + i = rsnd_node_fixed_index(dev, np, SSI_NAME, i); + if (i < 0) { + of_node_put(np); + break; + }
mod = rsnd_ssi_mod_get(priv, i);
@@ -1182,7 +1187,12 @@ int rsnd_ssi_probe(struct rsnd_priv *priv) if (!of_device_is_available(np)) goto skip;
- i = rsnd_node_fixed_index(np, SSI_NAME, i); + i = rsnd_node_fixed_index(dev, np, SSI_NAME, i); + if (i < 0) { + ret = -EINVAL; + of_node_put(np); + goto rsnd_ssi_probe_done; + }
ssi = rsnd_ssi_get(priv, i);
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 138f95dd9f4a..4b8a63e336c7 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -462,6 +462,7 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai, struct device_node *capture) { struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); + struct device *dev = rsnd_priv_to_dev(priv); struct device_node *node = rsnd_ssiu_of_node(priv); struct rsnd_dai_stream *io_p = &rdai->playback; struct rsnd_dai_stream *io_c = &rdai->capture; @@ -474,7 +475,11 @@ void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai, for_each_child_of_node(node, np) { struct rsnd_mod *mod;
- i = rsnd_node_fixed_index(np, SSIU_NAME, i); + i = rsnd_node_fixed_index(dev, np, SSIU_NAME, i); + if (i < 0) { + of_node_put(np); + break; + }
mod = rsnd_ssiu_mod_get(priv, i);
From: Radhey Shyam Pandey radhey.shyam.pandey@xilinx.com
[ Upstream commit 29e96fe9e0ec0f0fe1dd306a4ccb7b8983eae67a ]
In the macb binding documentation "phys" is an optional property. Make implementation in line with it. This change allows the traditional flow in which first stage bootloader does PS-GT configuration to work along with newer use cases in which PS-GT configuration is managed by the phy-zynqmp driver.
It fixes below macb probe failure when macb DT node doesn't have SGMII phys handle. "macb ff0b0000.ethernet: error -ENODEV: failed to get PS-GTR PHY"
Signed-off-by: Radhey Shyam Pandey radhey.shyam.pandey@xilinx.com Reviewed-by: Michal Simek michal.simek@xilinx.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/cadence/macb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 61284baa0496..ed7c2c2c4401 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -4594,7 +4594,7 @@ static int zynqmp_init(struct platform_device *pdev)
if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) { /* Ensure PS-GTR PHY device used in SGMII mode is ready */ - bp->sgmii_phy = devm_phy_get(&pdev->dev, "sgmii-phy"); + bp->sgmii_phy = devm_phy_optional_get(&pdev->dev, NULL);
if (IS_ERR(bp->sgmii_phy)) { ret = PTR_ERR(bp->sgmii_phy);
From: Thibaut VARÈNE hacks+kernel@slashdirt.org
[ Upstream commit e999a5da28a0e0f7de242d841ef7d5e48f4646ae ]
This patch fixes an invalid TX PA DC bias level on QCA9561, which results in a very low output power and very low throughput as devices are further away from the AP (compared to other 2.4GHz APs).
This patch was suggested by Felix Fietkau, who noted[1]: "The value written to that register is wrong, because while the mask definition AR_CH0_TOP2_XPABIASLVL uses a different value for 9561, the shift definition AR_CH0_TOP2_XPABIASLVL_S is hardcoded to 12, which is wrong for 9561."
In real life testing, without this patch the 2.4GHz throughput on Yuncore XD3200 is around 10Mbps sitting next to the AP, and closer to practical maximum with the patch applied.
[1] https://lore.kernel.org/all/91c58969-c60e-2f41-00ac-737786d435ae@nbd.name
Signed-off-by: Thibaut VARÈNE hacks+kernel@slashdirt.org Acked-by: Felix Fietkau nbd@nbd.name 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/20220417145145.1847-1-hacks+kernel@slashdirt.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/ar9003_phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index a171dbb29fbb..ad949eb02f3d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -720,7 +720,7 @@ #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) #define AR_CH0_TOP2_XPABIASLVL (AR_SREV_9561(ah) ? 0x1e00 : 0xf000) -#define AR_CH0_TOP2_XPABIASLVL_S 12 +#define AR_CH0_TOP2_XPABIASLVL_S (AR_SREV_9561(ah) ? 9 : 12)
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : \
From: Sakari Ailus sakari.ailus@linux.intel.com
[ Upstream commit 7dd0f93a31af03cba81c684c4c361bba510ffe71 ]
This reverts commit c09d776eaa060534a1663e3b89d842db3e1d9076.
Revert the commit as it breaks runtime PM support on OF based systems. More fixes to the driver are needed.
Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Reviewed-by: Tomasz Figa tfiga@chromium.org Reviewed-by: Bingbu Cao bingbu.cao@intel.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/dw9768.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c index 65c6acf3ced9..c086580efac7 100644 --- a/drivers/media/i2c/dw9768.c +++ b/drivers/media/i2c/dw9768.c @@ -469,11 +469,6 @@ static int dw9768_probe(struct i2c_client *client)
dw9768->sd.entity.function = MEDIA_ENT_F_LENS;
- /* - * Device is already turned on by i2c-core with ACPI domain PM. - * Attempt to turn off the device to satisfy the privacy LED concerns. - */ - pm_runtime_set_active(dev); pm_runtime_enable(dev); if (!pm_runtime_enabled(dev)) { ret = dw9768_runtime_resume(dev); @@ -488,7 +483,6 @@ static int dw9768_probe(struct i2c_client *client) dev_err(dev, "failed to register V4L2 subdev: %d", ret); goto err_power_off; } - pm_runtime_idle(dev);
return 0;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 02276e18defa2fccf16413b44440277d98c2b1ea ]
When the driver fails to probe, we will get the following splat:
[ 59.305988] ------------[ cut here ]------------ [ 59.306417] WARNING: CPU: 2 PID: 395 at drivers/regulator/core.c:2257 _regulator_put+0x3ec/0x4e0 [ 59.310345] RIP: 0010:_regulator_put+0x3ec/0x4e0 [ 59.318362] Call Trace: [ 59.318582] <TASK> [ 59.318765] regulator_put+0x1f/0x30 [ 59.319058] devres_release_group+0x319/0x3d0 [ 59.319420] i2c_device_probe+0x766/0x940
Fix this by disabling the regulator in error handling.
Signed-off-by: Zheyu Ma zheyuma97@gmail.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/dw9714.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c index cd7008ad8f2f..8c5797ba57d4 100644 --- a/drivers/media/i2c/dw9714.c +++ b/drivers/media/i2c/dw9714.c @@ -183,6 +183,7 @@ static int dw9714_probe(struct i2c_client *client) return 0;
err_cleanup: + regulator_disable(dw9714_dev->vcc); v4l2_ctrl_handler_free(&dw9714_dev->ctrls_vcm); media_entity_cleanup(&dw9714_dev->sd.entity);
From: Luca Weiss luca.weiss@fairphone.com
[ Upstream commit 86594f6af867b5165d2ba7b5a71fae3a5961e56c ]
If venus_probe fails at pm_runtime_put_sync the error handling first calls hfi_destroy and afterwards hfi_core_deinit. As hfi_destroy sets core->ops to NULL, hfi_core_deinit cannot call the core_deinit function anymore.
Avoid this null pointer derefence by skipping the call when necessary.
Signed-off-by: Luca Weiss luca.weiss@fairphone.com Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/hfi.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c index 4e2151fb47f0..1968f09ad177 100644 --- a/drivers/media/platform/qcom/venus/hfi.c +++ b/drivers/media/platform/qcom/venus/hfi.c @@ -104,6 +104,9 @@ int hfi_core_deinit(struct venus_core *core, bool blocking) mutex_lock(&core->lock); }
+ if (!core->ops) + goto unlock; + ret = core->ops->core_deinit(core);
if (!ret)
From: Vikash Garodia quic_vgarodia@quicinc.com
[ Upstream commit 73664f107c0fafb59cd91e576b81c986adb74610 ]
During reconfig (DRC) event from firmware, it is not guaranteed that all the DPB(internal) buffers would be released by the firmware. Some buffers might be released gradually while processing frames from the new sequence. These buffers now stay idle in the dpblist. In subsequent call to queue the DPBs to firmware, these idle buffers should not be queued. The fix identifies those buffers and free them.
Signed-off-by: Vikash Garodia quic_vgarodia@quicinc.com Tested-by: Fritz Koenig frkoenig@chromium.org Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/helpers.c | 34 +++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 0bca95d01650..fa01edd54c03 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -90,12 +90,28 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) } EXPORT_SYMBOL_GPL(venus_helper_check_codec);
+static void free_dpb_buf(struct venus_inst *inst, struct intbuf *buf) +{ + ida_free(&inst->dpb_ids, buf->dpb_out_tag); + + list_del_init(&buf->list); + dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, + buf->attrs); + kfree(buf); +} + int venus_helper_queue_dpb_bufs(struct venus_inst *inst) { - struct intbuf *buf; + struct intbuf *buf, *next; + unsigned int dpb_size = 0; int ret = 0;
- list_for_each_entry(buf, &inst->dpbbufs, list) { + if (inst->dpb_buftype == HFI_BUFFER_OUTPUT) + dpb_size = inst->output_buf_size; + else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2) + dpb_size = inst->output2_buf_size; + + list_for_each_entry_safe(buf, next, &inst->dpbbufs, list) { struct hfi_frame_data fdata;
memset(&fdata, 0, sizeof(fdata)); @@ -106,6 +122,12 @@ int venus_helper_queue_dpb_bufs(struct venus_inst *inst) if (buf->owned_by == FIRMWARE) continue;
+ /* free buffer from previous sequence which was released later */ + if (dpb_size > buf->size) { + free_dpb_buf(inst, buf); + continue; + } + fdata.clnt_data = buf->dpb_out_tag;
ret = hfi_session_process_buf(inst, &fdata); @@ -127,13 +149,7 @@ int venus_helper_free_dpb_bufs(struct venus_inst *inst) list_for_each_entry_safe(buf, n, &inst->dpbbufs, list) { if (buf->owned_by == FIRMWARE) continue; - - ida_free(&inst->dpb_ids, buf->dpb_out_tag); - - list_del_init(&buf->list); - dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, - buf->attrs); - kfree(buf); + free_dpb_buf(inst, buf); }
if (list_empty(&inst->dpbbufs))
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit e8123311cf06d7dae71e8c5fe78e0510d20cd30b ]
When the driver fails to call the dma_set_mask(), the driver will get the following splat:
[ 55.853884] BUG: KASAN: use-after-free in __process_removed_driver+0x3c/0x240 [ 55.854486] Read of size 8 at addr ffff88810de60408 by task modprobe/590 [ 55.856822] Call Trace: [ 55.860327] __process_removed_driver+0x3c/0x240 [ 55.861347] bus_for_each_dev+0x102/0x160 [ 55.861681] i2c_del_driver+0x2f/0x50
This is because the driver has initialized the i2c related resources in cx23885_dev_setup() but not released them in error handling, fix this bug by modifying the error path that jumps after failing to call the dma_set_mask().
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/cx23885/cx23885-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index f8f2ff3b00c3..a07b18f2034e 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2165,7 +2165,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev, err = dma_set_mask(&pci_dev->dev, 0xffffffff); if (err) { pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); - goto fail_ctrl; + goto fail_dma_set_mask; }
err = request_irq(pci_dev->irq, cx23885_irq, @@ -2173,7 +2173,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev, if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); - goto fail_irq; + goto fail_dma_set_mask; }
switch (dev->board) { @@ -2195,7 +2195,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev,
return 0;
-fail_irq: +fail_dma_set_mask: cx23885_dev_unregister(dev); fail_ctrl: v4l2_ctrl_handler_free(hdl);
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 2203436a4d24302871617373a7eb21bc17e38762 ]
When removing the module, we will get the following warning:
[ 14.746697] remove_proc_entry: removing non-empty directory 'irq/21', leaking at least 'cx25821[1]' [ 14.747449] WARNING: CPU: 4 PID: 368 at fs/proc/generic.c:717 remove_proc_entry+0x389/0x3f0 [ 14.751611] RIP: 0010:remove_proc_entry+0x389/0x3f0 [ 14.759589] Call Trace: [ 14.759792] <TASK> [ 14.759975] unregister_irq_proc+0x14c/0x170 [ 14.760340] irq_free_descs+0x94/0xe0 [ 14.760640] mp_unmap_irq+0xb6/0x100 [ 14.760937] acpi_unregister_gsi_ioapic+0x27/0x40 [ 14.761334] acpi_pci_irq_disable+0x1d3/0x320 [ 14.761688] pci_disable_device+0x1ad/0x380 [ 14.762027] ? _raw_spin_unlock_irqrestore+0x2d/0x60 [ 14.762442] ? cx25821_shutdown+0x20/0x9f0 [cx25821] [ 14.762848] cx25821_finidev+0x48/0xc0 [cx25821] [ 14.763242] pci_device_remove+0x92/0x240
Fix this by freeing the irq before call pci_disable_device().
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/cx25821/cx25821-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index 3078a39f0b95..6627fa9166d3 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -1332,11 +1332,11 @@ static void cx25821_finidev(struct pci_dev *pci_dev) struct cx25821_dev *dev = get_cx25821(v4l2_dev);
cx25821_shutdown(dev); - pci_disable_device(pci_dev);
/* unregister stuff */ if (pci_dev->irq) free_irq(pci_dev->irq, dev); + pci_disable_device(pci_dev);
cx25821_dev_unregister(dev); v4l2_device_unregister(v4l2_dev);
From: Heming Zhao heming.zhao@suse.com
[ Upstream commit e68cb83a57a458b01c9739e2ad9cb70b04d1e6d2 ]
If bitmap area contains invalid data, kernel will crash then mdadm triggers "Segmentation fault". This is cluster-md speical bug. In non-clustered env, mdadm will handle broken metadata case. In clustered array, only kernel space handles bitmap slot info. But even this bug only happened in clustered env, current sanity check is wrong, the code should be changed.
How to trigger: (faulty injection)
dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sda dd if=/dev/zero bs=1M count=1 oflag=direct of=/dev/sdb mdadm -C /dev/md0 -b clustered -e 1.2 -n 2 -l mirror /dev/sda /dev/sdb mdadm -Ss echo aaa > magic.txt == below modifying slot 2 bitmap data == dd if=magic.txt of=/dev/sda seek=16384 bs=1 count=3 <== destroy magic dd if=/dev/zero of=/dev/sda seek=16436 bs=1 count=4 <== ZERO chunksize mdadm -A /dev/md0 /dev/sda /dev/sdb == kernel crashes. mdadm outputs "Segmentation fault" ==
Reason of kernel crash:
In md_bitmap_read_sb (called by md_bitmap_create), bad bitmap magic didn't block chunksize assignment, and zero value made DIV_ROUND_UP_SECTOR_T() trigger "divide error".
Crash log:
kernel: md: md0 stopped. kernel: md/raid1:md0: not clean -- starting background reconstruction kernel: md/raid1:md0: active with 2 out of 2 mirrors kernel: dlm: ... ... kernel: md-cluster: Joined cluster 44810aba-38bb-e6b8-daca-bc97a0b254aa slot 1 kernel: md0: invalid bitmap file superblock: bad magic kernel: md_bitmap_copy_from_slot can't get bitmap from slot 2 kernel: md-cluster: Could not gather bitmaps from slot 2 kernel: divide error: 0000 [#1] SMP NOPTI kernel: CPU: 0 PID: 1603 Comm: mdadm Not tainted 5.14.6-1-default kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) kernel: RIP: 0010:md_bitmap_create+0x1d1/0x850 [md_mod] kernel: RSP: 0018:ffffc22ac0843ba0 EFLAGS: 00010246 kernel: ... ... kernel: Call Trace: kernel: ? dlm_lock_sync+0xd0/0xd0 [md_cluster 77fe..7a0] kernel: md_bitmap_copy_from_slot+0x2c/0x290 [md_mod 24ea..d3a] kernel: load_bitmaps+0xec/0x210 [md_cluster 77fe..7a0] kernel: md_bitmap_load+0x81/0x1e0 [md_mod 24ea..d3a] kernel: do_md_run+0x30/0x100 [md_mod 24ea..d3a] kernel: md_ioctl+0x1290/0x15a0 [md_mod 24ea....d3a] kernel: ? mddev_unlock+0xaa/0x130 [md_mod 24ea..d3a] kernel: ? blkdev_ioctl+0xb1/0x2b0 kernel: block_ioctl+0x3b/0x40 kernel: __x64_sys_ioctl+0x7f/0xb0 kernel: do_syscall_64+0x59/0x80 kernel: ? exit_to_user_mode_prepare+0x1ab/0x230 kernel: ? syscall_exit_to_user_mode+0x18/0x40 kernel: ? do_syscall_64+0x69/0x80 kernel: entry_SYSCALL_64_after_hwframe+0x44/0xae kernel: RIP: 0033:0x7f4a15fa722b kernel: ... ... kernel: ---[ end trace 8afa7612f559c868 ]--- kernel: RIP: 0010:md_bitmap_create+0x1d1/0x850 [md_mod]
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Guoqing Jiang guoqing.jiang@linux.dev Signed-off-by: Heming Zhao heming.zhao@suse.com Signed-off-by: Song Liu song@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md-bitmap.c | 44 ++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index bfd6026d7809..612460d2bdaf 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -639,14 +639,6 @@ static int md_bitmap_read_sb(struct bitmap *bitmap) daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; write_behind = le32_to_cpu(sb->write_behind); sectors_reserved = le32_to_cpu(sb->sectors_reserved); - /* Setup nodes/clustername only if bitmap version is - * cluster-compatible - */ - if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) { - nodes = le32_to_cpu(sb->nodes); - strlcpy(bitmap->mddev->bitmap_info.cluster_name, - sb->cluster_name, 64); - }
/* verify that the bitmap-specific fields are valid */ if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) @@ -668,6 +660,16 @@ static int md_bitmap_read_sb(struct bitmap *bitmap) goto out; }
+ /* + * Setup nodes/clustername only if bitmap version is + * cluster-compatible + */ + if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) { + nodes = le32_to_cpu(sb->nodes); + strlcpy(bitmap->mddev->bitmap_info.cluster_name, + sb->cluster_name, 64); + } + /* keep the array size field of the bitmap superblock up to date */ sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
@@ -700,9 +702,9 @@ static int md_bitmap_read_sb(struct bitmap *bitmap)
out: kunmap_atomic(sb); - /* Assigning chunksize is required for "re_read" */ - bitmap->mddev->bitmap_info.chunksize = chunksize; if (err == 0 && nodes && (bitmap->cluster_slot < 0)) { + /* Assigning chunksize is required for "re_read" */ + bitmap->mddev->bitmap_info.chunksize = chunksize; err = md_setup_cluster(bitmap->mddev, nodes); if (err) { pr_warn("%s: Could not setup cluster service (%d)\n", @@ -713,18 +715,18 @@ static int md_bitmap_read_sb(struct bitmap *bitmap) goto re_read; }
- out_no_sb: - if (test_bit(BITMAP_STALE, &bitmap->flags)) - bitmap->events_cleared = bitmap->mddev->events; - bitmap->mddev->bitmap_info.chunksize = chunksize; - bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; - bitmap->mddev->bitmap_info.max_write_behind = write_behind; - bitmap->mddev->bitmap_info.nodes = nodes; - if (bitmap->mddev->bitmap_info.space == 0 || - bitmap->mddev->bitmap_info.space > sectors_reserved) - bitmap->mddev->bitmap_info.space = sectors_reserved; - if (err) { + if (err == 0) { + if (test_bit(BITMAP_STALE, &bitmap->flags)) + bitmap->events_cleared = bitmap->mddev->events; + bitmap->mddev->bitmap_info.chunksize = chunksize; + bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; + bitmap->mddev->bitmap_info.max_write_behind = write_behind; + bitmap->mddev->bitmap_info.nodes = nodes; + if (bitmap->mddev->bitmap_info.space == 0 || + bitmap->mddev->bitmap_info.space > sectors_reserved) + bitmap->mddev->bitmap_info.space = sectors_reserved; + } else { md_bitmap_print_sb(bitmap); if (bitmap->cluster_slot < 0) md_cluster_stop(bitmap->mddev);
From: Aidan MacDonald aidanmacdonald.0x0@gmail.com
[ Upstream commit afadb04f1d6e74b18a253403f5274cde5e3fd7bd ]
Do what is done in other DMA-enabled MMC host drivers (cf. host/mmci.c) and limit the maximum segment size based on the DMA engine's capabilities. This is needed to avoid warnings like the following with CONFIG_DMA_API_DEBUG=y.
------------[ cut here ]------------ WARNING: CPU: 0 PID: 21 at kernel/dma/debug.c:1162 debug_dma_map_sg+0x2f4/0x39c DMA-API: jz4780-dma 13420000.dma-controller: mapping sg segment longer than device claims to support [len=98304] [max=65536] CPU: 0 PID: 21 Comm: kworker/0:1H Not tainted 5.18.0-rc1 #19 Workqueue: kblockd blk_mq_run_work_fn Stack : 81575aec 00000004 80620000 80620000 80620000 805e7358 00000009 801537ac 814c832c 806276e3 806e34b4 80620000 81575aec 00000001 81575ab8 09291444 00000000 00000000 805e7358 81575958 ffffffea 8157596c 00000000 636f6c62 6220646b 80387a70 0000000f 6d5f6b6c 80620000 00000000 81575ba4 00000009 805e170c 80896640 00000001 00010000 00000000 00000000 00006098 806e0000 ... Call Trace: [<80107670>] show_stack+0x84/0x120 [<80528cd8>] __warn+0xb8/0xec [<80528d78>] warn_slowpath_fmt+0x6c/0xb8 [<8016f1d4>] debug_dma_map_sg+0x2f4/0x39c [<80169d4c>] __dma_map_sg_attrs+0xf0/0x118 [<8016a27c>] dma_map_sg_attrs+0x14/0x28 [<804f66b4>] jz4740_mmc_prepare_dma_data+0x74/0xa4 [<804f6714>] jz4740_mmc_pre_request+0x30/0x54 [<804f4ff4>] mmc_blk_mq_issue_rq+0x6e0/0x7bc [<804f5590>] mmc_mq_queue_rq+0x220/0x2d4 [<8038b2c0>] blk_mq_dispatch_rq_list+0x480/0x664 [<80391040>] blk_mq_do_dispatch_sched+0x2dc/0x370 [<80391468>] __blk_mq_sched_dispatch_requests+0xec/0x164 [<80391540>] blk_mq_sched_dispatch_requests+0x44/0x94 [<80387900>] __blk_mq_run_hw_queue+0xb0/0xcc [<80134c14>] process_one_work+0x1b8/0x264 [<80134ff8>] worker_thread+0x2ec/0x3b8 [<8013b13c>] kthread+0x104/0x10c [<80101dcc>] ret_from_kernel_thread+0x14/0x1c
---[ end trace 0000000000000000 ]---
Signed-off-by: Aidan MacDonald aidanmacdonald.0x0@gmail.com Link: https://lore.kernel.org/r/20220411153753.50443-1-aidanmacdonald.0x0@gmail.co... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/jz4740_mmc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 7ab1b38a7be5..b1d563b2ed1b 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c @@ -247,6 +247,26 @@ static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host) return PTR_ERR(host->dma_rx); }
+ /* + * Limit the maximum segment size in any SG entry according to + * the parameters of the DMA engine device. + */ + if (host->dma_tx) { + struct device *dev = host->dma_tx->device->dev; + unsigned int max_seg_size = dma_get_max_seg_size(dev); + + if (max_seg_size < host->mmc->max_seg_size) + host->mmc->max_seg_size = max_seg_size; + } + + if (host->dma_rx) { + struct device *dev = host->dma_rx->device->dev; + unsigned int max_seg_size = dma_get_max_seg_size(dev); + + if (max_seg_size < host->mmc->max_seg_size) + host->mmc->max_seg_size = max_seg_size; + } + return 0; }
From: Vignesh Raghavendra vigneshr@ti.com
[ Upstream commit c7666240ec76422cb7546bd07cc8ae80dc0ccdd2 ]
The ARASAN MMC controller on Keystone 3 class of devices need the SDCD line to be connected for proper functioning. Similar to the issue pointed out in sdhci-of-arasan.c driver, commit 3794c542641f ("mmc: sdhci-of-arasan: Set controller to test mode when no CD bit").
In cases where this can't be connected, add a quirk to force the controller into test mode and set the TESTCD bit. Use the flag "ti,fails-without-test-cd", to implement this above quirk when required.
Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Aswath Govindraju a-govindraju@ti.com Link: https://lore.kernel.org/r/20220425063120.10135-3-a-govindraju@ti.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci_am654.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index e54fe24d47e7..e7ced1496a07 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -147,6 +147,9 @@ struct sdhci_am654_data { int drv_strength; int strb_sel; u32 flags; + u32 quirks; + +#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0) };
struct sdhci_am654_driver_data { @@ -369,6 +372,21 @@ static void sdhci_am654_write_b(struct sdhci_host *host, u8 val, int reg) } }
+static void sdhci_am654_reset(struct sdhci_host *host, u8 mask) +{ + u8 ctrl; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); + + sdhci_reset(host, mask); + + if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) { + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); + ctrl |= SDHCI_CTRL_CDTEST_INS | SDHCI_CTRL_CDTEST_EN; + sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); + } +} + static int sdhci_am654_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct sdhci_host *host = mmc_priv(mmc); @@ -500,7 +518,7 @@ static struct sdhci_ops sdhci_j721e_4bit_ops = { .set_clock = sdhci_j721e_4bit_set_clock, .write_b = sdhci_am654_write_b, .irq = sdhci_am654_cqhci_irq, - .reset = sdhci_reset, + .reset = sdhci_am654_reset, };
static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = { @@ -719,6 +737,9 @@ static int sdhci_am654_get_of_property(struct platform_device *pdev, device_property_read_u32(dev, "ti,clkbuf-sel", &sdhci_am654->clkbuf_sel);
+ if (device_property_read_bool(dev, "ti,fails-without-test-cd")) + sdhci_am654->quirks |= SDHCI_AM654_QUIRK_FORCE_CDTEST; + sdhci_get_of_property(pdev);
return 0;
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit c5acd61dbb32b6bda0f3a354108f2b8dcb788985 ]
If major equals 0, register_chrdev() returns an error code when it fails. This function dynamically allocates a major and returns its number on success, so we should use "< 0" to check it instead of "!".
Link: https://lore.kernel.org/r/20220418105755.2558828-1-lv.ruyi@zte.com.cn Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/megaraid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index a5d8cee2d510..bf491af9f0d6 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -4607,7 +4607,7 @@ static int __init megaraid_init(void) * major number allocation. */ major = register_chrdev(0, "megadev_legacy", &megadev_fops); - if (!major) { + if (major < 0) { printk(KERN_WARNING "megaraid: failed to register char device\n"); }
From: Haohui Mai ricetons@gmail.com
[ Upstream commit 7dba6e838e741caadcf27ef717b6dcb561e77f89 ]
This patch fixes the issue where the driver miscomputes the 64-bit values of the wptr of the SDMA doorbell when initializing the hardware. SDMA engines v4 and later on have full 64-bit registers for wptr thus they should be set properly.
Older generation hardwares like CIK / SI have only 16 / 20 / 24bits for the WPTR, where the calls of lower_32_bits() will be removed in a following patch.
Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Haohui Mai ricetons@gmail.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index d7e8f7232364..ff86c43b63d1 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -772,8 +772,8 @@ static void sdma_v4_0_ring_set_wptr(struct amdgpu_ring *ring)
DRM_DEBUG("Using doorbell -- " "wptr_offs == 0x%08x " - "lower_32_bits(ring->wptr) << 2 == 0x%08x " - "upper_32_bits(ring->wptr) << 2 == 0x%08x\n", + "lower_32_bits(ring->wptr << 2) == 0x%08x " + "upper_32_bits(ring->wptr << 2) == 0x%08x\n", ring->wptr_offs, lower_32_bits(ring->wptr << 2), upper_32_bits(ring->wptr << 2)); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index a8d49c005f73..627eb1f147c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -394,8 +394,8 @@ static void sdma_v5_0_ring_set_wptr(struct amdgpu_ring *ring) if (ring->use_doorbell) { DRM_DEBUG("Using doorbell -- " "wptr_offs == 0x%08x " - "lower_32_bits(ring->wptr) << 2 == 0x%08x " - "upper_32_bits(ring->wptr) << 2 == 0x%08x\n", + "lower_32_bits(ring->wptr << 2) == 0x%08x " + "upper_32_bits(ring->wptr << 2) == 0x%08x\n", ring->wptr_offs, lower_32_bits(ring->wptr << 2), upper_32_bits(ring->wptr << 2)); @@ -774,9 +774,9 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev)
if (!amdgpu_sriov_vf(adev)) { /* only bare-metal use register write for wptr */ WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR), - lower_32_bits(ring->wptr) << 2); + lower_32_bits(ring->wptr << 2)); WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_HI), - upper_32_bits(ring->wptr) << 2); + upper_32_bits(ring->wptr << 2)); }
doorbell = RREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_DOORBELL)); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 824eace69884..a5eb82bfeaa8 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -295,8 +295,8 @@ static void sdma_v5_2_ring_set_wptr(struct amdgpu_ring *ring) if (ring->use_doorbell) { DRM_DEBUG("Using doorbell -- " "wptr_offs == 0x%08x " - "lower_32_bits(ring->wptr) << 2 == 0x%08x " - "upper_32_bits(ring->wptr) << 2 == 0x%08x\n", + "lower_32_bits(ring->wptr << 2) == 0x%08x " + "upper_32_bits(ring->wptr << 2) == 0x%08x\n", ring->wptr_offs, lower_32_bits(ring->wptr << 2), upper_32_bits(ring->wptr << 2)); @@ -672,8 +672,8 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) WREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_MINOR_PTR_UPDATE), 1);
if (!amdgpu_sriov_vf(adev)) { /* only bare-metal use register write for wptr */ - WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr) << 2); - WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2); + WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR), lower_32_bits(ring->wptr << 2)); + WREG32(sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_WPTR_HI), upper_32_bits(ring->wptr << 2)); }
doorbell = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_DOORBELL));
From: Minghao Chi chi.minghao@zte.com.cn
[ Upstream commit 75b8715e20a20bc7b4844835e4035543a2674200 ]
Using pm_runtime_resume_and_get() to replace pm_runtime_get_sync() and pm_runtime_put_noidle(). This change is just to simplify the code, no actual functional changes.
Link: https://lore.kernel.org/r/20220420090353.2588804-1-chi.minghao@zte.com.cn Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Minghao Chi chi.minghao@zte.com.cn Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ti-j721e-ufs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/ufs/ti-j721e-ufs.c b/drivers/scsi/ufs/ti-j721e-ufs.c index eafe0db98d54..122d650d0810 100644 --- a/drivers/scsi/ufs/ti-j721e-ufs.c +++ b/drivers/scsi/ufs/ti-j721e-ufs.c @@ -29,11 +29,9 @@ static int ti_j721e_ufs_probe(struct platform_device *pdev) return PTR_ERR(regbase);
pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_noidle(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) goto disable_pm; - }
/* Select MPHY refclk frequency */ clk = devm_clk_get(dev, NULL);
From: James Smart jsmart2021@gmail.com
[ Upstream commit 646db1a560f44236b7278b822ca99a1d3b6ea72c ]
If no handler is found in lpfc_complete_unsol_iocb() to match the rctl of a received frame, the frame is dropped and resources are leaked.
Fix by returning resources when discarding an unhandled frame type. Update lpfc_fc_frame_check() handling of NOP basic link service.
Link: https://lore.kernel.org/r/20220426181419.9154-1-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_sli.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 09a45f8ecf3f..a174e06bd96e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -18124,7 +18124,6 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr) case FC_RCTL_ELS_REP: /* extended link services reply */ case FC_RCTL_ELS4_REQ: /* FC-4 ELS request */ case FC_RCTL_ELS4_REP: /* FC-4 ELS reply */ - case FC_RCTL_BA_NOP: /* basic link service NOP */ case FC_RCTL_BA_ABTS: /* basic link service abort */ case FC_RCTL_BA_RMC: /* remove connection */ case FC_RCTL_BA_ACC: /* basic accept */ @@ -18145,6 +18144,7 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr) fc_vft_hdr = (struct fc_vft_header *)fc_hdr; fc_hdr = &((struct fc_frame_header *)fc_vft_hdr)[1]; return lpfc_fc_frame_check(phba, fc_hdr); + case FC_RCTL_BA_NOP: /* basic link service NOP */ default: goto drop; } @@ -18959,12 +18959,14 @@ lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *vport, if (!lpfc_complete_unsol_iocb(phba, phba->sli4_hba.els_wq->pring, iocbq, fc_hdr->fh_r_ctl, - fc_hdr->fh_type)) + fc_hdr->fh_type)) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2540 Ring %d handler: unexpected Rctl " "x%x Type x%x received\n", LPFC_ELS_RING, fc_hdr->fh_r_ctl, fc_hdr->fh_type); + lpfc_in_buf_free(phba, &seq_dmabuf->dbuf); + }
/* Free iocb created in lpfc_prep_seq */ list_for_each_entry_safe(curr_iocb, next_iocb,
From: Hari Chandrakanthan quic_haric@quicinc.com
[ Upstream commit 161c64de239c7018e0295e7e0520a19f00aa32dc ]
When ath11k modules are removed using rmmod with spectral scan enabled, crash is observed. Different crash trace is observed for each crash.
Send spectral scan disable WMI command to firmware before cleaning the spectral dbring in the spectral_deinit API to avoid this crash.
call trace from one of the crash observed: [ 1252.880802] Unable to handle kernel NULL pointer dereference at virtual address 00000008 [ 1252.882722] pgd = 0f42e886 [ 1252.890955] [00000008] *pgd=00000000 [ 1252.893478] Internal error: Oops: 5 [#1] PREEMPT SMP ARM [ 1253.093035] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.4.89 #0 [ 1253.115261] Hardware name: Generic DT based system [ 1253.121149] PC is at ath11k_spectral_process_data+0x434/0x574 [ath11k] [ 1253.125940] LR is at 0x88e31017 [ 1253.132448] pc : [<7f9387b8>] lr : [<88e31017>] psr: a0000193 [ 1253.135488] sp : 80d01bc8 ip : 00000001 fp : 970e0000 [ 1253.141737] r10: 88e31000 r9 : 970ec000 r8 : 00000080 [ 1253.146946] r7 : 94734040 r6 : a0000113 r5 : 00000057 r4 : 00000000 [ 1253.152159] r3 : e18cb694 r2 : 00000217 r1 : 1df1f000 r0 : 00000001 [ 1253.158755] Flags: NzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user [ 1253.165266] Control: 10c0383d Table: 5e71006a DAC: 00000055 [ 1253.172472] Process swapper/0 (pid: 0, stack limit = 0x60870141) [ 1253.458055] [<7f9387b8>] (ath11k_spectral_process_data [ath11k]) from [<7f917fdc>] (ath11k_dbring_buffer_release_event+0x214/0x2e4 [ath11k]) [ 1253.466139] [<7f917fdc>] (ath11k_dbring_buffer_release_event [ath11k]) from [<7f8ea3c4>] (ath11k_wmi_tlv_op_rx+0x1840/0x29cc [ath11k]) [ 1253.478807] [<7f8ea3c4>] (ath11k_wmi_tlv_op_rx [ath11k]) from [<7f8fe868>] (ath11k_htc_rx_completion_handler+0x180/0x4e0 [ath11k]) [ 1253.490699] [<7f8fe868>] (ath11k_htc_rx_completion_handler [ath11k]) from [<7f91308c>] (ath11k_ce_per_engine_service+0x2c4/0x3b4 [ath11k]) [ 1253.502386] [<7f91308c>] (ath11k_ce_per_engine_service [ath11k]) from [<7f9a4198>] (ath11k_pci_ce_tasklet+0x28/0x80 [ath11k_pci]) [ 1253.514811] [<7f9a4198>] (ath11k_pci_ce_tasklet [ath11k_pci]) from [<8032227c>] (tasklet_action_common.constprop.2+0x64/0xe8) [ 1253.526476] [<8032227c>] (tasklet_action_common.constprop.2) from [<803021e8>] (__do_softirq+0x130/0x2d0) [ 1253.537756] [<803021e8>] (__do_softirq) from [<80322610>] (irq_exit+0xcc/0xe8) [ 1253.547304] [<80322610>] (irq_exit) from [<8036a4a4>] (__handle_domain_irq+0x60/0xb4) [ 1253.554428] [<8036a4a4>] (__handle_domain_irq) from [<805eb348>] (gic_handle_irq+0x4c/0x90) [ 1253.562321] [<805eb348>] (gic_handle_irq) from [<80301a78>] (__irq_svc+0x58/0x8c)
Tested-on: QCN6122 hw1.0 AHB WLAN.HK.2.6.0.1-00851-QCAHKSWPL_SILICONZ-1
Signed-off-by: Hari Chandrakanthan quic_haric@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/1649396345-349-1-git-send-email-quic_haric@quicinc... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/spectral.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/spectral.c b/drivers/net/wireless/ath/ath11k/spectral.c index 2b18871d5f7c..516a7b4cd180 100644 --- a/drivers/net/wireless/ath/ath11k/spectral.c +++ b/drivers/net/wireless/ath/ath11k/spectral.c @@ -212,7 +212,10 @@ static int ath11k_spectral_scan_config(struct ath11k *ar, return -ENODEV;
arvif->spectral_enabled = (mode != ATH11K_SPECTRAL_DISABLED); + + spin_lock_bh(&ar->spectral.lock); ar->spectral.mode = mode; + spin_unlock_bh(&ar->spectral.lock);
ret = ath11k_wmi_vdev_spectral_enable(ar, arvif->vdev_id, ATH11K_WMI_SPECTRAL_TRIGGER_CMD_CLEAR, @@ -843,9 +846,6 @@ static inline void ath11k_spectral_ring_free(struct ath11k *ar) { struct ath11k_spectral *sp = &ar->spectral;
- if (!sp->enabled) - return; - ath11k_dbring_srng_cleanup(ar, &sp->rx_ring); ath11k_dbring_buf_cleanup(ar, &sp->rx_ring); } @@ -897,15 +897,16 @@ void ath11k_spectral_deinit(struct ath11k_base *ab) if (!sp->enabled) continue;
- ath11k_spectral_debug_unregister(ar); - ath11k_spectral_ring_free(ar); + mutex_lock(&ar->conf_mutex); + ath11k_spectral_scan_config(ar, ATH11K_SPECTRAL_DISABLED); + mutex_unlock(&ar->conf_mutex);
spin_lock_bh(&sp->lock); - - sp->mode = ATH11K_SPECTRAL_DISABLED; sp->enabled = false; - spin_unlock_bh(&sp->lock); + + ath11k_spectral_debug_unregister(ar); + ath11k_spectral_ring_free(ar); } }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit ce216cfa84a4e1c23b105e652c550bdeaac9e922 ]
Add a quirk for the HP Pro Tablet 408, this BYTCR tablet has no CHAN package in its ACPI tables and uses SSP0-AIF1 rather then SSP0-AIF2 which is the default for BYTCR devices.
It also uses DMIC1 for the internal mic rather then the default IN3 and it uses JD2 rather then the default JD1 for jack-detect.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211485 Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20220427134918.527381-1-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/bytcr_rt5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index d76a505052fb..f81ae742faa7 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -773,6 +773,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_OVCD_SF_0P75 | BYT_RT5640_MCLK_EN), }, + { /* HP Pro Tablet 408 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pro Tablet 408"), + }, + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_1500UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* HP Stream 7 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
From: Steven Price steven.price@arm.com
[ Upstream commit 4b674dd69701c2e22e8e7770c1706a69f3b17269 ]
While the check for format_count > 64 in __drm_universal_plane_init() shouldn't be hit (it's a WARN_ON), in its current position it will then leak the plane->format_types array and fail to call drm_mode_object_unregister() leaking the modeset identifier. Move it to the start of the function to avoid allocating those resources in the first place.
Signed-off-by: Steven Price steven.price@arm.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Link: https://lore.kernel.org/dri-devel/20211203102815.38624-1-steven.price@arm.co... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_plane.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index bf0daa8d9bbd..726f2f163c26 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -247,6 +247,13 @@ static int __drm_universal_plane_init(struct drm_device *dev, if (WARN_ON(config->num_total_plane >= 32)) return -EINVAL;
+ /* + * First driver to need more than 64 formats needs to fix this. Each + * format is encoded as a bit and the current code only supports a u64. + */ + if (WARN_ON(format_count > 64)) + return -EINVAL; + WARN_ON(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)); @@ -268,13 +275,6 @@ static int __drm_universal_plane_init(struct drm_device *dev, return -ENOMEM; }
- /* - * First driver to need more than 64 formats needs to fix this. Each - * format is encoded as a bit and the current code only supports a u64. - */ - if (WARN_ON(format_count > 64)) - return -EINVAL; - if (format_modifiers) { const uint64_t *temp_modifiers = format_modifiers;
From: Mukul Joshi mukul.joshi@amd.com
[ Upstream commit b179fc28d521379ba7e0a38eec1a4c722e7ea634 ]
[ 168.544078] ====================================================== [ 168.550309] WARNING: possible circular locking dependency detected [ 168.556523] 5.16.0-kfd-fkuehlin #148 Tainted: G E [ 168.562558] ------------------------------------------------------ [ 168.568764] kfdtest/3479 is trying to acquire lock: [ 168.573672] ffffffffc0927a70 (&topology_lock){++++}-{3:3}, at: kfd_topology_device_by_id+0x16/0x60 [amdgpu] [ 168.583663] but task is already holding lock: [ 168.589529] ffff97d303dee668 (&mm->mmap_lock#2){++++}-{3:3}, at: vm_mmap_pgoff+0xa9/0x180 [ 168.597755] which lock already depends on the new lock.
[ 168.605970] the existing dependency chain (in reverse order) is: [ 168.613487] -> #3 (&mm->mmap_lock#2){++++}-{3:3}: [ 168.619700] lock_acquire+0xca/0x2e0 [ 168.623814] down_read+0x3e/0x140 [ 168.627676] do_user_addr_fault+0x40d/0x690 [ 168.632399] exc_page_fault+0x6f/0x270 [ 168.636692] asm_exc_page_fault+0x1e/0x30 [ 168.641249] filldir64+0xc8/0x1e0 [ 168.645115] call_filldir+0x7c/0x110 [ 168.649238] ext4_readdir+0x58e/0x940 [ 168.653442] iterate_dir+0x16a/0x1b0 [ 168.657558] __x64_sys_getdents64+0x83/0x140 [ 168.662375] do_syscall_64+0x35/0x80 [ 168.666492] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 168.672095] -> #2 (&type->i_mutex_dir_key#6){++++}-{3:3}: [ 168.679008] lock_acquire+0xca/0x2e0 [ 168.683122] down_read+0x3e/0x140 [ 168.686982] path_openat+0x5b2/0xa50 [ 168.691095] do_file_open_root+0xfc/0x190 [ 168.695652] file_open_root+0xd8/0x1b0 [ 168.702010] kernel_read_file_from_path_initns+0xc4/0x140 [ 168.709542] _request_firmware+0x2e9/0x5e0 [ 168.715741] request_firmware+0x32/0x50 [ 168.721667] amdgpu_cgs_get_firmware_info+0x370/0xdd0 [amdgpu] [ 168.730060] smu7_upload_smu_firmware_image+0x53/0x190 [amdgpu] [ 168.738414] fiji_start_smu+0xcf/0x4e0 [amdgpu] [ 168.745539] pp_dpm_load_fw+0x21/0x30 [amdgpu] [ 168.752503] amdgpu_pm_load_smu_firmware+0x4b/0x80 [amdgpu] [ 168.760698] amdgpu_device_fw_loading+0xb8/0x140 [amdgpu] [ 168.768412] amdgpu_device_init.cold+0xdf6/0x1716 [amdgpu] [ 168.776285] amdgpu_driver_load_kms+0x15/0x120 [amdgpu] [ 168.784034] amdgpu_pci_probe+0x19b/0x3a0 [amdgpu] [ 168.791161] local_pci_probe+0x40/0x80 [ 168.797027] work_for_cpu_fn+0x10/0x20 [ 168.802839] process_one_work+0x273/0x5b0 [ 168.808903] worker_thread+0x20f/0x3d0 [ 168.814700] kthread+0x176/0x1a0 [ 168.819968] ret_from_fork+0x1f/0x30 [ 168.825563] -> #1 (&adev->pm.mutex){+.+.}-{3:3}: [ 168.834721] lock_acquire+0xca/0x2e0 [ 168.840364] __mutex_lock+0xa2/0x930 [ 168.846020] amdgpu_dpm_get_mclk+0x37/0x60 [amdgpu] [ 168.853257] amdgpu_amdkfd_get_local_mem_info+0xba/0xe0 [amdgpu] [ 168.861547] kfd_create_vcrat_image_gpu+0x1b1/0xbb0 [amdgpu] [ 168.869478] kfd_create_crat_image_virtual+0x447/0x510 [amdgpu] [ 168.877884] kfd_topology_add_device+0x5c8/0x6f0 [amdgpu] [ 168.885556] kgd2kfd_device_init.cold+0x385/0x4c5 [amdgpu] [ 168.893347] amdgpu_amdkfd_device_init+0x138/0x180 [amdgpu] [ 168.901177] amdgpu_device_init.cold+0x141b/0x1716 [amdgpu] [ 168.909025] amdgpu_driver_load_kms+0x15/0x120 [amdgpu] [ 168.916458] amdgpu_pci_probe+0x19b/0x3a0 [amdgpu] [ 168.923442] local_pci_probe+0x40/0x80 [ 168.929249] work_for_cpu_fn+0x10/0x20 [ 168.935008] process_one_work+0x273/0x5b0 [ 168.940944] worker_thread+0x20f/0x3d0 [ 168.946623] kthread+0x176/0x1a0 [ 168.951765] ret_from_fork+0x1f/0x30 [ 168.957277] -> #0 (&topology_lock){++++}-{3:3}: [ 168.965993] check_prev_add+0x8f/0xbf0 [ 168.971613] __lock_acquire+0x1299/0x1ca0 [ 168.977485] lock_acquire+0xca/0x2e0 [ 168.982877] down_read+0x3e/0x140 [ 168.987975] kfd_topology_device_by_id+0x16/0x60 [amdgpu] [ 168.995583] kfd_device_by_id+0xa/0x20 [amdgpu] [ 169.002180] kfd_mmap+0x95/0x200 [amdgpu] [ 169.008293] mmap_region+0x337/0x5a0 [ 169.013679] do_mmap+0x3aa/0x540 [ 169.018678] vm_mmap_pgoff+0xdc/0x180 [ 169.024095] ksys_mmap_pgoff+0x186/0x1f0 [ 169.029734] do_syscall_64+0x35/0x80 [ 169.035005] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 169.041754] other info that might help us debug this:
[ 169.053276] Chain exists of: &topology_lock --> &type->i_mutex_dir_key#6 --> &mm->mmap_lock#2
[ 169.068389] Possible unsafe locking scenario:
[ 169.076661] CPU0 CPU1 [ 169.082383] ---- ---- [ 169.088087] lock(&mm->mmap_lock#2); [ 169.092922] lock(&type->i_mutex_dir_key#6); [ 169.100975] lock(&mm->mmap_lock#2); [ 169.108320] lock(&topology_lock); [ 169.112957] *** DEADLOCK ***
This commit fixes the deadlock warning by ensuring pm.mutex is not held while holding the topology lock. For this, kfd_local_mem_info is moved into the KFD dev struct and filled during device init. This cached value can then be used instead of querying the value again and again.
Signed-off-by: Mukul Joshi mukul.joshi@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 7 ++----- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 ++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 + drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 7 ++----- 5 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 607f65ab39ac..10cc834a5ac3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -944,8 +944,6 @@ static int kfd_ioctl_acquire_vm(struct file *filep, struct kfd_process *p,
bool kfd_dev_is_large_bar(struct kfd_dev *dev) { - struct kfd_local_mem_info mem_info; - if (debug_largebar) { pr_debug("Simulate large-bar allocation on non large-bar machine\n"); return true; @@ -954,9 +952,8 @@ bool kfd_dev_is_large_bar(struct kfd_dev *dev) if (dev->use_iommu_v2) return false;
- amdgpu_amdkfd_get_local_mem_info(dev->adev, &mem_info); - if (mem_info.local_mem_size_private == 0 && - mem_info.local_mem_size_public > 0) + if (dev->local_mem_info.local_mem_size_private == 0 && + dev->local_mem_info.local_mem_size_public > 0) return true; return false; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 1eaabd2cb41b..59b349a4c04a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -2152,7 +2152,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, * report the total FB size (public+private) as a single * private heap. */ - amdgpu_amdkfd_get_local_mem_info(kdev->adev, &local_mem_info); + local_mem_info = kdev->local_mem_info; sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + sub_type_hdr->length);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 62aa6c9d5123..c96d521447fc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -575,6 +575,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, if (kfd_resume(kfd)) goto kfd_resume_error;
+ amdgpu_amdkfd_get_local_mem_info(kfd->adev, &kfd->local_mem_info); + if (kfd_topology_add_device(kfd)) { dev_err(kfd_device, "Error adding device to topology\n"); goto kfd_topology_add_device_error; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 8f58fc491b28..49a29a60b71e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -272,6 +272,7 @@ struct kfd_dev {
struct kgd2kfd_shared_resources shared_resources; struct kfd_vmid_info vm_info; + struct kfd_local_mem_info local_mem_info;
const struct kfd2kgd_calls *kfd2kgd; struct mutex doorbell_mutex; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 3bdcae239bc0..9fc24f6823df 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1102,15 +1102,12 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu) uint32_t buf[7]; uint64_t local_mem_size; int i; - struct kfd_local_mem_info local_mem_info;
if (!gpu) return 0;
- amdgpu_amdkfd_get_local_mem_info(gpu->adev, &local_mem_info); - - local_mem_size = local_mem_info.local_mem_size_private + - local_mem_info.local_mem_size_public; + local_mem_size = gpu->local_mem_info.local_mem_size_private + + gpu->local_mem_info.local_mem_size_public;
buf[0] = gpu->pdev->devfn; buf[1] = gpu->pdev->subsystem_vendor |
From: Evan Quan evan.quan@amd.com
[ Upstream commit 555238d92ac32dbad2d77ad2bafc48d17391990c ]
Fix the compile warning below: drivers/gpu/drm/amd/amdgpu/../pm/legacy-dpm/kv_dpm.c:1641 kv_get_acp_boot_level() warn: always true condition '(table->entries[i]->clk >= 0) => (0-u32max >= 0)'
Reported-by: kernel test robot lkp@intel.com CC: Alex Deucher alexander.deucher@amd.com Signed-off-by: Evan Quan evan.quan@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/pm/legacy-dpm/kv_dpm.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c index 8b23cc9f098a..8fd0782a2b20 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c @@ -1623,19 +1623,7 @@ static int kv_update_samu_dpm(struct amdgpu_device *adev, bool gate)
static u8 kv_get_acp_boot_level(struct amdgpu_device *adev) { - u8 i; - struct amdgpu_clock_voltage_dependency_table *table = - &adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table; - - for (i = 0; i < table->count; i++) { - if (table->entries[i].clk >= 0) /* XXX */ - break; - } - - if (i >= table->count) - i = table->count - 1; - - return i; + return 0; }
static void kv_update_acp_boot_level(struct amdgpu_device *adev)
From: Abhishek Kumar kuabhs@chromium.org
[ Upstream commit b72a4aff947ba807177bdabb43debaf2c66bee05 ]
Double free crash is observed when FW recovery(caused by wmi timeout/crash) is followed by immediate suspend event. The FW recovery is triggered by ath10k_core_restart() which calls driver clean up via ath10k_halt(). When the suspend event occurs between the FW recovery, the restart worker thread is put into frozen state until suspend completes. The suspend event triggers ath10k_stop() which again triggers ath10k_halt() The double invocation of ath10k_halt() causes ath10k_htt_rx_free() to be called twice(Note: ath10k_htt_rx_alloc was not called by restart worker thread because of its frozen state), causing the crash.
To fix this, during the suspend flow, skip call to ath10k_halt() in ath10k_stop() when the current driver state is ATH10K_STATE_RESTARTING. Also, for driver state ATH10K_STATE_RESTARTING, call ath10k_wait_for_suspend() in ath10k_stop(). This is because call to ath10k_wait_for_suspend() is skipped later in [ath10k_halt() > ath10k_core_stop()] for the driver state ATH10K_STATE_RESTARTING.
The frozen restart worker thread will be cancelled during resume when the device comes out of suspend.
Below is the crash stack for reference:
[ 428.469167] ------------[ cut here ]------------ [ 428.469180] kernel BUG at mm/slub.c:4150! [ 428.469193] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [ 428.469219] Workqueue: events_unbound async_run_entry_fn [ 428.469230] RIP: 0010:kfree+0x319/0x31b [ 428.469241] RSP: 0018:ffffa1fac015fc30 EFLAGS: 00010246 [ 428.469247] RAX: ffffedb10419d108 RBX: ffff8c05262b0000 [ 428.469252] RDX: ffff8c04a8c07000 RSI: 0000000000000000 [ 428.469256] RBP: ffffa1fac015fc78 R08: 0000000000000000 [ 428.469276] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 428.469285] Call Trace: [ 428.469295] ? dma_free_attrs+0x5f/0x7d [ 428.469320] ath10k_core_stop+0x5b/0x6f [ 428.469336] ath10k_halt+0x126/0x177 [ 428.469352] ath10k_stop+0x41/0x7e [ 428.469387] drv_stop+0x88/0x10e [ 428.469410] __ieee80211_suspend+0x297/0x411 [ 428.469441] rdev_suspend+0x6e/0xd0 [ 428.469462] wiphy_suspend+0xb1/0x105 [ 428.469483] ? name_show+0x2d/0x2d [ 428.469490] dpm_run_callback+0x8c/0x126 [ 428.469511] ? name_show+0x2d/0x2d [ 428.469517] __device_suspend+0x2e7/0x41b [ 428.469523] async_suspend+0x1f/0x93 [ 428.469529] async_run_entry_fn+0x3d/0xd1 [ 428.469535] process_one_work+0x1b1/0x329 [ 428.469541] worker_thread+0x213/0x372 [ 428.469547] kthread+0x150/0x15f [ 428.469552] ? pr_cont_work+0x58/0x58 [ 428.469558] ? kthread_blkcg+0x31/0x31
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 Co-developed-by: Wen Gong quic_wgong@quicinc.com Signed-off-by: Wen Gong quic_wgong@quicinc.com Signed-off-by: Abhishek Kumar kuabhs@chromium.org Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220426221859.v2.1.I650b809482e1af8d0156ed88b5dc2... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/mac.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b11aaee8b8c0..a11b31191d5a 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -5339,13 +5339,29 @@ static int ath10k_start(struct ieee80211_hw *hw) static void ath10k_stop(struct ieee80211_hw *hw) { struct ath10k *ar = hw->priv; + u32 opt;
ath10k_drain_tx(ar);
mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_OFF) { - if (!ar->hw_rfkill_on) - ath10k_halt(ar); + if (!ar->hw_rfkill_on) { + /* If the current driver state is RESTARTING but not yet + * fully RESTARTED because of incoming suspend event, + * then ath10k_halt() is already called via + * ath10k_core_restart() and should not be called here. + */ + if (ar->state != ATH10K_STATE_RESTARTING) { + ath10k_halt(ar); + } else { + /* Suspending here, because when in RESTARTING + * state, ath10k_core_stop() skips + * ath10k_wait_for_suspend(). + */ + opt = WMI_PDEV_SUSPEND_AND_DISABLE_INTR; + ath10k_wait_for_suspend(ar, opt); + } + } ar->state = ATH10K_STATE_OFF; } mutex_unlock(&ar->conf_mutex);
From: Alexandru Elisei alexandru.elisei@arm.com
[ Upstream commit 3fed9e551417b84038b15117732ea4505eee386b ]
If a compat process tries to execute an unknown system call above the __ARM_NR_COMPAT_END number, the kernel sends a SIGILL signal to the offending process. Information about the error is printed to dmesg in compat_arm_syscall() -> arm64_notify_die() -> arm64_force_sig_fault() -> arm64_show_signal().
arm64_show_signal() interprets a non-zero value for current->thread.fault_code as an exception syndrome and displays the message associated with the ESR_ELx.EC field (bits 31:26). current->thread.fault_code is set in compat_arm_syscall() -> arm64_notify_die() with the bad syscall number instead of a valid ESR_ELx value. This means that the ESR_ELx.EC field has the value that the user set for the syscall number and the kernel can end up printing bogus exception messages*. For example, for the syscall number 0x68000000, which evaluates to ESR_ELx.EC value of 0x1A (ESR_ELx_EC_FPAC) the kernel prints this error:
[ 18.349161] syscall[300]: unhandled exception: ERET/ERETAA/ERETAB, ESR 0x68000000, Oops - bad compat syscall(2) in syscall[10000+50000] [ 18.350639] CPU: 2 PID: 300 Comm: syscall Not tainted 5.18.0-rc1 #79 [ 18.351249] Hardware name: Pine64 RockPro64 v2.0 (DT) [..]
which is misleading, as the bad compat syscall has nothing to do with pointer authentication.
Stop arm64_show_signal() from printing exception syndrome information by having compat_arm_syscall() set the ESR_ELx value to 0, as it has no meaning for an invalid system call number. The example above now becomes:
[ 19.935275] syscall[301]: unhandled exception: Oops - bad compat syscall(2) in syscall[10000+50000] [ 19.936124] CPU: 1 PID: 301 Comm: syscall Not tainted 5.18.0-rc1-00005-g7e08006d4102 #80 [ 19.936894] Hardware name: Pine64 RockPro64 v2.0 (DT) [..]
which although shows less information because the syscall number, wrongfully advertised as the ESR value, is missing, it is better than showing plainly wrong information. The syscall number can be easily obtained with strace.
*A 32-bit value above or equal to 0x8000_0000 is interpreted as a negative integer in compat_arm_syscal() and the condition scno < __ARM_NR_COMPAT_END evaluates to true; the syscall will exit to userspace in this case with the ENOSYS error code instead of arm64_notify_die() being called.
Signed-off-by: Alexandru Elisei alexandru.elisei@arm.com Reviewed-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220425114444.368693-3-alexandru.elisei@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/sys_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index 12c6864e51e1..df14336c3a29 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -113,6 +113,6 @@ long compat_arm_syscall(struct pt_regs *regs, int scno) addr = instruction_pointer(regs) - (compat_thumb_mode(regs) ? 2 : 4);
arm64_notify_die("Oops - bad compat syscall(2)", regs, - SIGILL, ILL_ILLTRP, addr, scno); + SIGILL, ILL_ILLTRP, addr, 0); return 0; }
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit b9e4f1d2b505df8e2439b63e67afaa287c1c43e2 ]
The irq_of_parse_and_map() function returns 0 on failure, and does not return an negative value.
Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/483175/ Link: https://lore.kernel.org/r/20220424031959.3172406-1-lv.ruyi@zte.com.cn Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 3b92372e7bdf..1d4bbde29320 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -570,9 +570,9 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) }
irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - if (irq < 0) { - ret = irq; - DRM_DEV_ERROR(&pdev->dev, "failed to get irq: %d\n", ret); + if (!irq) { + ret = -EINVAL; + DRM_DEV_ERROR(&pdev->dev, "failed to get irq\n"); goto fail; }
From: Jessica Zhang quic_jesszhan@quicinc.com
[ Upstream commit 3ce8bdca394fc606b55e7c5ed779d171aaae5d09 ]
Currently, dpu_hw_lm_collect_misr returns EINVAL if CRC is disabled. This causes a lot of spam in the DRM debug logs as it's called for every vblank.
Instead of returning EINVAL when CRC is disabled in dpu_hw_lm_collect_misr, let's return ENODATA and add an extra ENODATA check before the debug log in dpu_crtc_get_crc.
Changes since V1: - Added reported-by and suggested-by tags
Reported-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Suggested-by: Rob Clark robdclark@chromium.org Signed-off-by: Jessica Zhang quic_jesszhan@quicinc.com Tested-by: Jessica Zhang quic_jesszhan@quicinc.com # RB5 (qrb5165) Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/484274/ Link: https://lore.kernel.org/r/20220430005210.339-1-quic_jesszhan@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 7763558ef566..16ba9f9b9a78 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -204,7 +204,8 @@ static int dpu_crtc_get_crc(struct drm_crtc *crtc) rc = m->hw_lm->ops.collect_misr(m->hw_lm, &crcs[i]);
if (rc) { - DRM_DEBUG_DRIVER("MISR read failed\n"); + if (rc != -ENODATA) + DRM_DEBUG_DRIVER("MISR read failed\n"); return rc; } } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 86363c0ec834..462f5082099e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -138,7 +138,7 @@ static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) ctrl = DPU_REG_READ(c, LM_MISR_CTRL);
if (!(ctrl & LM_MISR_CTRL_ENABLE)) - return -EINVAL; + return -ENODATA;
if (!(ctrl & LM_MISR_CTRL_STATUS)) return -EINVAL;
From: Max Filippov jcmvbkbc@gmail.com
[ Upstream commit de4415d0bac91192ee9c74e849bc61429efa9b42 ]
Context tracking call must be done after hardirq tracking call, otherwise lockdep_assert_irqs_disabled called from rcu_eqs_exit gives a warning. To avoid context tracking logic duplication for IRQ/exception entry paths move trace_hardirqs_off call back to common entry code.
Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/xtensa/kernel/entry.S | 19 +++++++++++++------ arch/xtensa/kernel/traps.c | 11 ++--------- 2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 6b6eff658795..07d683d94e17 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -442,7 +442,6 @@ KABI_W or a3, a3, a0 moveqz a3, a0, a2 # a3 = LOCKLEVEL iff interrupt KABI_W movi a2, PS_WOE_MASK KABI_W or a3, a3, a2 - rsr a2, exccause #endif
/* restore return address (or 0 if return to userspace) */ @@ -469,19 +468,27 @@ KABI_W or a3, a3, a2
save_xtregs_opt a1 a3 a4 a5 a6 a7 PT_XTREGS_OPT +#ifdef CONFIG_TRACE_IRQFLAGS + rsr abi_tmp0, ps + extui abi_tmp0, abi_tmp0, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH + beqz abi_tmp0, 1f + abi_call trace_hardirqs_off +1: +#endif + /* Go to second-level dispatcher. Set up parameters to pass to the * exception handler and call the exception handler. */
- rsr a4, excsave1 - addx4 a4, a2, a4 - l32i a4, a4, EXC_TABLE_DEFAULT # load handler - mov abi_arg1, a2 # pass EXCCAUSE + l32i abi_arg1, a1, PT_EXCCAUSE # pass EXCCAUSE + rsr abi_tmp0, excsave1 + addx4 abi_tmp0, abi_arg1, abi_tmp0 + l32i abi_tmp0, abi_tmp0, EXC_TABLE_DEFAULT # load handler mov abi_arg0, a1 # pass stack frame
/* Call the second-level handler */
- abi_callx a4 + abi_callx abi_tmp0
/* Jump here for exception exit */ .global common_exception_return diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 9345007d474d..5f86208c67c8 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -242,12 +242,8 @@ DEFINE_PER_CPU(unsigned long, nmi_count);
void do_nmi(struct pt_regs *regs) { - struct pt_regs *old_regs; + struct pt_regs *old_regs = set_irq_regs(regs);
- if ((regs->ps & PS_INTLEVEL_MASK) < LOCKLEVEL) - trace_hardirqs_off(); - - old_regs = set_irq_regs(regs); nmi_enter(); ++*this_cpu_ptr(&nmi_count); check_valid_nmi(); @@ -269,12 +265,9 @@ void do_interrupt(struct pt_regs *regs) XCHAL_INTLEVEL6_MASK, XCHAL_INTLEVEL7_MASK, }; - struct pt_regs *old_regs; + struct pt_regs *old_regs = set_irq_regs(regs); unsigned unhandled = ~0u;
- trace_hardirqs_off(); - - old_regs = set_irq_regs(regs); irq_enter();
for (;;) {
From: Wen Gong quic_wgong@quicinc.com
[ Upstream commit 7330e1ec9748948177830c6e1a13379835d577f9 ]
When test connect/disconnect to an AP frequently with WCN6855, sometimes it show below log.
[ 277.040121] wls1: deauthenticating from 8c:21:0a:b3:5a:64 by local choice (Reason: 3=DEAUTH_LEAVING) [ 277.050906] ath11k_pci 0000:05:00.0: wmi stats vdev id 0 mac 00:03:7f:29:61:11 [ 277.050944] ath11k_pci 0000:05:00.0: wmi stats bssid 8c:21:0a:b3:5a:64 vif pK-error [ 277.050954] ath11k_pci 0000:05:00.0: not found station for bssid 8c:21:0a:b3:5a:64 [ 277.050961] ath11k_pci 0000:05:00.0: failed to parse rssi chain -71 [ 277.050967] ath11k_pci 0000:05:00.0: failed to pull fw stats: -71 [ 277.050976] ath11k_pci 0000:05:00.0: wmi stats vdev id 0 mac 00:03:7f:29:61:11 [ 277.050983] ath11k_pci 0000:05:00.0: wmi stats bssid 8c:21:0a:b3:5a:64 vif pK-error [ 277.050989] ath11k_pci 0000:05:00.0: not found station for bssid 8c:21:0a:b3:5a:64 [ 277.050995] ath11k_pci 0000:05:00.0: failed to parse rssi chain -71 [ 277.051000] ath11k_pci 0000:05:00.0: failed to pull fw stats: -71 [ 278.064050] ath11k_pci 0000:05:00.0: failed to request fw stats: -110
Reason is: When running disconnect operation, sta_info removed from local->sta_hash by __sta_info_destroy_part1() from __sta_info_flush(), after this, ieee80211_find_sta_by_ifaddr() which called by ath11k_wmi_tlv_fw_stats_data_parse() and ath11k_wmi_tlv_rssi_chain_parse() cannot find this station, then failed log printed.
steps are like this: 1. when disconnect from AP, __sta_info_destroy() called __sta_info_destroy_part1() and __sta_info_destroy_part2().
2. in __sta_info_destroy_part1(), it has "sta_info_hash_del(local, sta)" and "list_del_rcu(&sta->list)", it will remove the ieee80211_sta from the list of ieee80211_hw.
3. in __sta_info_destroy_part2(), it called drv_sta_state()->ath11k_mac_op_sta_state(), then peer->sta is clear at this moment.
4. in __sta_info_destroy_part2(), it then called sta_set_sinfo()->drv_sta_statistics() ->ath11k_mac_op_sta_statistics(), then WMI_REQUEST_STATS_CMDID sent to firmware.
5. WMI_UPDATE_STATS_EVENTID reported from firmware, at this moment, the ieee80211_sta can not be found again because it has remove from list in step2 and also peer->sta is clear in step3.
6. in __sta_info_destroy_part2(), it then called cleanup_single_sta()-> sta_info_free()->kfree(sta), at this moment, the ieee80211_sta is freed in memory, then the failed log will not happen because function ath11k_mac_op_sta_state() will not be called.
Actually this print log is not a real error, it is only to skip parse the info, so change to skip print by default debug setting.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
Signed-off-by: Wen Gong quic_wgong@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220428022426.2927-1-quic_wgong@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/wmi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 2751fe8814df..0900f75eef20 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5789,9 +5789,9 @@ static int ath11k_wmi_tlv_rssi_chain_parse(struct ath11k_base *ab, arvif->bssid, NULL); if (!sta) { - ath11k_warn(ab, "not found station for bssid %pM\n", - arvif->bssid); - ret = -EPROTO; + ath11k_dbg(ab, ATH11K_DBG_WMI, + "not found station of bssid %pM for rssi chain\n", + arvif->bssid); goto exit; }
@@ -5889,8 +5889,9 @@ static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base *ab, "wmi stats vdev id %d snr %d\n", src->vdev_id, src->beacon_snr); } else { - ath11k_warn(ab, "not found station for bssid %pM\n", - arvif->bssid); + ath11k_dbg(ab, ATH11K_DBG_WMI, + "not found station of bssid %pM for vdev stat\n", + arvif->bssid); } }
From: Xiaoguang Wang xiaoguang.wang@linux.alibaba.com
[ Upstream commit bb9b9eb0ae2e9d3f6036f0ad907c3a83dcd43485 ]
When tcmu_vma_fault() gets a page successfully, before the current context completes page fault procedure, find_free_blocks() may run and call unmap_mapping_range() to unmap the page. Assume that when find_free_blocks() initially completes and the previous page fault procedure starts to run again and completes, then one truncated page has been mapped to userspace. But note that tcmu_vma_fault() has gotten a refcount for the page so any other subsystem won't be able to use the page unless the userspace address is unmapped later.
If another command subsequently runs and needs to extend dbi_thresh it may reuse the corresponding slot for the previous page in data_bitmap. Then though we'll allocate new page for this slot in data_area, no page fault will happen because we have a valid map and the real request's data will be lost.
Filesystem implementations will also run into this issue but they usually lock the page when vm_operations_struct->fault gets a page and unlock the page after finish_fault() completes. For truncate filesystems lock pages in truncate_inode_pages() to protect against racing wrt. page faults.
To fix this possible data corruption scenario we can apply a method similar to the filesystems. For pages that are to be freed, tcmu_blocks_release() locks and unlocks. Make tcmu_vma_fault() also lock found page under cmdr_lock. At the same time, since tcmu_vma_fault() gets an extra page refcount, tcmu_blocks_release() won't free pages if pages are in page fault procedure, which means it is safe to call tcmu_blocks_release() before unmap_mapping_range().
With these changes tcmu_blocks_release() will wait for all page faults to be completed before calling unmap_mapping_range(). And later, if unmap_mapping_range() is called, it will ensure stale mappings are removed.
Link: https://lore.kernel.org/r/20220421023735.9018-1-xiaoguang.wang@linux.alibaba... Reviewed-by: Bodo Stroesser bostroesser@gmail.com Signed-off-by: Xiaoguang Wang xiaoguang.wang@linux.alibaba.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_user.c | 40 ++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index fd7267baa707..b1fd06edea59 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -20,6 +20,7 @@ #include <linux/configfs.h> #include <linux/mutex.h> #include <linux/workqueue.h> +#include <linux/pagemap.h> #include <net/genetlink.h> #include <scsi/scsi_common.h> #include <scsi/scsi_proto.h> @@ -1667,6 +1668,26 @@ static u32 tcmu_blocks_release(struct tcmu_dev *udev, unsigned long first, xas_lock(&xas); xas_for_each(&xas, page, (last + 1) * udev->data_pages_per_blk - 1) { xas_store(&xas, NULL); + /* + * While reaching here there may be page faults occurring on + * the to-be-released pages. A race condition may occur if + * unmap_mapping_range() is called before page faults on these + * pages have completed; a valid but stale map is created. + * + * If another command subsequently runs and needs to extend + * dbi_thresh, it may reuse the slot corresponding to the + * previous page in data_bitmap. Though we will allocate a new + * page for the slot in data_area, no page fault will happen + * because we have a valid map. Therefore the command's data + * will be lost. + * + * We lock and unlock pages that are to be released to ensure + * all page faults have completed. This way + * unmap_mapping_range() can ensure stale maps are cleanly + * removed. + */ + lock_page(page); + unlock_page(page); __free_page(page); pages_freed++; } @@ -1822,6 +1843,7 @@ static struct page *tcmu_try_get_data_page(struct tcmu_dev *udev, uint32_t dpi) page = xa_load(&udev->data_pages, dpi); if (likely(page)) { get_page(page); + lock_page(page); mutex_unlock(&udev->cmdr_lock); return page; } @@ -1863,6 +1885,7 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf) struct page *page; unsigned long offset; void *addr; + vm_fault_t ret = 0;
int mi = tcmu_find_mem_index(vmf->vma); if (mi < 0) @@ -1887,10 +1910,11 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf) page = tcmu_try_get_data_page(udev, dpi); if (!page) return VM_FAULT_SIGBUS; + ret = VM_FAULT_LOCKED; }
vmf->page = page; - return 0; + return ret; }
static const struct vm_operations_struct tcmu_vm_ops = { @@ -3205,12 +3229,22 @@ static void find_free_blocks(void) udev->dbi_max = block; }
+ /* + * Release the block pages. + * + * Also note that since tcmu_vma_fault() gets an extra page + * refcount, tcmu_blocks_release() won't free pages if pages + * are mapped. This means it is safe to call + * tcmu_blocks_release() before unmap_mapping_range() which + * drops the refcount of any pages it unmaps and thus releases + * them. + */ + pages_freed = tcmu_blocks_release(udev, start, end - 1); + /* Here will truncate the data area from off */ off = udev->data_off + (loff_t)start * udev->data_blk_size; unmap_mapping_range(udev->inode->i_mapping, off, 0, 1);
- /* Release the block pages */ - pages_freed = tcmu_blocks_release(udev, start, end - 1); mutex_unlock(&udev->cmdr_lock);
total_pages_freed += pages_freed;
From: jianghaoran jianghaoran@kylinos.cn
[ Upstream commit b52e1cce31ca721e937d517411179f9196ee6135 ]
ARPHRD_TUNNEL interface can't process rs packets and will generate TX errors
ex: ip tunnel add ethn mode ipip local 192.168.1.1 remote 192.168.1.2 ifconfig ethn x.x.x.x
ethn: flags=209<UP,POINTOPOINT,RUNNING,NOARP> mtu 1480 inet x.x.x.x netmask 255.255.255.255 destination x.x.x.x inet6 fe80::5efe:ac1e:3cdb prefixlen 64 scopeid 0x20<link> tunnel txqueuelen 1000 (IPIP Tunnel) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 3 dropped 0 overruns 0 carrier 0 collisions 0
Signed-off-by: jianghaoran jianghaoran@kylinos.cn Link: https://lore.kernel.org/r/20220429053802.246681-1-jianghaoran@kylinos.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/addrconf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1afc4c024981..51e77dc6571a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4219,7 +4219,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id, send_rs = send_mld && ipv6_accept_ra(ifp->idev) && ifp->idev->cnf.rtr_solicits != 0 && - (dev->flags&IFF_LOOPBACK) == 0; + (dev->flags & IFF_LOOPBACK) == 0 && + (dev->type != ARPHRD_TUNNEL); read_unlock_bh(&ifp->idev->lock);
/* While dad is in progress mld report's source address is in6_addrany.
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit c389362096be8ee69ec3a163a0699a31e84b8451 ]
The memory of spec is allocated with kvzalloc(), the corresponding release function should not be kfree(), use kvfree() instead.
Generated by: scripts/coccinelle/api/kfree_mismatch.cocci
Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c index bec9ed0103a9..2b80fe73549d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c @@ -101,7 +101,7 @@ mlx5_ct_fs_smfs_matcher_create(struct mlx5_ct_fs *fs, struct mlx5dr_table *tbl, spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2 | MLX5_MATCH_OUTER_HEADERS;
dr_matcher = mlx5_smfs_matcher_create(tbl, priority, spec); - kfree(spec); + kvfree(spec); if (!dr_matcher) return ERR_PTR(-EINVAL);
From: Mark Bloch mbloch@nvidia.com
[ Upstream commit 7b0c6338597613f465d131bd939a51844a00455a ]
When an FTE has no children is means all the rules where removed and the FTE can be deleted regardless of the dests_size value. While dests_size should be 0 when there are no children be extra careful not to leak memory or get firmware syndrome if the proper bookkeeping of dests_size wasn't done.
Signed-off-by: Mark Bloch mbloch@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/fs_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 3ad67e6b5586..89ba72e8d109 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -2071,16 +2071,16 @@ void mlx5_del_flow_rules(struct mlx5_flow_handle *handle) down_write_ref_node(&fte->node, false); for (i = handle->num_rules - 1; i >= 0; i--) tree_remove_node(&handle->rule[i]->node, true); - if (fte->dests_size) { - if (fte->modify_mask) - modify_fte(fte); - up_write_ref_node(&fte->node, false); - } else if (list_empty(&fte->node.children)) { + if (list_empty(&fte->node.children)) { del_hw_fte(&fte->node); /* Avoid double call to del_hw_fte */ fte->node.del_hw_func = NULL; up_write_ref_node(&fte->node, false); tree_put_node(&fte->node, false); + } else if (fte->dests_size) { + if (fte->modify_mask) + modify_fte(fte); + up_write_ref_node(&fte->node, false); } else { up_write_ref_node(&fte->node, false); }
From: Mark Brown broonie@kernel.org
[ Upstream commit ad685980469b9f9b99d4d6ea05f4cb8f57cb2234 ]
DAPM tracks and reports the value presented to the user from DAPM controls separately to the register value, these may diverge during initialisation or when an autodisable control is in use.
When writing DAPM controls we currently report that a change has occurred if either the DAPM value or the value stored in the register has changed, meaning that if the two are out of sync we may appear to report a spurious event to userspace. Since we use this folded in value for nothing other than the value reported to userspace simply drop the folding in of the register change.
Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20220428161833.3690050-1-broonie@kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/soc-dapm.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index ca917a849c42..869c76506b66 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3437,7 +3437,6 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, update.val = val; card->update = &update; } - change |= reg_change;
ret = soc_dapm_mixer_update_power(card, kcontrol, connect, rconnect); @@ -3539,7 +3538,6 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, update.val = val; card->update = &update; } - change |= reg_change;
ret = soc_dapm_mux_update_power(card, kcontrol, item[0], e);
From: Peter Ujfalusi peter.ujfalusi@linux.intel.com
[ Upstream commit a962890a5a3cce903ff7c7a19fadee63ed9efdc7 ]
It is possible to craft a topology where sof_get_control_data() would do out of bounds access because it expects that it is only called when the payload is bytes type. Confusingly it also handles other types of controls, but the payload parsing implementation is only valid for bytes.
Fix the code to count the non bytes controls and instead of storing a pointer to sof_abi_hdr in sof_widget_data (which is only valid for bytes), store the pointer to the data itself and add a new member to save the size of the data.
In case of non bytes controls we store the pointer to the chanv itself, which is just an array of values at the end.
In case of bytes control, drop the wrong cdata->data (wdata[i].pdata) check against NULL since it is incorrect and invalid in this context. The data is pointing to the end of cdata struct, so it should never be null.
Reported-by: Sergey Senozhatsky senozhatsky@chromium.org Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Sergey Senozhatsky senozhatsky@chromium.org Tested-by: Sergey Senozhatsky senozhatsky@chromium.org Link: https://lore.kernel.org/r/20220427185221.28928-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 | 39 +++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-)
diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 2f8450a8c0a1..af1bbd34213c 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -20,7 +20,8 @@ struct sof_widget_data { int ctrl_type; int ipc_cmd; - struct sof_abi_hdr *pdata; + void *pdata; + size_t pdata_size; struct snd_sof_control *control; };
@@ -784,16 +785,26 @@ static int sof_get_control_data(struct snd_soc_component *scomp, }
cdata = wdata[i].control->ipc_control_data; - wdata[i].pdata = cdata->data; - if (!wdata[i].pdata) - return -EINVAL;
- /* make sure data is valid - data can be updated at runtime */ - if (widget->dobj.widget.kcontrol_type[i] == SND_SOC_TPLG_TYPE_BYTES && - wdata[i].pdata->magic != SOF_ABI_MAGIC) - return -EINVAL; + if (widget->dobj.widget.kcontrol_type[i] == SND_SOC_TPLG_TYPE_BYTES) { + /* make sure data is valid - data can be updated at runtime */ + if (cdata->data->magic != SOF_ABI_MAGIC) + return -EINVAL; + + wdata[i].pdata = cdata->data->data; + wdata[i].pdata_size = cdata->data->size; + } else { + /* points to the control data union */ + wdata[i].pdata = cdata->chanv; + /* + * wdata[i].control->size is calculated with struct_size + * and includes the size of struct sof_ipc_ctrl_data + */ + wdata[i].pdata_size = wdata[i].control->size - + sizeof(struct sof_ipc_ctrl_data); + }
- *size += wdata[i].pdata->size; + *size += wdata[i].pdata_size;
/* get data type */ switch (cdata->cmd) { @@ -876,10 +887,12 @@ static int sof_process_load(struct snd_soc_component *scomp, */ if (ipc_data_size) { for (i = 0; i < widget->num_kcontrols; i++) { - memcpy(&process->data[offset], - wdata[i].pdata->data, - wdata[i].pdata->size); - offset += wdata[i].pdata->size; + if (!wdata[i].pdata_size) + continue; + + memcpy(&process->data[offset], wdata[i].pdata, + wdata[i].pdata_size); + offset += wdata[i].pdata_size; } }
From: Petr Machata petrm@nvidia.com
[ Upstream commit b6b584562cbe7dc357083459d6dd5b171e12cadb ]
The idea behind the warnings is that the user would get warned in case when more than one priority is configured for a given DSCP value on a netdevice.
The warning is currently wrong, because dcb_ieee_getapp_mask() returns the first matching entry, not all of them, and the warning will then claim that some priority is "current", when in fact it is not.
But more importantly, the warning is misleading in general. Consider the following commands:
# dcb app flush dev swp19 dscp-prio # dcb app add dev swp19 dscp-prio 24:3 # dcb app replace dev swp19 dscp-prio 24:2
The last command will issue the following warning:
mlxsw_spectrum3 0000:07:00.0 swp19: Ignoring new priority 2 for DSCP 24 in favor of current value of 3
The reason is that the "replace" command works by first adding the new value, and then removing all old values. This is the only way to make the replacement without causing the traffic to be prioritized to whatever the chip defaults to. The warning is issued in response to adding the new priority, and then no warning is shown when the old priority is removed. The upshot is that the canonical way to change traffic prioritization always produces a warning about ignoring the new priority, but what gets configured is in fact what the user intended.
An option to just emit warning every time that the prioritization changes just to make it clear that it happened is obviously unsatisfactory.
Therefore, in this patch, remove the warnings.
Reported-by: Maksym Yaremchuk maksymy@nvidia.com Signed-off-by: Petr Machata petrm@nvidia.com Signed-off-by: Ido Schimmel idosch@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c | 13 ------------- 1 file changed, 13 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c index 5f92b1691360..aff6d4f35cd2 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c @@ -168,8 +168,6 @@ static int mlxsw_sp_dcbnl_ieee_setets(struct net_device *dev, static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev, struct dcb_app *app) { - int prio; - if (app->priority >= IEEE_8021QAZ_MAX_TCS) { netdev_err(dev, "APP entry with priority value %u is invalid\n", app->priority); @@ -183,17 +181,6 @@ static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev, app->protocol); return -EINVAL; } - - /* Warn about any DSCP APP entries with the same PID. */ - prio = fls(dcb_ieee_getapp_mask(dev, app)); - if (prio--) { - if (prio < app->priority) - netdev_warn(dev, "Choosing priority %d for DSCP %d in favor of previously-active value of %d\n", - app->priority, app->protocol, prio); - else if (prio > app->priority) - netdev_warn(dev, "Ignoring new priority %d for DSCP %d in favor of current value of %d\n", - app->priority, app->protocol, prio); - } break;
case IEEE_8021QAZ_APP_SEL_ETHERTYPE:
From: Petr Machata petrm@nvidia.com
[ Upstream commit 0106668cd2f91bf913fb78972840dedfba80a3c3 ]
When trapping packets for on-CPU processing, Spectrum machines differentiate between control and non-control traps. Traffic trapped through non-control traps is treated as data and kept in shared buffer in pools 0-4. Traffic trapped through control traps is kept in the dedicated control buffer 9. The advantage of marking traps as control is that pressure in the data plane does not prevent the control traffic to be processed.
When the LLDP trap was introduced, it was marked as a control trap. But then in commit aed4b5721143 ("mlxsw: spectrum: PTP: Hook into packet receive path"), PTP traps were introduced. Because Ethernet-encapsulated PTP packets look to the Spectrum-1 ASIC as LLDP traffic and are trapped under the LLDP trap, this trap was reconfigured as non-control, in sync with the PTP traps.
There is however no requirement that PTP traffic be handled as data. Besides, the usual encapsulation for PTP traffic is UDP, not bare Ethernet, and that is in deployments that even need PTP, which is far less common than LLDP. This is reflected by the default policer, which was not bumped up to the 19Kpps / 24Kpps that is the expected load of a PTP-enabled Spectrum-1 switch.
Marking of LLDP trap as non-control was therefore probably misguided. In this patch, change it back to control.
Reported-by: Maksym Yaremchuk maksymy@nvidia.com Signed-off-by: Petr Machata petrm@nvidia.com Signed-off-by: Ido Schimmel idosch@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c index 47b061b99160..ed4d0d3448f3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c @@ -864,7 +864,7 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = { .trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP), .listeners_arr = { MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU, - false, SP_LLDP, DISCARD), + true, SP_LLDP, DISCARD), }, }, {
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit b95b5391684b39695887afb4a13cccee7820f5d6 ]
Memory allocations should be done in sw_init. hw_init should just be hardware programming needed to initialize the IP block. This is how most other IP blocks work. Move the GPU memory allocations from psp hw_init to psp sw_init and move the memory free to sw_fini. This also fixes a potential GPU memory leak if psp hw_init fails.
Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 95 ++++++++++++------------- 1 file changed, 47 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index a6acec1a6155..21aa556a6bef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -357,7 +357,39 @@ static int psp_sw_init(void *handle) } }
+ ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, + amdgpu_sriov_vf(adev) ? + AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, + &psp->fw_pri_bo, + &psp->fw_pri_mc_addr, + &psp->fw_pri_buf); + if (ret) + return ret; + + ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &psp->fence_buf_bo, + &psp->fence_buf_mc_addr, + &psp->fence_buf); + if (ret) + goto failed1; + + ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, + (void **)&psp->cmd_buf_mem); + if (ret) + goto failed2; + return 0; + +failed2: + amdgpu_bo_free_kernel(&psp->fw_pri_bo, + &psp->fw_pri_mc_addr, &psp->fw_pri_buf); +failed1: + amdgpu_bo_free_kernel(&psp->fence_buf_bo, + &psp->fence_buf_mc_addr, &psp->fence_buf); + return ret; }
static int psp_sw_fini(void *handle) @@ -391,6 +423,13 @@ static int psp_sw_fini(void *handle) kfree(cmd); cmd = NULL;
+ amdgpu_bo_free_kernel(&psp->fw_pri_bo, + &psp->fw_pri_mc_addr, &psp->fw_pri_buf); + amdgpu_bo_free_kernel(&psp->fence_buf_bo, + &psp->fence_buf_mc_addr, &psp->fence_buf); + amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, + (void **)&psp->cmd_buf_mem); + return 0; }
@@ -2430,51 +2469,18 @@ static int psp_load_fw(struct amdgpu_device *adev) struct psp_context *psp = &adev->psp;
if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) { - psp_ring_stop(psp, PSP_RING_TYPE__KM); /* should not destroy ring, only stop */ - goto skip_memalloc; - } - - if (amdgpu_sriov_vf(adev)) { - ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, - AMDGPU_GEM_DOMAIN_VRAM, - &psp->fw_pri_bo, - &psp->fw_pri_mc_addr, - &psp->fw_pri_buf); + /* should not destroy ring, only stop */ + psp_ring_stop(psp, PSP_RING_TYPE__KM); } else { - ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG, - AMDGPU_GEM_DOMAIN_GTT, - &psp->fw_pri_bo, - &psp->fw_pri_mc_addr, - &psp->fw_pri_buf); - } - - if (ret) - goto failed; - - ret = amdgpu_bo_create_kernel(adev, PSP_FENCE_BUFFER_SIZE, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, - &psp->fence_buf_bo, - &psp->fence_buf_mc_addr, - &psp->fence_buf); - if (ret) - goto failed; - - ret = amdgpu_bo_create_kernel(adev, PSP_CMD_BUFFER_SIZE, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, - &psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, - (void **)&psp->cmd_buf_mem); - if (ret) - goto failed; + memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE);
- memset(psp->fence_buf, 0, PSP_FENCE_BUFFER_SIZE); - - ret = psp_ring_init(psp, PSP_RING_TYPE__KM); - if (ret) { - DRM_ERROR("PSP ring init failed!\n"); - goto failed; + ret = psp_ring_init(psp, PSP_RING_TYPE__KM); + if (ret) { + DRM_ERROR("PSP ring init failed!\n"); + goto failed; + } }
-skip_memalloc: ret = psp_hw_start(psp); if (ret) goto failed; @@ -2592,13 +2598,6 @@ static int psp_hw_fini(void *handle) psp_tmr_terminate(psp); psp_ring_destroy(psp, PSP_RING_TYPE__KM);
- amdgpu_bo_free_kernel(&psp->fw_pri_bo, - &psp->fw_pri_mc_addr, &psp->fw_pri_buf); - amdgpu_bo_free_kernel(&psp->fence_buf_bo, - &psp->fence_buf_mc_addr, &psp->fence_buf); - amdgpu_bo_free_kernel(&psp->cmd_buf_bo, &psp->cmd_buf_mc_addr, - (void **)&psp->cmd_buf_mem); - return 0; }
From: Alice Wong shiwei.wong@amd.com
[ Upstream commit ab0cd4a9ae5b4679b714d8dbfedc0901fecdce9f ]
When psp_hw_init failed, it will set the load_type to AMDGPU_FW_LOAD_DIRECT. During amdgpu_device_ip_fini, amdgpu_ucode_free_bo checks that load_type is AMDGPU_FW_LOAD_DIRECT and skips deallocating fw_buf causing memory leak. Remove load_type check in amdgpu_ucode_free_bo.
Signed-off-by: Alice Wong shiwei.wong@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/amdgpu_ucode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index ca3350502618..aebafbc327fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -714,8 +714,7 @@ int amdgpu_ucode_create_bo(struct amdgpu_device *adev)
void amdgpu_ucode_free_bo(struct amdgpu_device *adev) { - if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) - amdgpu_bo_free_kernel(&adev->firmware.fw_buf, + amdgpu_bo_free_kernel(&adev->firmware.fw_buf, &adev->firmware.fw_buf_mc, &adev->firmware.fw_buf_ptr); }
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit 6d435a94ba5bb4f2ad381c0828fbae89c66b50fe ]
The MT6315 PMIC dt-binding should enforce that one of the valid regulator-compatible is set in each regulator node. However it was mistakenly matching against regulator-name instead.
Fix the typo. This not only fixes the compatible verification, but also lifts the regulator-name restriction, so that more meaningful names can be set for each platform.
Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.com Link: https://lore.kernel.org/r/20220429201325.2205799-1-nfraprado@collabora.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../devicetree/bindings/regulator/mt6315-regulator.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml index 61dd5af80db6..5d2d989de893 100644 --- a/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml @@ -31,7 +31,7 @@ properties: $ref: "regulator.yaml#"
properties: - regulator-name: + regulator-compatible: pattern: "^vbuck[1-4]$"
additionalProperties: false
From: Jacob Keller jacob.e.keller@intel.com
[ Upstream commit baeb705fd6a7245cc1fa69ed991a9cffdf44a174 ]
The ice_get_vf_vsi function can return NULL in some cases, such as if handling messages during a reset where the VSI is being removed and recreated.
Several places throughout the driver do not bother to check whether this VSI pointer is valid. Static analysis tools maybe report issues because they detect paths where a potentially NULL pointer could be dereferenced.
Fix this by checking the return value of ice_get_vf_vsi everywhere.
Signed-off-by: Jacob Keller jacob.e.keller@intel.com Reviewed-by: Paul Menzel pmenzel@molgen.mpg.de Tested-by: Konrad Jankowski konrad0.jankowski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ice/ice_devlink.c | 5 ++- drivers/net/ethernet/intel/ice/ice_repr.c | 7 +++- drivers/net/ethernet/intel/ice/ice_sriov.c | 32 +++++++++++++++++-- drivers/net/ethernet/intel/ice/ice_vf_lib.c | 28 +++++++++++++++- drivers/net/ethernet/intel/ice/ice_virtchnl.c | 5 +++ .../ethernet/intel/ice/ice_virtchnl_fdir.c | 7 +++- 6 files changed, 77 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index a230edb38466..4a9de59121d8 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -753,9 +753,12 @@ int ice_devlink_create_vf_port(struct ice_vf *vf)
pf = vf->pf; dev = ice_pf_to_dev(pf); - vsi = ice_get_vf_vsi(vf); devlink_port = &vf->devlink_port;
+ vsi = ice_get_vf_vsi(vf); + if (!vsi) + return -EINVAL; + attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF; attrs.pci_vf.pf = pf->hw.bus.func; attrs.pci_vf.vf = vf->vf_id; diff --git a/drivers/net/ethernet/intel/ice/ice_repr.c b/drivers/net/ethernet/intel/ice/ice_repr.c index 848f2adea563..a91b81c3088b 100644 --- a/drivers/net/ethernet/intel/ice/ice_repr.c +++ b/drivers/net/ethernet/intel/ice/ice_repr.c @@ -293,8 +293,13 @@ static int ice_repr_add(struct ice_vf *vf) struct ice_q_vector *q_vector; struct ice_netdev_priv *np; struct ice_repr *repr; + struct ice_vsi *vsi; int err;
+ vsi = ice_get_vf_vsi(vf); + if (!vsi) + return -EINVAL; + repr = kzalloc(sizeof(*repr), GFP_KERNEL); if (!repr) return -ENOMEM; @@ -313,7 +318,7 @@ static int ice_repr_add(struct ice_vf *vf) goto err_alloc; }
- repr->src_vsi = ice_get_vf_vsi(vf); + repr->src_vsi = vsi; repr->vf = vf; vf->repr = repr; np = netdev_priv(repr->netdev); diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c index 0c438219f7a3..bb1721f1321d 100644 --- a/drivers/net/ethernet/intel/ice/ice_sriov.c +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c @@ -46,7 +46,12 @@ static void ice_free_vf_entries(struct ice_pf *pf) */ static void ice_vf_vsi_release(struct ice_vf *vf) { - ice_vsi_release(ice_get_vf_vsi(vf)); + struct ice_vsi *vsi = ice_get_vf_vsi(vf); + + if (WARN_ON(!vsi)) + return; + + ice_vsi_release(vsi); ice_vf_invalidate_vsi(vf); }
@@ -104,6 +109,8 @@ static void ice_dis_vf_mappings(struct ice_vf *vf)
hw = &pf->hw; vsi = ice_get_vf_vsi(vf); + if (WARN_ON(!vsi)) + return;
dev = ice_pf_to_dev(pf); wr32(hw, VPINT_ALLOC(vf->vf_id), 0); @@ -341,6 +348,9 @@ static void ice_ena_vf_q_mappings(struct ice_vf *vf, u16 max_txq, u16 max_rxq) struct ice_hw *hw = &vf->pf->hw; u32 reg;
+ if (WARN_ON(!vsi)) + return; + /* set regardless of mapping mode */ wr32(hw, VPLAN_TXQ_MAPENA(vf->vf_id), VPLAN_TXQ_MAPENA_TX_ENA_M);
@@ -386,6 +396,9 @@ static void ice_ena_vf_mappings(struct ice_vf *vf) { struct ice_vsi *vsi = ice_get_vf_vsi(vf);
+ if (WARN_ON(!vsi)) + return; + ice_ena_vf_msix_mappings(vf); ice_ena_vf_q_mappings(vf, vsi->alloc_txq, vsi->alloc_rxq); } @@ -1128,6 +1141,8 @@ static struct ice_vf *ice_get_vf_from_pfq(struct ice_pf *pf, u16 pfq) u16 rxq_idx;
vsi = ice_get_vf_vsi(vf); + if (!vsi) + continue;
ice_for_each_rxq(vsi, rxq_idx) if (vsi->rxq_map[rxq_idx] == pfq) { @@ -1521,8 +1536,15 @@ static int ice_calc_all_vfs_min_tx_rate(struct ice_pf *pf) static bool ice_min_tx_rate_oversubscribed(struct ice_vf *vf, int min_tx_rate) { - int link_speed_mbps = ice_get_link_speed_mbps(ice_get_vf_vsi(vf)); - int all_vfs_min_tx_rate = ice_calc_all_vfs_min_tx_rate(vf->pf); + struct ice_vsi *vsi = ice_get_vf_vsi(vf); + int all_vfs_min_tx_rate; + int link_speed_mbps; + + if (WARN_ON(!vsi)) + return false; + + link_speed_mbps = ice_get_link_speed_mbps(vsi); + all_vfs_min_tx_rate = ice_calc_all_vfs_min_tx_rate(vf->pf);
/* this VF's previous rate is being overwritten */ all_vfs_min_tx_rate -= vf->min_tx_rate; @@ -1566,6 +1588,10 @@ ice_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate, goto out_put_vf;
vsi = ice_get_vf_vsi(vf); + if (!vsi) { + ret = -EINVAL; + goto out_put_vf; + }
/* when max_tx_rate is zero that means no max Tx rate limiting, so only * check if max_tx_rate is non-zero diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index 6578059d9479..aefd66a4db80 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -220,8 +220,10 @@ static void ice_vf_clear_counters(struct ice_vf *vf) { struct ice_vsi *vsi = ice_get_vf_vsi(vf);
+ if (vsi) + vsi->num_vlan = 0; + vf->num_mac = 0; - vsi->num_vlan = 0; memset(&vf->mdd_tx_events, 0, sizeof(vf->mdd_tx_events)); memset(&vf->mdd_rx_events, 0, sizeof(vf->mdd_rx_events)); } @@ -251,6 +253,9 @@ static int ice_vf_rebuild_vsi(struct ice_vf *vf) struct ice_vsi *vsi = ice_get_vf_vsi(vf); struct ice_pf *pf = vf->pf;
+ if (WARN_ON(!vsi)) + return -EINVAL; + if (ice_vsi_rebuild(vsi, true)) { dev_err(ice_pf_to_dev(pf), "failed to rebuild VF %d VSI\n", vf->vf_id); @@ -514,6 +519,10 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) ice_trigger_vf_reset(vf, flags & ICE_VF_RESET_VFLR, false);
vsi = ice_get_vf_vsi(vf); + if (WARN_ON(!vsi)) { + err = -EIO; + goto out_unlock; + }
ice_dis_vf_qs(vf);
@@ -572,6 +581,11 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
vf->vf_ops->post_vsi_rebuild(vf); vsi = ice_get_vf_vsi(vf); + if (WARN_ON(!vsi)) { + err = -EINVAL; + goto out_unlock; + } + ice_eswitch_update_repr(vsi); ice_eswitch_replay_vf_mac_rule(vf);
@@ -610,6 +624,9 @@ void ice_dis_vf_qs(struct ice_vf *vf) { struct ice_vsi *vsi = ice_get_vf_vsi(vf);
+ if (WARN_ON(!vsi)) + return; + ice_vsi_stop_lan_tx_rings(vsi, ICE_NO_RESET, vf->vf_id); ice_vsi_stop_all_rx_rings(vsi); ice_set_vf_state_qs_dis(vf); @@ -790,6 +807,9 @@ static int ice_vf_rebuild_host_mac_cfg(struct ice_vf *vf) u8 broadcast[ETH_ALEN]; int status;
+ if (WARN_ON(!vsi)) + return -EINVAL; + if (ice_is_eswitch_mode_switchdev(vf->pf)) return 0;
@@ -875,6 +895,9 @@ static int ice_vf_rebuild_host_tx_rate_cfg(struct ice_vf *vf) struct ice_vsi *vsi = ice_get_vf_vsi(vf); int err;
+ if (WARN_ON(!vsi)) + return -EINVAL; + if (vf->min_tx_rate) { err = ice_set_min_bw_limit(vsi, (u64)vf->min_tx_rate * 1000); if (err) { @@ -938,6 +961,9 @@ void ice_vf_rebuild_host_cfg(struct ice_vf *vf) struct device *dev = ice_pf_to_dev(vf->pf); struct ice_vsi *vsi = ice_get_vf_vsi(vf);
+ if (WARN_ON(!vsi)) + return; + ice_vf_set_host_trust_cfg(vf);
if (ice_vf_rebuild_host_mac_cfg(vf)) diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c index 2889e050a4c9..5405a0e752cf 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -2392,6 +2392,11 @@ static int ice_vc_ena_vlan_stripping(struct ice_vf *vf) }
vsi = ice_get_vf_vsi(vf); + if (!vsi) { + v_ret = VIRTCHNL_STATUS_ERR_PARAM; + goto error_param; + } + if (vsi->inner_vlan_ops.ena_stripping(vsi, ETH_P_8021Q)) v_ret = VIRTCHNL_STATUS_ERR_PARAM;
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c index 8e38ee2faf58..b74ccbd1591a 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c @@ -1344,7 +1344,12 @@ static void ice_vf_fdir_dump_info(struct ice_vf *vf) pf = vf->pf; hw = &pf->hw; dev = ice_pf_to_dev(pf); - vf_vsi = pf->vsi[vf->lan_vsi_idx]; + vf_vsi = ice_get_vf_vsi(vf); + if (!vf_vsi) { + dev_dbg(dev, "VF %d: invalid VSI pointer\n", vf->vf_id); + return; + } + vsi_num = ice_get_hw_vsi_num(hw, vf_vsi->idx);
fd_size = rd32(hw, VSIQF_FD_SIZE(vsi_num));
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit fc4ef9d5724973193bfa5ebed181dba6de3a56db ]
There is a slab-out-of-bounds Write bug in hid-bigbenff driver. The problem is the driver assumes the device must have an input but some malicious devices violate this assumption.
Fix this by checking hid_device's input is non-empty before its usage.
Reported-by: syzkaller syzkaller@googlegroups.com Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-bigbenff.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c index 74ad8bf98bfd..e8c5e3ac9fff 100644 --- a/drivers/hid/hid-bigbenff.c +++ b/drivers/hid/hid-bigbenff.c @@ -347,6 +347,12 @@ static int bigben_probe(struct hid_device *hid, bigben->report = list_entry(report_list->next, struct hid_report, list);
+ if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + error = -ENODEV; + goto error_hw_stop; + } + hidinput = list_first_entry(&hid->inputs, struct hid_input, list); set_bit(FF_RUMBLE, hidinput->input->ffbit);
From: Thierry Reding treding@nvidia.com
[ Upstream commit cb7e1abc2c73633e1eefa168ab2dad6e838899c9 ]
When mapping the DMA-BUF attachment fails, map->sgt will be an ERR_PTR- encoded error code and the cleanup code would try to free that memory, which obviously would fail.
Zero out that pointer after extracting the error code when this happens so that kfree() can do the right thing.
Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/tegra/gem.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 0063403ab5e1..7c7dd84e6db8 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -88,6 +88,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ if (IS_ERR(map->sgt)) { dma_buf_detach(buf, map->attach); err = PTR_ERR(map->sgt); + map->sgt = NULL; goto free; }
From: Zhen Lei thunder.leizhen@huawei.com
[ Upstream commit 8af6b91f58341325bf74ecb0389ddc0039091d84 ]
When "crashkernel=X,high" is used, there may be two crash regions: high=crashk_res and low=crashk_low_res. But now the syscall kexec_file_load() only add crashk_res into "linux,usable-memory-range", this may cause the second kernel to have no available dma memory.
Fix it like kexec-tools does for option -c, add both 'high' and 'low' regions into the dtb.
Signed-off-by: Zhen Lei thunder.leizhen@huawei.com Acked-by: Rob Herring robh@kernel.org Acked-by: Baoquan He bhe@redhat.com Link: https://lore.kernel.org/r/20220506114402.365-6-thunder.leizhen@huawei.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/kexec.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c index b9bd1cff1793..8d374cc552be 100644 --- a/drivers/of/kexec.c +++ b/drivers/of/kexec.c @@ -386,6 +386,15 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image, crashk_res.end - crashk_res.start + 1); if (ret) goto out; + + if (crashk_low_res.end) { + ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, + "linux,usable-memory-range", + crashk_low_res.start, + crashk_low_res.end - crashk_low_res.start + 1); + if (ret) + goto out; + } }
/* add bootargs */
From: Charles Keepax ckeepax@opensource.cirrus.com
[ Upstream commit ff69ec96b87dccb3a29edef8cec5d4fefbbc2055 ]
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.
A fixup is also required to use the width directly rather than relying on the format in hw_params, now both little and big endian would be supported. It is worth noting this changes the behaviour of S24_LE to use a word length of 24 rather than 32. This would appear to be a correction since the fact S24_LE is stored as 32 bits should not be presented over the bus.
Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Link: https://lore.kernel.org/r/20220504170905.332415-26-ckeepax@opensource.cirrus... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/tscs454.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/codecs/tscs454.c b/sound/soc/codecs/tscs454.c index 7e1826d6f06f..32e6fa7b0a06 100644 --- a/sound/soc/codecs/tscs454.c +++ b/sound/soc/codecs/tscs454.c @@ -3120,18 +3120,17 @@ static int set_aif_sample_format(struct snd_soc_component *component, unsigned int width; int ret;
- switch (format) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (snd_pcm_format_width(format)) { + case 16: width = FV_WL_16; break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: width = FV_WL_20; break; - case SNDRV_PCM_FORMAT_S24_3LE: + case 24: width = FV_WL_24; break; - case SNDRV_PCM_FORMAT_S24_LE: - case SNDRV_PCM_FORMAT_S32_LE: + case 32: width = FV_WL_32; break; default: @@ -3326,6 +3325,7 @@ static const struct snd_soc_component_driver soc_component_dev_tscs454 = { .num_dapm_routes = ARRAY_SIZE(tscs454_intercon), .controls = tscs454_snd_controls, .num_controls = ARRAY_SIZE(tscs454_snd_controls), + .endianness = 1, };
#define TSCS454_RATES SNDRV_PCM_RATE_8000_96000
From: Gavin Li gavinl@nvidia.com
[ Upstream commit 37ca95e62ee23fa6d2c2c64e3dc40b4a0c0146dc ]
Currently, health recovery will reload driver to recover it from fatal errors. During the driver's load process, it would wait for FW to set the pre-init bit for up to 120 seconds, beyond this threshold it would abort the load process. In some cases, such as a FW upgrade on the DPU, this timeout period is insufficient, and the user has no way to recover the host device.
To solve this issue, introduce a new FW pre-init timeout for health recovery, which is set to 2 hours.
The timeout for devlink reload and probe will use the original one because they are user triggered flows, and therefore should not have a significantly long timeout, during which the user command would hang.
Signed-off-by: Gavin Li gavinl@nvidia.com Reviewed-by: Moshe Shemesh moshe@nvidia.com Reviewed-by: Shay Drory shayd@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/mellanox/mlx5/core/devlink.c | 4 ++-- .../ethernet/mellanox/mlx5/core/fw_reset.c | 2 +- .../ethernet/mellanox/mlx5/core/lib/tout.c | 1 + .../ethernet/mellanox/mlx5/core/lib/tout.h | 1 + .../net/ethernet/mellanox/mlx5/core/main.c | 23 +++++++++++-------- .../ethernet/mellanox/mlx5/core/mlx5_core.h | 2 +- 6 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index 057dde6f4417..9401127fb0ec 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -178,13 +178,13 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a *actions_performed = BIT(action); switch (action) { case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: - return mlx5_load_one(dev); + return mlx5_load_one(dev, false); case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET) break; /* On fw_activate action, also driver is reloaded and reinit performed */ *actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); - return mlx5_load_one(dev); + return mlx5_load_one(dev, false); default: /* Unsupported action should not get to this function */ WARN_ON(1); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c index 81eb67fb95b0..052af4901c0b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c @@ -149,7 +149,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) { complete(&fw_reset->done); } else { - mlx5_load_one(dev); + mlx5_load_one(dev, false); devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0, BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) | BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE)); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c index c1df0d3595d8..d758848d34d0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c @@ -10,6 +10,7 @@ struct mlx5_timeouts {
static const u32 tout_def_sw_val[MAX_TIMEOUT_TYPES] = { [MLX5_TO_FW_PRE_INIT_TIMEOUT_MS] = 120000, + [MLX5_TO_FW_PRE_INIT_ON_RECOVERY_TIMEOUT_MS] = 7200000, [MLX5_TO_FW_PRE_INIT_WARN_MESSAGE_INTERVAL_MS] = 20000, [MLX5_TO_FW_PRE_INIT_WAIT_MS] = 2, [MLX5_TO_FW_INIT_MS] = 2000, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h index 1c42ead782fa..257c03eeab36 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.h @@ -7,6 +7,7 @@ enum mlx5_timeouts_types { /* pre init timeouts (not read from FW) */ MLX5_TO_FW_PRE_INIT_TIMEOUT_MS, + MLX5_TO_FW_PRE_INIT_ON_RECOVERY_TIMEOUT_MS, MLX5_TO_FW_PRE_INIT_WARN_MESSAGE_INTERVAL_MS, MLX5_TO_FW_PRE_INIT_WAIT_MS,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index ef196cb764e2..8b5263699994 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1014,7 +1014,7 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev) mlx5_devcom_unregister_device(dev->priv.devcom); }
-static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot) +static int mlx5_function_setup(struct mlx5_core_dev *dev, u64 timeout) { int err;
@@ -1029,11 +1029,11 @@ static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot)
/* wait for firmware to accept initialization segments configurations */ - err = wait_fw_init(dev, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT), + err = wait_fw_init(dev, timeout, mlx5_tout_ms(dev, FW_PRE_INIT_WARN_MESSAGE_INTERVAL)); if (err) { mlx5_core_err(dev, "Firmware over %llu MS in pre-initializing state, aborting\n", - mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT)); + timeout); return err; }
@@ -1296,7 +1296,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev) mutex_lock(&dev->intf_state_mutex); dev->state = MLX5_DEVICE_STATE_UP;
- err = mlx5_function_setup(dev, true); + err = mlx5_function_setup(dev, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT)); if (err) goto err_function;
@@ -1360,9 +1360,10 @@ void mlx5_uninit_one(struct mlx5_core_dev *dev) mutex_unlock(&dev->intf_state_mutex); }
-int mlx5_load_one(struct mlx5_core_dev *dev) +int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery) { int err = 0; + u64 timeout;
mutex_lock(&dev->intf_state_mutex); if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) { @@ -1372,7 +1373,11 @@ int mlx5_load_one(struct mlx5_core_dev *dev) /* remove any previous indication of internal error */ dev->state = MLX5_DEVICE_STATE_UP;
- err = mlx5_function_setup(dev, false); + if (recovery) + timeout = mlx5_tout_ms(dev, FW_PRE_INIT_ON_RECOVERY_TIMEOUT); + else + timeout = mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT); + err = mlx5_function_setup(dev, timeout); if (err) goto err_function;
@@ -1746,7 +1751,7 @@ static void mlx5_pci_resume(struct pci_dev *pdev)
mlx5_pci_trace(dev, "Enter, loading driver..\n");
- err = mlx5_load_one(dev); + err = mlx5_load_one(dev, false);
mlx5_pci_trace(dev, "Done, err = %d, device %s\n", err, !err ? "recovered" : "Failed"); @@ -1833,7 +1838,7 @@ static int mlx5_resume(struct pci_dev *pdev) { struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
- return mlx5_load_one(dev); + return mlx5_load_one(dev, false); }
static const struct pci_device_id mlx5_core_pci_table[] = { @@ -1878,7 +1883,7 @@ int mlx5_recover_device(struct mlx5_core_dev *dev) return -EIO; }
- return mlx5_load_one(dev); + return mlx5_load_one(dev, true); }
static struct pci_driver mlx5_core_driver = { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h index a9b2d6ead542..9026be1d6223 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h @@ -290,7 +290,7 @@ void mlx5_mdev_uninit(struct mlx5_core_dev *dev); int mlx5_init_one(struct mlx5_core_dev *dev); void mlx5_uninit_one(struct mlx5_core_dev *dev); void mlx5_unload_one(struct mlx5_core_dev *dev); -int mlx5_load_one(struct mlx5_core_dev *dev); +int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery);
int mlx5_vport_get_other_func_cap(struct mlx5_core_dev *dev, u16 function_id, void *out);
From: Brent Lu brent.lu@intel.com
[ Upstream commit d1c808765deb2bcd35d827402ed4d75d068aae18 ]
The SOF topology supports 2 BE Links(dmic01 and dmic16k) and each link supports up to four DMICs. However, Chromebook does not implement ACPI NHLT table so the mach->mach_params.dmic_num is always zero. We add a quirk so machine driver knows it's running on a Chromebook and need to create BE Links for DMIC.
Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com Signed-off-by: Brent Lu brent.lu@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20220509170922.54868-3-pierre-louis.bossart@linux.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/intel/boards/sof_ssp_amp.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 88530e9de543..ef70c6f27fe1 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -9,6 +9,7 @@
#include <linux/acpi.h> #include <linux/delay.h> +#include <linux/dmi.h> #include <linux/module.h> #include <linux/platform_device.h> #include <sound/core.h> @@ -78,6 +79,16 @@ struct sof_card_private { bool idisp_codec; };
+static const struct dmi_system_id chromebook_platforms[] = { + { + .ident = "Google Chromebooks", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + } + }, + {}, +}; + static const struct snd_soc_dapm_widget sof_ssp_amp_dapm_widgets[] = { SND_SOC_DAPM_MIC("SoC DMIC", NULL), }; @@ -371,7 +382,7 @@ static int sof_ssp_amp_probe(struct platform_device *pdev) struct snd_soc_dai_link *dai_links; struct snd_soc_acpi_mach *mach; struct sof_card_private *ctx; - int dmic_be_num, hdmi_num = 0; + int dmic_be_num = 0, hdmi_num = 0; int ret, ssp_codec;
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); @@ -383,7 +394,8 @@ static int sof_ssp_amp_probe(struct platform_device *pdev)
mach = pdev->dev.platform_data;
- dmic_be_num = mach->mach_params.dmic_num; + if (dmi_check_system(chromebook_platforms) || mach->mach_params.dmic_num > 0) + dmic_be_num = 2;
ssp_codec = sof_ssp_amp_quirk & SOF_AMPLIFIER_SSP_MASK;
From: Xiang Chen chenxiang66@hisilicon.com
[ Upstream commit 9b5387fe5af38116b452259d87cd66594b6277c1 ]
If we fail to notify the phy up event then undo the RPM resume, as the phy up notify event handling pairs with that RPM resume.
Link: https://lore.kernel.org/r/1651839939-101188-1-git-send-email-john.garry@huaw... Reported-by: Yihang Li liyihang6@hisilicon.com Tested-by: Yihang Li liyihang6@hisilicon.com Signed-off-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 79f87d7c3e68..7d819fc0395e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1563,9 +1563,15 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
phy->port_id = port_id;
- /* Call pm_runtime_put_sync() with pairs in hisi_sas_phyup_pm_work() */ + /* + * Call pm_runtime_get_noresume() which pairs with + * hisi_sas_phyup_pm_work() -> pm_runtime_put_sync(). + * For failure call pm_runtime_put() as we are in a hardirq context. + */ pm_runtime_get_noresume(dev); - hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP_PM); + res = hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP_PM); + if (!res) + pm_runtime_put(dev);
res = IRQ_HANDLED;
From: James Smart jsmart2021@gmail.com
[ Upstream commit ead76d4c09b89f4c8d632648026a476a5a34fde8 ]
After running a short external loopback test, when the external loopback is removed and a normal cable inserted that is directly connected to a target device, the system oops in the llpfc_set_rrq_active() routine.
When the loopback was inserted an FLOGI was transmit. As we're looped back, we receive the FLOGI request. The FLOGI is ABTS'd as we recognize the same wppn thus understand it's a loopback. However, as the ABTS sends address information the port is not set to (fffffe), the ABTS is dropped on the wire. A short 1 frame loopback test is run and completes before the ABTS times out. The looback is unplugged and the new cable plugged in, and the an FLOGI to the new device occurs and completes. Due to a mixup in ref counting the completion of the new FLOGI releases the fabric ndlp. Then the original ABTS completes and references the released ndlp generating the oops.
Correct by no-op'ing the ABTS when in loopback mode (it will be dropped anyway). Added a flag to track the mode to recognize when it should be no-op'd.
Link: https://lore.kernel.org/r/20220506035519.50908-5-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 12 ++++++++++++ drivers/scsi/lpfc/lpfc_hbadisc.c | 3 +++ drivers/scsi/lpfc/lpfc_sli.c | 8 +++++--- 4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 0025760230e5..da5e91a91151 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1025,6 +1025,7 @@ struct lpfc_hba { #define LS_MDS_LINK_DOWN 0x8 /* MDS Diagnostics Link Down */ #define LS_MDS_LOOPBACK 0x10 /* MDS Diagnostics Link Up (Loopback) */ #define LS_CT_VEN_RPA 0x20 /* Vendor RPA sent to switch */ +#define LS_EXTERNAL_LOOPBACK 0x40 /* External loopback plug inserted */
uint32_t hba_flag; /* hba generic flags */ #define HBA_ERATT_HANDLED 0x1 /* This flag is set when eratt handled */ diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 46a01a51b207..9545a35f0777 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1387,6 +1387,9 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
phba->hba_flag |= (HBA_FLOGI_ISSUED | HBA_FLOGI_OUTSTANDING);
+ /* Clear external loopback plug detected flag */ + phba->link_flag &= ~LS_EXTERNAL_LOOPBACK; + /* Check for a deferred FLOGI ACC condition */ if (phba->defer_flogi_acc_flag) { /* lookup ndlp for received FLOGI */ @@ -8182,6 +8185,9 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, uint32_t fc_flag = 0; uint32_t port_state = 0;
+ /* Clear external loopback plug detected flag */ + phba->link_flag &= ~LS_EXTERNAL_LOOPBACK; + cmd = *lp++; sp = (struct serv_parm *) lp;
@@ -8233,6 +8239,12 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, return 1; }
+ /* External loopback plug insertion detected */ + phba->link_flag |= LS_EXTERNAL_LOOPBACK; + + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_LIBDFC, + "1119 External Loopback plug detected\n"); + /* abort the flogi coming back to ourselves * due to external loopback on the port. */ diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2b877dff5ed4..6b6b3790d7b5 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1221,6 +1221,9 @@ lpfc_linkdown(struct lpfc_hba *phba)
phba->defer_flogi_acc_flag = false;
+ /* Clear external loopback plug detected flag */ + phba->link_flag &= ~LS_EXTERNAL_LOOPBACK; + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE); spin_unlock_irq(&phba->hbalock); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index a174e06bd96e..11f907278f09 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12202,7 +12202,8 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
if (phba->link_state < LPFC_LINK_UP || (phba->sli_rev == LPFC_SLI_REV4 && - phba->sli4_hba.link_state.status == LPFC_FC_LA_TYPE_LINK_DOWN)) + phba->sli4_hba.link_state.status == LPFC_FC_LA_TYPE_LINK_DOWN) || + (phba->link_flag & LS_EXTERNAL_LOOPBACK)) ia = true; else ia = false; @@ -12661,7 +12662,8 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, ndlp = lpfc_cmd->rdata->pnode;
if (lpfc_is_link_up(phba) && - (ndlp && ndlp->nlp_state == NLP_STE_MAPPED_NODE)) + (ndlp && ndlp->nlp_state == NLP_STE_MAPPED_NODE) && + !(phba->link_flag & LS_EXTERNAL_LOOPBACK)) ia = false; else ia = true; @@ -21126,7 +21128,7 @@ lpfc_sli4_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, abtswqe = &abtsiocb->wqe; memset(abtswqe, 0, sizeof(*abtswqe));
- if (!lpfc_is_link_up(phba)) + if (!lpfc_is_link_up(phba) || (phba->link_flag & LS_EXTERNAL_LOOPBACK)) bf_set(abort_cmd_ia, &abtswqe->abort_cmd, 1); bf_set(abort_cmd_criteria, &abtswqe->abort_cmd, T_XRI_TAG); abtswqe->abort_cmd.rsrvd5 = 0;
From: James Smart jsmart2021@gmail.com
[ Upstream commit e6f51041450282a8668af3a8fc5c7744e81a447c ]
When configuring CMF management based on signals instead of FPINs, FPIN alarm and warning statistics are not tracked.
Change the behavior so that FPIN alarms and warnings are always tracked regardless of the configured mode.
Similar changes are made in the CMF signal stat accounting logic. Upon receipt of a signal, only track signaled alarms and warnings. FPIN stats should not be incremented upon receipt of a signal.
Link: https://lore.kernel.org/r/20220506035519.50908-11-jsmart2021@gmail.com Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_els.c | 49 +++++++++++------------------------ drivers/scsi/lpfc/lpfc_init.c | 22 ++-------------- 2 files changed, 17 insertions(+), 54 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9545a35f0777..892b3da1ba45 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3877,9 +3877,6 @@ lpfc_least_capable_settings(struct lpfc_hba *phba, { u32 rsp_sig_cap = 0, drv_sig_cap = 0; u32 rsp_sig_freq_cyc = 0, rsp_sig_freq_scale = 0; - struct lpfc_cgn_info *cp; - u32 crc; - u16 sig_freq;
/* Get rsp signal and frequency capabilities. */ rsp_sig_cap = be32_to_cpu(pcgd->xmt_signal_capability); @@ -3935,25 +3932,7 @@ lpfc_least_capable_settings(struct lpfc_hba *phba, } }
- if (!phba->cgn_i) - return; - - /* Update signal frequency in congestion info buffer */ - cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; - - /* Frequency (in ms) Signal Warning/Signal Congestion Notifications - * are received by the HBA - */ - sig_freq = phba->cgn_sig_freq; - - if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY) - cp->cgn_warn_freq = cpu_to_le16(sig_freq); - if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) { - cp->cgn_alarm_freq = cpu_to_le16(sig_freq); - cp->cgn_warn_freq = cpu_to_le16(sig_freq); - } - crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED); - cp->cgn_info_crc = cpu_to_le32(crc); + /* We are NOT recording signal frequency in congestion info buffer */ return;
out_no_support: @@ -9971,11 +9950,14 @@ lpfc_els_rcv_fpin_cgn(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) /* Take action here for an Alarm event */ if (phba->cmf_active_mode != LPFC_CFG_OFF) { if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_ALARM) { - /* Track of alarm cnt for cgn_info */ - atomic_inc(&phba->cgn_fabric_alarm_cnt); /* Track of alarm cnt for SYNC_WQE */ atomic_inc(&phba->cgn_sync_alarm_cnt); } + /* Track alarm cnt for cgn_info regardless + * of whether CMF is configured for Signals + * or FPINs. + */ + atomic_inc(&phba->cgn_fabric_alarm_cnt); goto cleanup; } break; @@ -9983,11 +9965,14 @@ lpfc_els_rcv_fpin_cgn(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) /* Take action here for a Warning event */ if (phba->cmf_active_mode != LPFC_CFG_OFF) { if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_WARN) { - /* Track of warning cnt for cgn_info */ - atomic_inc(&phba->cgn_fabric_warn_cnt); /* Track of warning cnt for SYNC_WQE */ atomic_inc(&phba->cgn_sync_warn_cnt); } + /* Track warning cnt and freq for cgn_info + * regardless of whether CMF is configured for + * Signals or FPINs. + */ + atomic_inc(&phba->cgn_fabric_warn_cnt); cleanup: /* Save frequency in ms */ phba->cgn_fpin_frequency = @@ -9996,14 +9981,10 @@ lpfc_els_rcv_fpin_cgn(struct lpfc_hba *phba, struct fc_tlv_desc *tlv) if (phba->cgn_i) { cp = (struct lpfc_cgn_info *) phba->cgn_i->virt; - if (phba->cgn_reg_fpin & - LPFC_CGN_FPIN_ALARM) - cp->cgn_alarm_freq = - cpu_to_le16(value); - if (phba->cgn_reg_fpin & - LPFC_CGN_FPIN_WARN) - cp->cgn_warn_freq = - cpu_to_le16(value); + cp->cgn_alarm_freq = + cpu_to_le16(value); + cp->cgn_warn_freq = + cpu_to_le16(value); crc = lpfc_cgn_calc_crc32 (cp, LPFC_CGN_INFO_SZ, diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f9cd4b72d949..011849c1ed3c 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5866,21 +5866,8 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba)
/* Use the frequency found in the last rcv'ed FPIN */ value = phba->cgn_fpin_frequency; - if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_WARN) - cp->cgn_warn_freq = cpu_to_le16(value); - if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_ALARM) - cp->cgn_alarm_freq = cpu_to_le16(value); - - /* Frequency (in ms) Signal Warning/Signal Congestion Notifications - * are received by the HBA - */ - value = phba->cgn_sig_freq; - - if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY || - phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) - cp->cgn_warn_freq = cpu_to_le16(value); - if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) - cp->cgn_alarm_freq = cpu_to_le16(value); + cp->cgn_warn_freq = cpu_to_le16(value); + cp->cgn_alarm_freq = cpu_to_le16(value);
lvalue = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED); @@ -6595,9 +6582,6 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) /* Alarm overrides warning, so check that first */ if (cgn_signal->alarm_cnt) { if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) { - /* Keep track of alarm cnt for cgn_info */ - atomic_add(cgn_signal->alarm_cnt, - &phba->cgn_fabric_alarm_cnt); /* Keep track of alarm cnt for CMF_SYNC_WQE */ atomic_add(cgn_signal->alarm_cnt, &phba->cgn_sync_alarm_cnt); @@ -6606,8 +6590,6 @@ lpfc_sli4_async_sli_evt(struct lpfc_hba *phba, struct lpfc_acqe_sli *acqe_sli) /* signal action needs to be taken */ if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY || phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) { - /* Keep track of warning cnt for cgn_info */ - atomic_add(cnt, &phba->cgn_fabric_warn_cnt); /* Keep track of warning cnt for CMF_SYNC_WQE */ atomic_add(cnt, &phba->cgn_sync_warn_cnt); }
From: Eric Dumazet edumazet@google.com
[ Upstream commit d7ea0d9df2a6265b2b180d17ebc64b38105968fc ]
I have a syzbot report that managed to get a crash in skb_checksum_help()
If syzbot can trigger these BUG(), it makes sense to replace them with more friendly WARN_ON_ONCE() since skb_checksum_help() can instead return an error code.
Note that syzbot will still crash there, until real bug is fixed.
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/core/dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c index 2771fd22dc6a..0784c339cd7d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3215,11 +3215,15 @@ int skb_checksum_help(struct sk_buff *skb) }
offset = skb_checksum_start_offset(skb); - BUG_ON(offset >= skb_headlen(skb)); + ret = -EINVAL; + if (WARN_ON_ONCE(offset >= skb_headlen(skb))) + goto out; + csum = skb_checksum(skb, offset, skb->len - offset, 0);
offset += skb->csum_offset; - BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb)); + if (WARN_ON_ONCE(offset + sizeof(__sum16) > skb_headlen(skb))) + goto out;
ret = skb_ensure_writable(skb, offset + sizeof(__sum16)); if (ret)
From: Heiko Carstens hca@linux.ibm.com
[ Upstream commit 63678eecec57fc51b778be3da35a397931287170 ]
gcc 12 does not (always) optimize away code that should only be generated if parameters are constant and within in a certain range. This depends on various obscure kernel config options, however in particular PROFILE_ALL_BRANCHES can trigger this compile error:
In function ‘__atomic_add_const’, inlined from ‘__preempt_count_add.part.0’ at ./arch/s390/include/asm/preempt.h:50:3: ./arch/s390/include/asm/atomic_ops.h:80:9: error: impossible constraint in ‘asm’ 80 | asm volatile( \ | ^~~
Workaround this by simply disabling the optimization for PROFILE_ALL_BRANCHES, since the kernel will be so slow, that this optimization won't matter at all.
Reported-by: Thomas Richter tmricht@linux.ibm.com Reviewed-by: Sven Schnelle svens@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/include/asm/preempt.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h index d9d5350cc3ec..bf15da0fedbc 100644 --- a/arch/s390/include/asm/preempt.h +++ b/arch/s390/include/asm/preempt.h @@ -46,10 +46,17 @@ static inline bool test_preempt_need_resched(void)
static inline void __preempt_count_add(int val) { - if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) - __atomic_add_const(val, &S390_lowcore.preempt_count); - else - __atomic_add(val, &S390_lowcore.preempt_count); + /* + * With some obscure config options and CONFIG_PROFILE_ALL_BRANCHES + * enabled, gcc 12 fails to handle __builtin_constant_p(). + */ + if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) { + if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) { + __atomic_add_const(val, &S390_lowcore.preempt_count); + return; + } + } + __atomic_add(val, &S390_lowcore.preempt_count); }
static inline void __preempt_count_sub(int val)
From: Ravi Bangoria ravi.bangoria@amd.com
[ Upstream commit 39b2ca75eec8a33e2ffdb8aa0c4840ec3e3b472c ]
IBS pmu initialization code ignores return value provided by callee functions. Fix it.
Signed-off-by: Ravi Bangoria ravi.bangoria@amd.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lore.kernel.org/r/20220509044914.1473-2-ravi.bangoria@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/amd/ibs.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 9739019d4b67..367ca899e6e8 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -759,9 +759,10 @@ static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name) return ret; }
-static __init void perf_event_ibs_init(void) +static __init int perf_event_ibs_init(void) { struct attribute **attr = ibs_op_format_attrs; + int ret;
/* * Some chips fail to reset the fetch count when it is written; instead @@ -773,7 +774,9 @@ static __init void perf_event_ibs_init(void) if (boot_cpu_data.x86 == 0x19 && boot_cpu_data.x86_model < 0x10) perf_ibs_fetch.fetch_ignore_if_zero_rip = 1;
- perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); + ret = perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); + if (ret) + return ret;
if (ibs_caps & IBS_CAPS_OPCNT) { perf_ibs_op.config_mask |= IBS_OP_CNT_CTL; @@ -786,15 +789,35 @@ static __init void perf_event_ibs_init(void) perf_ibs_op.cnt_mask |= IBS_OP_MAX_CNT_EXT_MASK; }
- perf_ibs_pmu_init(&perf_ibs_op, "ibs_op"); + ret = perf_ibs_pmu_init(&perf_ibs_op, "ibs_op"); + if (ret) + goto err_op; + + ret = register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs"); + if (ret) + goto err_nmi;
- register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs"); pr_info("perf: AMD IBS detected (0x%08x)\n", ibs_caps); + return 0; + +err_nmi: + perf_pmu_unregister(&perf_ibs_op.pmu); + free_percpu(perf_ibs_op.pcpu); + perf_ibs_op.pcpu = NULL; +err_op: + perf_pmu_unregister(&perf_ibs_fetch.pmu); + free_percpu(perf_ibs_fetch.pcpu); + perf_ibs_fetch.pcpu = NULL; + + return ret; }
#else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
-static __init void perf_event_ibs_init(void) { } +static __init int perf_event_ibs_init(void) +{ + return 0; +}
#endif
@@ -1064,9 +1087,7 @@ static __init int amd_ibs_init(void) x86_pmu_amd_ibs_starting_cpu, x86_pmu_amd_ibs_dying_cpu);
- perf_event_ibs_init(); - - return 0; + return perf_event_ibs_init(); }
/* Since we need the pci subsystem to init ibs we can't do this earlier: */
From: Hao Jia jiahao.os@bytedance.com
[ Upstream commit 2679a83731d51a744657f718fc02c3b077e47562 ]
When we use raw_spin_rq_lock() to acquire the rq lock and have to update the rq clock while holding the lock, the kernel may issue a WARN_DOUBLE_CLOCK warning.
Since we directly use raw_spin_rq_lock() to acquire rq lock instead of rq_lock(), there is no corresponding change to rq->clock_update_flags. In particular, we have obtained the rq lock of other CPUs, the rq->clock_update_flags of this CPU may be RQCF_UPDATED at this time, and then calling update_rq_clock() will trigger the WARN_DOUBLE_CLOCK warning.
So we need to clear RQCF_UPDATED of rq->clock_update_flags to avoid the WARN_DOUBLE_CLOCK warning.
For the sched_rt_period_timer() and migrate_task_rq_dl() cases we simply replace raw_spin_rq_lock()/raw_spin_rq_unlock() with rq_lock()/rq_unlock().
For the {pull,push}_{rt,dl}_task() cases, we add the double_rq_clock_clear_update() function to clear RQCF_UPDATED of rq->clock_update_flags, and call double_rq_clock_clear_update() before double_lock_balance()/double_rq_lock() returns to avoid the WARN_DOUBLE_CLOCK warning.
Some call trace reports: Call Trace 1: <IRQ> sched_rt_period_timer+0x10f/0x3a0 ? enqueue_top_rt_rq+0x110/0x110 __hrtimer_run_queues+0x1a9/0x490 hrtimer_interrupt+0x10b/0x240 __sysvec_apic_timer_interrupt+0x8a/0x250 sysvec_apic_timer_interrupt+0x9a/0xd0 </IRQ> <TASK> asm_sysvec_apic_timer_interrupt+0x12/0x20
Call Trace 2: <TASK> activate_task+0x8b/0x110 push_rt_task.part.108+0x241/0x2c0 push_rt_tasks+0x15/0x30 finish_task_switch+0xaa/0x2e0 ? __switch_to+0x134/0x420 __schedule+0x343/0x8e0 ? hrtimer_start_range_ns+0x101/0x340 schedule+0x4e/0xb0 do_nanosleep+0x8e/0x160 hrtimer_nanosleep+0x89/0x120 ? hrtimer_init_sleeper+0x90/0x90 __x64_sys_nanosleep+0x96/0xd0 do_syscall_64+0x34/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
Call Trace 3: <TASK> deactivate_task+0x93/0xe0 pull_rt_task+0x33e/0x400 balance_rt+0x7e/0x90 __schedule+0x62f/0x8e0 do_task_dead+0x3f/0x50 do_exit+0x7b8/0xbb0 do_group_exit+0x2d/0x90 get_signal+0x9df/0x9e0 ? preempt_count_add+0x56/0xa0 ? __remove_hrtimer+0x35/0x70 arch_do_signal_or_restart+0x36/0x720 ? nanosleep_copyout+0x39/0x50 ? do_nanosleep+0x131/0x160 ? audit_filter_inodes+0xf5/0x120 exit_to_user_mode_prepare+0x10f/0x1e0 syscall_exit_to_user_mode+0x17/0x30 do_syscall_64+0x40/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
Call Trace 4: update_rq_clock+0x128/0x1a0 migrate_task_rq_dl+0xec/0x310 set_task_cpu+0x84/0x1e4 try_to_wake_up+0x1d8/0x5c0 wake_up_process+0x1c/0x30 hrtimer_wakeup+0x24/0x3c __hrtimer_run_queues+0x114/0x270 hrtimer_interrupt+0xe8/0x244 arch_timer_handler_phys+0x30/0x50 handle_percpu_devid_irq+0x88/0x140 generic_handle_domain_irq+0x40/0x60 gic_handle_irq+0x48/0xe0 call_on_irq_stack+0x2c/0x60 do_interrupt_handler+0x80/0x84
Steps to reproduce: 1. Enable CONFIG_SCHED_DEBUG when compiling the kernel 2. echo 1 > /sys/kernel/debug/clear_warn_once echo "WARN_DOUBLE_CLOCK" > /sys/kernel/debug/sched/features echo "NO_RT_PUSH_IPI" > /sys/kernel/debug/sched/features 3. Run some rt/dl tasks that periodically work and sleep, e.g. Create 2*n rt or dl (90% running) tasks via rt-app (on a system with n CPUs), and Dietmar Eggemann reports Call Trace 4 when running on PREEMPT_RT kernel.
Signed-off-by: Hao Jia jiahao.os@bytedance.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Dietmar Eggemann dietmar.eggemann@arm.com Link: https://lore.kernel.org/r/20220430085843.62939-2-jiahao.os@bytedance.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/core.c | 6 +++--- kernel/sched/deadline.c | 5 +++-- kernel/sched/rt.c | 5 +++-- kernel/sched/sched.h | 28 ++++++++++++++++++++++++---- 4 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d58c0389eb23..e58d894df207 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -610,10 +610,10 @@ void double_rq_lock(struct rq *rq1, struct rq *rq2) swap(rq1, rq2);
raw_spin_rq_lock(rq1); - if (__rq_lockp(rq1) == __rq_lockp(rq2)) - return; + if (__rq_lockp(rq1) != __rq_lockp(rq2)) + raw_spin_rq_lock_nested(rq2, SINGLE_DEPTH_NESTING);
- raw_spin_rq_lock_nested(rq2, SINGLE_DEPTH_NESTING); + double_rq_clock_clear_update(rq1, rq2); } #endif
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index fb4255ae0b2c..b61281d10458 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1832,6 +1832,7 @@ select_task_rq_dl(struct task_struct *p, int cpu, int flags)
static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused) { + struct rq_flags rf; struct rq *rq;
if (READ_ONCE(p->__state) != TASK_WAKING) @@ -1843,7 +1844,7 @@ static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused * from try_to_wake_up(). Hence, p->pi_lock is locked, but * rq->lock is not... So, lock it */ - raw_spin_rq_lock(rq); + rq_lock(rq, &rf); if (p->dl.dl_non_contending) { update_rq_clock(rq); sub_running_bw(&p->dl, &rq->dl); @@ -1859,7 +1860,7 @@ static void migrate_task_rq_dl(struct task_struct *p, int new_cpu __maybe_unused put_task_struct(p); } sub_rq_bw(&p->dl, &rq->dl); - raw_spin_rq_unlock(rq); + rq_unlock(rq, &rf); }
static void check_preempt_equal_dl(struct rq *rq, struct task_struct *p) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index a32c46889af8..7891c0f0e1ff 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -871,6 +871,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) int enqueue = 0; struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i); struct rq *rq = rq_of_rt_rq(rt_rq); + struct rq_flags rf; int skip;
/* @@ -885,7 +886,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) if (skip) continue;
- raw_spin_rq_lock(rq); + rq_lock(rq, &rf); update_rq_clock(rq);
if (rt_rq->rt_time) { @@ -923,7 +924,7 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
if (enqueue) sched_rt_rq_enqueue(rt_rq); - raw_spin_rq_unlock(rq); + rq_unlock(rq, &rf); }
if (!throttled && (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF)) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 8dccb34eb190..2133aea22086 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2478,6 +2478,24 @@ unsigned long arch_scale_freq_capacity(int cpu) } #endif
+#ifdef CONFIG_SCHED_DEBUG +/* + * In double_lock_balance()/double_rq_lock(), we use raw_spin_rq_lock() to + * acquire rq lock instead of rq_lock(). So at the end of these two functions + * we need to call double_rq_clock_clear_update() to clear RQCF_UPDATED of + * rq->clock_update_flags to avoid the WARN_DOUBLE_CLOCK warning. + */ +static inline void double_rq_clock_clear_update(struct rq *rq1, struct rq *rq2) +{ + rq1->clock_update_flags &= (RQCF_REQ_SKIP|RQCF_ACT_SKIP); + /* rq1 == rq2 for !CONFIG_SMP, so just clear RQCF_UPDATED once. */ +#ifdef CONFIG_SMP + rq2->clock_update_flags &= (RQCF_REQ_SKIP|RQCF_ACT_SKIP); +#endif +} +#else +static inline void double_rq_clock_clear_update(struct rq *rq1, struct rq *rq2) {} +#endif
#ifdef CONFIG_SMP
@@ -2543,14 +2561,15 @@ static inline int _double_lock_balance(struct rq *this_rq, struct rq *busiest) __acquires(busiest->lock) __acquires(this_rq->lock) { - if (__rq_lockp(this_rq) == __rq_lockp(busiest)) - return 0; - - if (likely(raw_spin_rq_trylock(busiest))) + if (__rq_lockp(this_rq) == __rq_lockp(busiest) || + likely(raw_spin_rq_trylock(busiest))) { + double_rq_clock_clear_update(this_rq, busiest); return 0; + }
if (rq_order_less(this_rq, busiest)) { raw_spin_rq_lock_nested(busiest, SINGLE_DEPTH_NESTING); + double_rq_clock_clear_update(this_rq, busiest); return 0; }
@@ -2644,6 +2663,7 @@ static inline void double_rq_lock(struct rq *rq1, struct rq *rq2) BUG_ON(rq1 != rq2); raw_spin_rq_lock(rq1); __acquire(rq2->lock); /* Fake it out ;) */ + double_rq_clock_clear_update(rq1, rq2); }
/*
From: Patrice Chotard patrice.chotard@foss.st.com
[ Upstream commit d83d89ea68b4726700fa87b22db075e4217e691c ]
In APM mode, TCF and TEF flags are not set. To avoid timeout in stm32_qspi_wait_cmd(), don't check if TCF/TEF are set.
Signed-off-by: Patrice Chotard patrice.chotard@foss.st.com Reported-by: eberhard.stoll@kontron.de Link: https://lore.kernel.org/r/20220511074644.558874-2-patrice.chotard@foss.st.co... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-stm32-qspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index ffdc55f87e82..dd38cb8ffbc2 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -308,7 +308,8 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, if (!op->data.nbytes) goto wait_nobusy;
- if (readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) + if ((readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) || + qspi->fmode == CCR_FMODE_APM) goto out;
reinit_completion(&qspi->data_completion);
From: Mikulas Patocka mpatocka@redhat.com
[ Upstream commit 84bc4f1dbbbb5f8aa68706a96711dccb28b518e5 ]
We observed the error "cacheline tracking ENOMEM, dma-debug disabled" during a light system load (copying some files). The reason for this error is that the dma_active_cacheline radix tree uses GFP_NOWAIT allocation - so it can't access the emergency memory reserves and it fails as soon as anybody reaches the watermark.
This patch changes GFP_NOWAIT to GFP_ATOMIC, so that it can access the emergency memory reserves.
Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index f8ff598596b8..ac740630c79c 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -448,7 +448,7 @@ void debug_dma_dump_mappings(struct device *dev) * other hand, consumes a single dma_debug_entry, but inserts 'nents' * entries into the tree. */ -static RADIX_TREE(dma_active_cacheline, GFP_NOWAIT); +static RADIX_TREE(dma_active_cacheline, GFP_ATOMIC); static DEFINE_SPINLOCK(radix_lock); #define ACTIVE_CACHELINE_MAX_OVERLAP ((1 << RADIX_TREE_MAX_TAGS) - 1) #define CACHELINE_PER_PAGE_SHIFT (PAGE_SHIFT - L1_CACHE_SHIFT)
From: Christian Brauner christian.brauner@ubuntu.com
[ Upstream commit e1bbcd277a53e08d619ffeec56c5c9287f2bf42f ]
Hold writers when changing a mount's idmapping to make it more robust.
The vfs layer takes care to retrieve the idmapping of a mount once ensuring that the idmapping used for vfs permission checking is identical to the idmapping passed down to the filesystem.
For ioctl codepaths the filesystem itself is responsible for taking the idmapping into account if they need to. While all filesystems with FS_ALLOW_IDMAP raised take the same precautions as the vfs we should enforce it explicitly by making sure there are no active writers on the relevant mount while changing the idmapping.
This is similar to turning a mount ro with the difference that in contrast to turning a mount ro changing the idmapping can only ever be done once while a mount can transition between ro and rw as much as it wants.
This is a minor user-visible change. But it is extremely unlikely to matter. The caller must've created a detached mount via OPEN_TREE_CLONE and then handed that O_PATH fd to another process or thread which then must've gotten a writable fd for that mount and started creating files in there while the caller is still changing mount properties. While not impossible it will be an extremely rare corner-case and should in general be considered a bug in the application. Consider making a mount MOUNT_ATTR_NOEXEC or MOUNT_ATTR_NODEV while allowing someone else to perform lookups or exec'ing in parallel by handing them a copy of the OPEN_TREE_CLONE fd or another fd beneath that mount.
Link: https://lore.kernel.org/r/20220510095840.152264-1-brauner@kernel.org Cc: Seth Forshee seth.forshee@digitalocean.com Cc: Christoph Hellwig hch@lst.de Cc: Al Viro viro@zeniv.linux.org.uk Cc: linux-fsdevel@vger.kernel.org Signed-off-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/namespace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c index afe2b64b14f1..41461f55c039 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4026,8 +4026,9 @@ static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) static inline bool mnt_allow_writers(const struct mount_kattr *kattr, const struct mount *mnt) { - return !(kattr->attr_set & MNT_READONLY) || - (mnt->mnt.mnt_flags & MNT_READONLY); + return (!(kattr->attr_set & MNT_READONLY) || + (mnt->mnt.mnt_flags & MNT_READONLY)) && + !kattr->mnt_userns; }
static int mount_setattr_prepare(struct mount_kattr *kattr, struct mount *mnt)
From: Zheng Bin zhengbin13@huawei.com
[ Upstream commit cbcab8cd737c74c20195c31d647e19f7cb49c9b8 ]
acp_pci_rn_probe misses a call platform_device_unregister in error path, this patch fixes that.
Signed-off-by: Zheng Bin zhengbin13@huawei.com Link: https://lore.kernel.org/r/20220512013728.4128903-1-zhengbin13@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/amd/pci-rn.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/sof/amd/pci-rn.c b/sound/soc/sof/amd/pci-rn.c index 392ffbdf6417..d809d151a38c 100644 --- a/sound/soc/sof/amd/pci-rn.c +++ b/sound/soc/sof/amd/pci-rn.c @@ -93,6 +93,7 @@ static int acp_pci_rn_probe(struct pci_dev *pci, const struct pci_device_id *pci res = devm_kzalloc(&pci->dev, sizeof(struct resource) * ARRAY_SIZE(renoir_res), GFP_KERNEL); if (!res) { sof_pci_remove(pci); + platform_device_unregister(dmic_dev); return -ENOMEM; }
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit d52848620de00cde4a3a5df908e231b8c8868250 ]
ASUS B1400CEAE fails to resume from suspend to idle by default. This was bisected back to commit df4f9bc4fb9c ("nvme-pci: add support for ACPI StorageD3Enable property") but this is a red herring to the problem.
Before this commit the system wasn't getting into deepest sleep state. Presumably this commit is allowing entry into deepest sleep state as advertised by firmware, but there are some other problems related to the wakeup.
As it is confirmed the system works properly with S3, set the default for this system to S3.
Reported-by: Jian-Hong Pan jhp@endlessos.org Link: https://bugzilla.kernel.org/show_bug.cgi?id=215742 Signed-off-by: Mario Limonciello mario.limonciello@amd.com Tested-by: Jian-Hong Pan jhp@endlessos.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/sleep.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index c992e57b2c79..3147702710af 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -373,6 +373,18 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"), }, }, + /* + * ASUS B1400CEAE hangs on resume from suspend (see + * https://bugzilla.kernel.org/show_bug.cgi?id=215742). + */ + { + .callback = init_default_s3, + .ident = "ASUS B1400CEAE", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK B1400CEAE"), + }, + }, {}, };
From: Corey Minyard cminyard@mvista.com
[ Upstream commit 7602b957e2404e5f98d9a40b68f1fd27f0028712 ]
Even though it's not possible to get into the SSIF_GETTING_MESSAGES and SSIF_GETTING_EVENTS states without a valid message in the msg field, it's probably best to be defensive here and check and print a log, since that means something else went wrong.
Also add a default clause to that switch statement to release the lock and print a log, in case the state variable gets messed up somehow.
Reported-by: Haowen Bai baihaowen@meizu.com Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/ipmi_ssif.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index f199cc194844..64c73ea9c915 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -814,6 +814,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, break;
case SSIF_GETTING_EVENTS: + if (!msg) { + /* Should never happen, but just in case. */ + dev_warn(&ssif_info->client->dev, + "No message set while getting events\n"); + ipmi_ssif_unlock_cond(ssif_info, flags); + break; + } + if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { /* Error getting event, probably done. */ msg->done(msg); @@ -838,6 +846,14 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, break;
case SSIF_GETTING_MESSAGES: + if (!msg) { + /* Should never happen, but just in case. */ + dev_warn(&ssif_info->client->dev, + "No message set while getting messages\n"); + ipmi_ssif_unlock_cond(ssif_info, flags); + break; + } + if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { /* Error getting event, probably done. */ msg->done(msg); @@ -861,6 +877,13 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, deliver_recv_msg(ssif_info, msg); } break; + + default: + /* Should never happen, but just in case. */ + dev_warn(&ssif_info->client->dev, + "Invalid state in message done handling: %d\n", + ssif_info->ssif_state); + ipmi_ssif_unlock_cond(ssif_info, flags); }
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
From: Corey Minyard cminyard@mvista.com
[ Upstream commit 9824117dd964ecebf5d81990dbf21dfb56445049 ]
There was a "type" element added to this structure, but some static values were missed. The default value will be zero, which is correct, but create an initializer for the type and initialize the type properly in the initializer to avoid future issues.
Reported-by: Joe Wiese jwiese@rackspace.com Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/ipmi_poweroff.c | 4 +--- drivers/char/ipmi/ipmi_watchdog.c | 14 +++++--------- include/linux/ipmi_smi.h | 6 ++++++ 3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index bc3a18daf97a..62e71c46ac5f 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c @@ -94,9 +94,7 @@ static void dummy_recv_free(struct ipmi_recv_msg *msg) { atomic_dec(&dummy_count); } -static struct ipmi_smi_msg halt_smi_msg = { - .done = dummy_smi_free -}; +static struct ipmi_smi_msg halt_smi_msg = INIT_IPMI_SMI_MSG(dummy_smi_free); static struct ipmi_recv_msg halt_recv_msg = { .done = dummy_recv_free }; diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 0604abdd249a..4c1e9663ea47 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -354,9 +354,7 @@ static void msg_free_recv(struct ipmi_recv_msg *msg) complete(&msg_wait); } } -static struct ipmi_smi_msg smi_msg = { - .done = msg_free_smi -}; +static struct ipmi_smi_msg smi_msg = INIT_IPMI_SMI_MSG(msg_free_smi); static struct ipmi_recv_msg recv_msg = { .done = msg_free_recv }; @@ -475,9 +473,8 @@ static void panic_recv_free(struct ipmi_recv_msg *msg) atomic_dec(&panic_done_count); }
-static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = { - .done = panic_smi_free -}; +static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = + INIT_IPMI_SMI_MSG(panic_smi_free); static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = { .done = panic_recv_free }; @@ -516,9 +513,8 @@ static void panic_halt_ipmi_heartbeat(void) atomic_sub(2, &panic_done_count); }
-static struct ipmi_smi_msg panic_halt_smi_msg = { - .done = panic_smi_free -}; +static struct ipmi_smi_msg panic_halt_smi_msg = + INIT_IPMI_SMI_MSG(panic_smi_free); static struct ipmi_recv_msg panic_halt_recv_msg = { .done = panic_recv_free }; diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 9277d21c2690..5d69820d8b02 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h @@ -125,6 +125,12 @@ struct ipmi_smi_msg { void (*done)(struct ipmi_smi_msg *msg); };
+#define INIT_IPMI_SMI_MSG(done_handler) \ +{ \ + .done = done_handler, \ + .type = IPMI_SMI_MSG_TYPE_NORMAL \ +} + struct ipmi_smi_handlers { struct module *owner;
From: Corey Minyard cminyard@mvista.com
[ Upstream commit 2ebaf18a0b7fb764bba6c806af99fe868cee93de ]
The was it was wouldn't work in some situations, simplify it. What was there was unnecessary complexity.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/ipmi_msghandler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index f1827257ef0e..2610e809c802 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -11,8 +11,8 @@ * Copyright 2002 MontaVista Software Inc. */
-#define pr_fmt(fmt) "%s" fmt, "IPMI message handler: " -#define dev_fmt pr_fmt +#define pr_fmt(fmt) "IPMI message handler: " fmt +#define dev_fmt(fmt) pr_fmt(fmt)
#include <linux/module.h> #include <linux/errno.h>
From: Daniel Latypov dlatypov@google.com
[ Upstream commit a02353f491622e49c7ddedc6a6dc4f1d6ed2150a ]
When filtering what tests to run (suites and/or cases) via kunit.filter_glob (e.g. kunit.py run <glob>), we allocate copies of suites.
These allocations can fail, and we largely don't handle that. Note: realistically, this probably doesn't matter much. We're not allocating much memory and this happens early in boot, so if we can't do that, then there's likely far bigger problems.
This patch makes us immediately bail out from the top-level function (kunit_filter_suites) with -ENOMEM if any of the underlying kmalloc() calls return NULL.
Implementation note: we used to return NULL pointers from some functions to indicate either that all suites/tests were filtered out or there was an error allocating the new array.
We'll log a short error in this case and not run any tests or print a TAP header. From a kunit.py user's perspective, they'll get a message about missing/invalid TAP output and have to dig into the test.log to see it. Since hitting this error seems so unlikely, it's probably fine to not invent a way to plumb this error message more visibly.
See also: https://lore.kernel.org/linux-kselftest/20220329103919.2376818-1-lv.ruyi@zte...
Signed-off-by: Daniel Latypov dlatypov@google.com Reported-by: Zeal Robot zealci@zte.com.cn Reported-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Brendan Higgins brendanhiggins@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/kunit/executor.c | 27 ++++++++++++++++++++++----- lib/kunit/executor_test.c | 4 +++- 2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index 22640c9ee819..2f73a6a35a7e 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c @@ -71,9 +71,13 @@ kunit_filter_tests(struct kunit_suite *const suite, const char *test_glob)
/* Use memcpy to workaround copy->name being const. */ copy = kmalloc(sizeof(*copy), GFP_KERNEL); + if (!copy) + return ERR_PTR(-ENOMEM); memcpy(copy, suite, sizeof(*copy));
filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL); + if (!filtered) + return ERR_PTR(-ENOMEM);
n = 0; kunit_suite_for_each_test_case(suite, test_case) { @@ -106,14 +110,16 @@ kunit_filter_subsuite(struct kunit_suite * const * const subsuite,
filtered = kmalloc_array(n + 1, sizeof(*filtered), GFP_KERNEL); if (!filtered) - return NULL; + return ERR_PTR(-ENOMEM);
n = 0; for (i = 0; subsuite[i] != NULL; ++i) { if (!glob_match(filter->suite_glob, subsuite[i]->name)) continue; filtered_suite = kunit_filter_tests(subsuite[i], filter->test_glob); - if (filtered_suite) + if (IS_ERR(filtered_suite)) + return ERR_CAST(filtered_suite); + else if (filtered_suite) filtered[n++] = filtered_suite; } filtered[n] = NULL; @@ -146,7 +152,8 @@ static void kunit_free_suite_set(struct suite_set suite_set) }
static struct suite_set kunit_filter_suites(const struct suite_set *suite_set, - const char *filter_glob) + const char *filter_glob, + int *err) { int i; struct kunit_suite * const **copy, * const *filtered_subsuite; @@ -166,6 +173,10 @@ static struct suite_set kunit_filter_suites(const struct suite_set *suite_set,
for (i = 0; i < max; ++i) { filtered_subsuite = kunit_filter_subsuite(suite_set->start[i], &filter); + if (IS_ERR(filtered_subsuite)) { + *err = PTR_ERR(filtered_subsuite); + return filtered; + } if (filtered_subsuite) *copy++ = filtered_subsuite; } @@ -236,9 +247,15 @@ int kunit_run_all_tests(void) .start = __kunit_suites_start, .end = __kunit_suites_end, }; + int err;
- if (filter_glob_param) - suite_set = kunit_filter_suites(&suite_set, filter_glob_param); + if (filter_glob_param) { + suite_set = kunit_filter_suites(&suite_set, filter_glob_param, &err); + if (err) { + pr_err("kunit executor: error filtering suites: %d\n", err); + return err; + } + }
if (!action_param) kunit_exec_run_tests(&suite_set); diff --git a/lib/kunit/executor_test.c b/lib/kunit/executor_test.c index 4ed57fd94e42..eac6ff480273 100644 --- a/lib/kunit/executor_test.c +++ b/lib/kunit/executor_test.c @@ -137,14 +137,16 @@ static void filter_suites_test(struct kunit *test) .end = suites + 2, }; struct suite_set filtered = {.start = NULL, .end = NULL}; + int err = 0;
/* Emulate two files, each having one suite */ subsuites[0][0] = alloc_fake_suite(test, "suite0", dummy_test_cases); subsuites[1][0] = alloc_fake_suite(test, "suite1", dummy_test_cases);
/* Filter out suite1 */ - filtered = kunit_filter_suites(&suite_set, "suite0"); + filtered = kunit_filter_suites(&suite_set, "suite0", &err); kfree_subsuites_at_end(test, &filtered); /* let us use ASSERTs without leaking */ + KUNIT_EXPECT_EQ(test, err, 0); KUNIT_ASSERT_EQ(test, filtered.end - filtered.start, (ptrdiff_t)1);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, filtered.start);
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit ad732da434a2936128769216eddaece3b1af4588 ]
This memory allocation failure can be triggered by fault injection or high pressure testing, resulting a WARN.
Fix this by replacing WARN with pr_warn.
Reported-by: syzkaller syzkaller@googlegroups.com Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220511014453.1621366-1-dzm91@hust.edu.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtlwifi/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index 86a236873254..a8eebafb9a7e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -1014,7 +1014,7 @@ int rtl_usb_probe(struct usb_interface *intf, hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + sizeof(struct rtl_usb_priv), &rtl_ops); if (!hw) { - WARN_ONCE(true, "rtl_usb: ieee80211 alloc failed\n"); + pr_warn("rtl_usb: ieee80211 alloc failed\n"); return -ENOMEM; } rtlpriv = hw->priv;
From: Felix Fietkau nbd@nbd.name
[ Upstream commit 77045a3740fa3d2325293cf8623899532b39303e ]
The hardware receives them properly, they should not be dropped
Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index e9e7efbf350d..a8df65cc115f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -521,7 +521,7 @@ mt7915_mac_fill_rx_rate(struct mt7915_dev *dev, status->encoding = RX_ENC_VHT; if (gi) status->enc_flags |= RX_ENC_FLAG_SHORT_GI; - if (i > 9) + if (i > 11) return -EINVAL; break; case MT_PHY_TYPE_HE_MU:
From: Felix Fietkau nbd@nbd.name
[ Upstream commit 3128ea016965ce9f91ddf4e1dd944724462d1698 ]
The hardware receives them properly, they should not be dropped
Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 233998ca4857..f34070ca7bbe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -696,7 +696,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) status->nss = FIELD_GET(MT_PRXV_NSTS, v0) + 1; status->encoding = RX_ENC_VHT; - if (i > 9) + if (i > 11) return -EINVAL; break; case MT_PHY_TYPE_HE_MU:
From: Felix Fietkau nbd@nbd.name
[ Upstream commit bc98e7fdd80d215b4b55eea001023231eb8ce12e ]
The driver needs to check if the format is 802.2 vs 802.3 in order to set a tx descriptor flag. skb->protocol can't be used, since it may not be properly initialized for packets coming in from a packet socket. Fix misdetection by checking the ethertype from the skb data instead
Reported-by: Thibaut VARÈNE hacks+kernel@slashdirt.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 4 +++- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index a8df65cc115f..eaa31f5e0b00 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1017,6 +1017,7 @@ mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi,
u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; u8 fc_type, fc_stype; + u16 ethertype; bool wmm = false; u32 val;
@@ -1030,7 +1031,8 @@ mt7915_mac_write_txwi_8023(struct mt7915_dev *dev, __le32 *txwi, val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) | FIELD_PREP(MT_TXD1_TID, tid);
- if (be16_to_cpu(skb->protocol) >= ETH_P_802_3_MIN) + 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); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index f34070ca7bbe..c5350e7a11e6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -814,6 +814,7 @@ mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi, { u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; u8 fc_type, fc_stype; + u16 ethertype; bool wmm = false; u32 val;
@@ -827,7 +828,8 @@ mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi, val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) | FIELD_PREP(MT_TXD1_TID, tid);
- if (be16_to_cpu(skb->protocol) >= ETH_P_802_3_MIN) + 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);
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit a71eb6025305192e646040cd76ccacb5bd48a1b5 ]
rga->m2m_dev needs to be freed when rga_probe fails.
Signed-off-by: Hangyu Hua hbh25y@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/platform/rockchip/rga/rga.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 3d3d1062e212..2f8df74ad0fd 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -865,7 +865,7 @@ static int rga_probe(struct platform_device *pdev)
ret = pm_runtime_resume_and_get(rga->dev); if (ret < 0) - goto rel_vdev; + goto rel_m2m;
rga->version.major = (rga_read(rga, RGA_VERSION_INFO) >> 24) & 0xFF; rga->version.minor = (rga_read(rga, RGA_VERSION_INFO) >> 20) & 0x0F; @@ -881,7 +881,7 @@ static int rga_probe(struct platform_device *pdev) DMA_ATTR_WRITE_COMBINE); if (!rga->cmdbuf_virt) { ret = -ENOMEM; - goto rel_vdev; + goto rel_m2m; }
rga->src_mmu_pages = @@ -918,6 +918,8 @@ static int rga_probe(struct platform_device *pdev) free_dma: dma_free_attrs(rga->dev, RGA_CMDBUF_SIZE, rga->cmdbuf_virt, rga->cmdbuf_phy, DMA_ATTR_WRITE_COMBINE); +rel_m2m: + v4l2_m2m_release(rga->m2m_dev); rel_vdev: video_device_release(vfd); unreg_v4l2_dev:
From: Philipp Zabel p.zabel@pengutronix.de
[ Upstream commit 67e33dd957880879e785cfea83a3aa24bd5c5577 ]
Let VIDIOC_ENUM_FRAMEINTERVALS return -EINVAL if userspace queries frame intervals for frame sizes unsupported by the encoder. Fixes the following v4l2-compliance failure:
fail: v4l2-test-formats.cpp(123): found frame intervals for invalid size 47x16 fail: v4l2-test-formats.cpp(282): node->codec_mask & STATEFUL_ENCODER test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: FAIL
[hverkuil: drop incorrect 'For decoder devices, return -ENOTTY.' in the commit log]
Signed-off-by: Philipp Zabel p.zabel@pengutronix.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 --- .../media/platform/chips-media/coda-common.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/chips-media/coda-common.c b/drivers/media/platform/chips-media/coda-common.c index a57822b05070..a2cad1830318 100644 --- a/drivers/media/platform/chips-media/coda-common.c +++ b/drivers/media/platform/chips-media/coda-common.c @@ -1324,7 +1324,8 @@ static int coda_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *f) { struct coda_ctx *ctx = fh_to_ctx(fh); - int i; + struct coda_q_data *q_data; + const struct coda_codec *codec;
if (f->index) return -EINVAL; @@ -1333,12 +1334,19 @@ static int coda_enum_frameintervals(struct file *file, void *fh, if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV) return -EINVAL;
- for (i = 0; i < CODA_MAX_FORMATS; i++) { - if (f->pixel_format == ctx->cvd->src_formats[i] || - f->pixel_format == ctx->cvd->dst_formats[i]) - break; + if (coda_format_normalize_yuv(f->pixel_format) == V4L2_PIX_FMT_YUV420) { + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); + codec = coda_find_codec(ctx->dev, f->pixel_format, + q_data->fourcc); + } else { + codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, + f->pixel_format); } - if (i == CODA_MAX_FORMATS) + if (!codec) + return -EINVAL; + + if (f->width < MIN_W || f->width > codec->max_w || + f->height < MIN_H || f->height > codec->max_h) return -EINVAL;
f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
From: Benjamin Gaignard benjamin.gaignard@collabora.com
[ Upstream commit 46c836569196f377f87a3657b330cffaf94bd727 ]
Always set pps_cb_qp_offset and pps_cr_qp_offset values in Hantro/G2 register whatever is V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT flag value. The vendor code does the same to set these values. This fixes conformance test CAINIT_G_SHARP_3.
Fluster HEVC score is increase by one with this patch.
Signed-off-by: Benjamin Gaignard benjamin.gaignard@collabora.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/hantro/hantro_g2_hevc_dec.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c index c524af41baf5..2e7eec0372cd 100644 --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c @@ -180,13 +180,8 @@ static void set_params(struct hantro_ctx *ctx) hantro_reg_write(vpu, &g2_max_cu_qpd_depth, 0); }
- if (pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT) { - hantro_reg_write(vpu, &g2_cb_qp_offset, pps->pps_cb_qp_offset); - hantro_reg_write(vpu, &g2_cr_qp_offset, pps->pps_cr_qp_offset); - } else { - hantro_reg_write(vpu, &g2_cb_qp_offset, 0); - hantro_reg_write(vpu, &g2_cr_qp_offset, 0); - } + hantro_reg_write(vpu, &g2_cb_qp_offset, pps->pps_cb_qp_offset); + hantro_reg_write(vpu, &g2_cr_qp_offset, pps->pps_cr_qp_offset);
hantro_reg_write(vpu, &g2_filt_offset_beta, pps->pps_beta_offset_div2); hantro_reg_write(vpu, &g2_filt_offset_tc, pps->pps_tc_offset_div2);
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit eca89cf60b040ee2cae693ea72a0364284f3084c ]
Fixes smatch warning:
drivers/media/i2c/ccs/ccs-core.c:1676 ccs_power_on() warn: 'sensor->ext_clk' from clk_prepare_enable() not released on lines: 1606.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Acked-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/ccs/ccs-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 03e841b8443f..7ae469caf990 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -1602,8 +1602,11 @@ static int ccs_power_on(struct device *dev) usleep_range(1000, 2000); } while (--retry);
- if (!reset) - return -EIO; + if (!reset) { + dev_err(dev, "software reset failed\n"); + rval = -EIO; + goto out_cci_addr_fail; + } }
if (sensor->hwcfg.i2c_addr_alt) {
From: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp
[ Upstream commit db264d4c66c0fe007b5d19fd007707cd0697603d ]
Since usb_register_dev() from imon_init_display() from imon_probe() holds minor_rwsem while display_open() which holds driver_lock and ictx->lock is called with minor_rwsem held from usb_open(), holding driver_lock or ictx->lock when calling usb_register_dev() causes circular locking dependency problem.
Since usb_deregister_dev() from imon_disconnect() holds minor_rwsem while display_open() which holds driver_lock is called with minor_rwsem held, holding driver_lock when calling usb_deregister_dev() also causes circular locking dependency problem.
Sean Young explained that the problem is there are imon devices which have two usb interfaces, even though it is one device. The probe and disconnect function of both usb interfaces can run concurrently.
Alan Stern responded that the driver and USB cores guarantee that when an interface is probed, both the interface and its USB device are locked. Ditto for when the disconnect callback gets run. So concurrent probing/ disconnection of multiple interfaces on the same device is not possible.
Therefore, we don't need locks for handling race between imon_probe() and imon_disconnect(). But we still need to handle race between display_open() /vfd_write()/lcd_write()/display_close() and imon_disconnect(), for disconnect event can happen while file descriptors are in use.
Since "struct file"->private_data is set by display_open(), vfd_write()/ lcd_write()/display_close() can assume that "struct file"->private_data is not NULL even after usb_set_intfdata(interface, NULL) was called.
Replace insufficiently held driver_lock with refcount_t based management. Add a boolean flag for recording whether imon_disconnect() was already called. Use RCU for accessing this boolean flag and refcount_t.
Since the boolean flag for imon_disconnect() is shared, disconnect event on either intf0 or intf1 affects both interfaces. But I assume that this change does not matter, for usually disconnect event would not happen while interfaces are in use.
Link: https://syzkaller.appspot.com/bug?extid=c558267ad910fc494497
Reported-by: syzbot syzbot+c558267ad910fc494497@syzkaller.appspotmail.com Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Tested-by: syzbot syzbot+c558267ad910fc494497@syzkaller.appspotmail.com Cc: Alan Stern stern@rowland.harvard.edu Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/imon.c | 99 +++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 52 deletions(-)
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 54da6f60079b..ab090663f975 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -153,6 +153,24 @@ struct imon_context { const struct imon_usb_dev_descr *dev_descr; /* device description with key */ /* table for front panels */ + /* + * Fields for deferring free_imon_context(). + * + * Since reference to "struct imon_context" is stored into + * "struct file"->private_data, we need to remember + * how many file descriptors might access this "struct imon_context". + */ + refcount_t users; + /* + * Use a flag for telling display_open()/vfd_write()/lcd_write() that + * imon_disconnect() was already called. + */ + bool disconnected; + /* + * We need to wait for RCU grace period in order to allow + * display_open() to safely check ->disconnected and increment ->users. + */ + struct rcu_head rcu; };
#define TOUCH_TIMEOUT (HZ/30) @@ -160,18 +178,18 @@ struct imon_context { /* vfd character device file operations */ static const struct file_operations vfd_fops = { .owner = THIS_MODULE, - .open = &display_open, - .write = &vfd_write, - .release = &display_close, + .open = display_open, + .write = vfd_write, + .release = display_close, .llseek = noop_llseek, };
/* lcd character device file operations */ static const struct file_operations lcd_fops = { .owner = THIS_MODULE, - .open = &display_open, - .write = &lcd_write, - .release = &display_close, + .open = display_open, + .write = lcd_write, + .release = display_close, .llseek = noop_llseek, };
@@ -439,9 +457,6 @@ static struct usb_driver imon_driver = { .id_table = imon_usb_id_table, };
-/* to prevent races between open() and disconnect(), probing, etc */ -static DEFINE_MUTEX(driver_lock); - /* Module bookkeeping bits */ MODULE_AUTHOR(MOD_AUTHOR); MODULE_DESCRIPTION(MOD_DESC); @@ -481,9 +496,11 @@ static void free_imon_context(struct imon_context *ictx) struct device *dev = ictx->dev;
usb_free_urb(ictx->tx_urb); + WARN_ON(ictx->dev_present_intf0); usb_free_urb(ictx->rx_urb_intf0); + WARN_ON(ictx->dev_present_intf1); usb_free_urb(ictx->rx_urb_intf1); - kfree(ictx); + kfree_rcu(ictx, rcu);
dev_dbg(dev, "%s: iMON context freed\n", __func__); } @@ -499,9 +516,6 @@ static int display_open(struct inode *inode, struct file *file) int subminor; int retval = 0;
- /* prevent races with disconnect */ - mutex_lock(&driver_lock); - subminor = iminor(inode); interface = usb_find_interface(&imon_driver, subminor); if (!interface) { @@ -509,13 +523,16 @@ static int display_open(struct inode *inode, struct file *file) retval = -ENODEV; goto exit; } - ictx = usb_get_intfdata(interface);
- if (!ictx) { + rcu_read_lock(); + ictx = usb_get_intfdata(interface); + if (!ictx || ictx->disconnected || !refcount_inc_not_zero(&ictx->users)) { + rcu_read_unlock(); pr_err("no context found for minor %d\n", subminor); retval = -ENODEV; goto exit; } + rcu_read_unlock();
mutex_lock(&ictx->lock);
@@ -533,8 +550,10 @@ static int display_open(struct inode *inode, struct file *file)
mutex_unlock(&ictx->lock);
+ if (retval && refcount_dec_and_test(&ictx->users)) + free_imon_context(ictx); + exit: - mutex_unlock(&driver_lock); return retval; }
@@ -544,16 +563,9 @@ static int display_open(struct inode *inode, struct file *file) */ static int display_close(struct inode *inode, struct file *file) { - struct imon_context *ictx = NULL; + struct imon_context *ictx = file->private_data; int retval = 0;
- ictx = file->private_data; - - if (!ictx) { - pr_err("no context for device\n"); - return -ENODEV; - } - mutex_lock(&ictx->lock);
if (!ictx->display_supported) { @@ -568,6 +580,8 @@ static int display_close(struct inode *inode, struct file *file) }
mutex_unlock(&ictx->lock); + if (refcount_dec_and_test(&ictx->users)) + free_imon_context(ictx); return retval; }
@@ -934,15 +948,12 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, int offset; int seq; int retval = 0; - struct imon_context *ictx; + struct imon_context *ictx = file->private_data; static const unsigned char vfd_packet6[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
- ictx = file->private_data; - if (!ictx) { - pr_err_ratelimited("no context for device\n"); + if (ictx->disconnected) return -ENODEV; - }
mutex_lock(&ictx->lock);
@@ -1018,13 +1029,10 @@ static ssize_t lcd_write(struct file *file, const char __user *buf, size_t n_bytes, loff_t *pos) { int retval = 0; - struct imon_context *ictx; + struct imon_context *ictx = file->private_data;
- ictx = file->private_data; - if (!ictx) { - pr_err_ratelimited("no context for device\n"); + if (ictx->disconnected) return -ENODEV; - }
mutex_lock(&ictx->lock);
@@ -2404,7 +2412,6 @@ static int imon_probe(struct usb_interface *interface, int ifnum, sysfs_err; int ret = 0; struct imon_context *ictx = NULL; - struct imon_context *first_if_ctx = NULL; u16 vendor, product;
usbdev = usb_get_dev(interface_to_usbdev(interface)); @@ -2416,17 +2423,12 @@ static int imon_probe(struct usb_interface *interface, dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n", __func__, vendor, product, ifnum);
- /* prevent races probing devices w/multiple interfaces */ - mutex_lock(&driver_lock); - first_if = usb_ifnum_to_if(usbdev, 0); if (!first_if) { ret = -ENODEV; goto fail; }
- first_if_ctx = usb_get_intfdata(first_if); - if (ifnum == 0) { ictx = imon_init_intf0(interface, id); if (!ictx) { @@ -2434,9 +2436,11 @@ static int imon_probe(struct usb_interface *interface, ret = -ENODEV; goto fail; } + refcount_set(&ictx->users, 1);
} else { /* this is the secondary interface on the device */ + struct imon_context *first_if_ctx = usb_get_intfdata(first_if);
/* fail early if first intf failed to register */ if (!first_if_ctx) { @@ -2450,14 +2454,13 @@ static int imon_probe(struct usb_interface *interface, ret = -ENODEV; goto fail; } + refcount_inc(&ictx->users);
}
usb_set_intfdata(interface, ictx);
if (ifnum == 0) { - mutex_lock(&ictx->lock); - if (product == 0xffdc && ictx->rf_device) { sysfs_err = sysfs_create_group(&interface->dev.kobj, &imon_rf_attr_group); @@ -2468,21 +2471,17 @@ static int imon_probe(struct usb_interface *interface,
if (ictx->display_supported) imon_init_display(ictx, interface); - - mutex_unlock(&ictx->lock); }
dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n", vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
- mutex_unlock(&driver_lock); usb_put_dev(usbdev);
return 0;
fail: - mutex_unlock(&driver_lock); usb_put_dev(usbdev); dev_err(dev, "unable to register, err %d\n", ret);
@@ -2498,10 +2497,8 @@ static void imon_disconnect(struct usb_interface *interface) struct device *dev; int ifnum;
- /* prevent races with multi-interface device probing and display_open */ - mutex_lock(&driver_lock); - ictx = usb_get_intfdata(interface); + ictx->disconnected = true; dev = ictx->dev; ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
@@ -2542,11 +2539,9 @@ static void imon_disconnect(struct usb_interface *interface) } }
- if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) + if (refcount_dec_and_test(&ictx->users)) free_imon_context(ictx);
- mutex_unlock(&driver_lock); - dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n", __func__, ifnum); }
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit 59267fc34f4900dcd2ec3295f6be04b79aee2186 ]
If an adapter is trying to claim a free logical address then it is in the 'is_configuring' state. If during that process the cable is disconnected (HPD goes low, which in turn invalidates the physical address), then cec_adap_unconfigure() is called, and that set the is_configuring boolean to false, even though the thread that's trying to claim an LA is still running.
Don't touch the is_configuring bool in cec_adap_unconfigure(), it will eventually be cleared by the thread. By making that change the cec_config_log_addr() function also had to change: it was aborting if is_configuring became false (since that is what cec_adap_unconfigure() did), but that no longer works. Instead check if the physical address is invalid. That is a much more appropriate check anyway.
This fixes a bug where the the adapter could be disabled even though the device was still configuring. This could cause POLL transmits to time out.
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/cec/core/cec-adap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index 2e12331c12a9..01766e744772 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -1278,7 +1278,7 @@ static int cec_config_log_addr(struct cec_adapter *adap, * While trying to poll the physical address was reset * and the adapter was unconfigured, so bail out. */ - if (!adap->is_configuring) + if (adap->phys_addr == CEC_PHYS_ADDR_INVALID) return -EINTR;
if (err) @@ -1335,7 +1335,6 @@ static void cec_adap_unconfigure(struct cec_adapter *adap) adap->phys_addr != CEC_PHYS_ADDR_INVALID) WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); adap->log_addrs.log_addr_mask = 0; - adap->is_configuring = false; adap->is_configured = false; cec_flush(adap); wake_up_interruptible(&adap->kthread_waitq); @@ -1527,9 +1526,10 @@ static int cec_config_thread_func(void *arg) for (i = 0; i < las->num_log_addrs; i++) las->log_addr[i] = CEC_LOG_ADDR_INVALID; cec_adap_unconfigure(adap); + adap->is_configuring = false; adap->kthread_config = NULL; - mutex_unlock(&adap->lock); complete(&adap->config_completion); + mutex_unlock(&adap->lock); return 0; }
From: Lukas Wunner lukas@wunner.de
[ Upstream commit d1408f6b4dd78fb1b9e26bcf64477984e5f85409 ]
Commit 2c9d6c2b871d ("usbnet: run unbind() before unregister_netdev()") sought to fix a use-after-free on disconnect of USB Ethernet adapters.
It turns out that a different fix is necessary to address the issue: https://lore.kernel.org/netdev/18b3541e5372bc9b9fc733d422f4e698c089077c.1650...
So the commit was not necessary.
The commit made binding and unbinding of USB Ethernet asymmetrical: Before, usbnet_probe() first invoked the ->bind() callback and then register_netdev(). usbnet_disconnect() mirrored that by first invoking unregister_netdev() and then ->unbind().
Since the commit, the order in usbnet_disconnect() is reversed and no longer mirrors usbnet_probe().
One consequence is that a PHY disconnected (and stopped) in ->unbind() is afterwards stopped once more by unregister_netdev() as it closes the netdev before unregistering. That necessitates a contortion in ->stop() because the PHY may only be stopped if it hasn't already been disconnected.
Reverting the commit allows making the call to phy_stop() unconditional in ->stop().
Tested-by: Oleksij Rempel o.rempel@pengutronix.de # LAN9514/9512/9500 Tested-by: Ferry Toth fntoth@gmail.com # LAN9514 Signed-off-by: Lukas Wunner lukas@wunner.de Acked-by: Oliver Neukum oneukum@suse.com Cc: Martyn Welch martyn.welch@collabora.com Cc: Andrew Lunn andrew@lunn.ch Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/usb/asix_devices.c | 6 +----- drivers/net/usb/smsc95xx.c | 3 +-- drivers/net/usb/usbnet.c | 6 +++--- 3 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 38e47a93fb83..5b5eb630c4b7 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -795,11 +795,7 @@ static int ax88772_stop(struct usbnet *dev) { struct asix_common_private *priv = dev->driver_priv;
- /* On unplugged USB, we will get MDIO communication errors and the - * PHY will be set in to PHY_HALTED state. - */ - if (priv->phydev->state != PHY_HALTED) - phy_stop(priv->phydev); + phy_stop(priv->phydev);
return 0; } diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 4ef61f6b85df..edf0492ad489 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1243,8 +1243,7 @@ static int smsc95xx_start_phy(struct usbnet *dev)
static int smsc95xx_stop(struct usbnet *dev) { - if (dev->net->phydev) - phy_stop(dev->net->phydev); + phy_stop(dev->net->phydev);
return 0; } diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9a6450f796dc..36b24ec11650 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1616,9 +1616,6 @@ void usbnet_disconnect (struct usb_interface *intf) xdev->bus->bus_name, xdev->devpath, dev->driver_info->description);
- if (dev->driver_info->unbind) - dev->driver_info->unbind(dev, intf); - net = dev->net; unregister_netdev (net);
@@ -1626,6 +1623,9 @@ void usbnet_disconnect (struct usb_interface *intf)
usb_scuttle_anchored_urbs(&dev->deferred);
+ if (dev->driver_info->unbind) + dev->driver_info->unbind(dev, intf); + usb_kill_urb(dev->interrupt); usb_free_urb(dev->interrupt); kfree(dev->padding_pkt);
From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit 05abad857277dda198063017b00ba5b9fed2c0cb ]
This adds HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN quirk which can be used to mark HCI_Enhanced_Setup_Synchronous_Connection as broken even if its support command bit are set since some controller report it as supported but the command don't work properly with some configurations (e.g. BT_VOICE_TRANSPARENT/mSBC).
Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/bluetooth/hci.h | 9 +++++++++ include/net/bluetooth/hci_core.h | 8 ++++++-- net/bluetooth/hci_conn.c | 2 +- net/bluetooth/sco.c | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 69ef31cea582..62a9bb022aed 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -265,6 +265,15 @@ enum { * runtime suspend, because event filtering takes place there. */ HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, + + /* + * When this quirk is set, disables the use of + * HCI_OP_ENHANCED_SETUP_SYNC_CONN command to setup SCO connections. + * + * This quirk can be set before hci_register_dev is called or + * during the hdev->setup vendor callback. + */ + HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, };
/* HCI device flags */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 62d7b81b1cb7..5a52a2018b56 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1495,8 +1495,12 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define privacy_mode_capable(dev) (use_ll_privacy(dev) && \ (hdev->commands[39] & 0x04))
-/* Use enhanced synchronous connection if command is supported */ -#define enhanced_sco_capable(dev) ((dev)->commands[29] & 0x08) +/* Use enhanced synchronous connection if command is supported and its quirk + * has not been set. + */ +#define enhanced_sync_conn_capable(dev) \ + (((dev)->commands[29] & 0x08) && \ + !test_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &(dev)->quirks))
/* Use ext scanning if set ext scan param and ext scan enable is supported */ #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \ diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index fe803bee419a..882a7df13005 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -481,7 +481,7 @@ static bool hci_setup_sync_conn(struct hci_conn *conn, __u16 handle)
bool hci_setup_sync(struct hci_conn *conn, __u16 handle) { - if (enhanced_sco_capable(conn->hdev)) + if (enhanced_sync_conn_capable(conn->hdev)) return hci_enhanced_setup_sync_conn(conn, handle);
return hci_setup_sync_conn(conn, handle); diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 8eabf41b2993..2a58c7d88433 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -885,7 +885,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, err = -EBADFD; break; } - if (enhanced_sco_capable(hdev) && + if (enhanced_sync_conn_capable(hdev) && voice.setting == BT_VOICE_TRANSPARENT) sco_pi(sk)->codec.id = BT_CODEC_TRANSPARENT; hci_dev_put(hdev);
From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit d44e1dbda36fff5d7c2586683c4adc0963aef908 ]
This sets HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN for QCA controllers since SCO appear to not work when using HCI_OP_ENHANCED_SETUP_SYNC_CONN.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215576 Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btusb.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 50df417207af..06a854a2507e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3335,6 +3335,11 @@ static int btusb_setup_qca(struct hci_dev *hdev) msleep(QCA_BT_RESET_WAIT_MS); }
+ /* Mark HCI_OP_ENHANCED_SETUP_SYNC_CONN as broken as it doesn't seem to + * work with the likes of HSP/HFP mSBC. + */ + set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks); + return 0; }
From: Zijun Hu quic_zijuhu@quicinc.com
[ Upstream commit 247f226adadfb7be09dd537f177429f4415aef8e ]
Set HCI_QUIRK_BROKEN_ERR_DATA_REPORTING for QCA controllers since they answer HCI_OP_READ_DEF_ERR_DATA_REPORTING with error code "UNKNOWN HCI COMMAND" as shown below:
[ 580.517552] Bluetooth: hci0: unexpected cc 0x0c5a length: 1 < 2 [ 580.517660] Bluetooth: hci0: Opcode 0x c5a failed: -38
hcitool -i hci0 cmd 0x03 0x5a < HCI Command: ogf 0x03, ocf 0x005a, plen 0
HCI Event: 0x0e plen 4
01 5A 0C 01
btmon log: < HCI Command: Read Default Erroneous Data Reporting (0x03|0x005a) plen 0
HCI Event: Command Complete (0x0e) plen 4
Read Default Erroneous Data Reporting (0x03|0x005a) ncmd 1 Status: Unknown HCI Command (0x01)
Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btusb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 06a854a2507e..e48c3ad069bb 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3339,6 +3339,7 @@ static int btusb_setup_qca(struct hci_dev *hdev) * work with the likes of HSP/HFP mSBC. */ set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks); + set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
return 0; }
From: Pavan Chebbi pavan.chebbi@broadcom.com
[ Upstream commit 11862689e8f117e4702f55000790d7bce6859e84 ]
For correctness, we need to configure the packet filters for timestamping during bnxt_open. This way they are always configured after firmware reset or chip reset. We should not assume that the filters will always be retained across resets.
This patch modifies the ioctl handler and always configures the PTP filters in the bnxt_open() path.
Cc: Richard Cochran richardcochran@gmail.com Signed-off-by: Pavan Chebbi pavan.chebbi@broadcom.com Signed-off-by: Michael Chan michael.chan@broadcom.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 1 + drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 56 ++++++++++++++----- drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h | 2 + 3 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1d69fe0737a1..d5149478a351 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -10363,6 +10363,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) if (BNXT_PF(bp)) bnxt_vf_reps_open(bp); bnxt_ptp_init_rtc(bp, true); + bnxt_ptp_cfg_tstamp_filters(bp); return 0;
open_err_irq: diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c index 00f2f80c0073..f9c94e5fe718 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c @@ -295,6 +295,27 @@ static int bnxt_ptp_cfg_event(struct bnxt *bp, u8 event) return hwrm_req_send(bp, req); }
+void bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp) +{ + struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; + struct hwrm_port_mac_cfg_input *req; + + if (!ptp || !ptp->tstamp_filters) + return; + + if (hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG)) + goto out; + req->flags = cpu_to_le32(ptp->tstamp_filters); + req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE); + req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl); + + if (!hwrm_req_send(bp, req)) + return; + ptp->tstamp_filters = 0; +out: + netdev_warn(bp->dev, "Failed to configure HW packet timestamp filters\n"); +} + void bnxt_ptp_reapply_pps(struct bnxt *bp) { struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; @@ -435,27 +456,36 @@ static int bnxt_ptp_enable(struct ptp_clock_info *ptp_info, static int bnxt_hwrm_ptp_cfg(struct bnxt *bp) { struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; - struct hwrm_port_mac_cfg_input *req; u32 flags = 0; - int rc; + int rc = 0;
- rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG); - if (rc) - return rc; + switch (ptp->rx_filter) { + case HWTSTAMP_FILTER_NONE: + flags = PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE; + break; + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + flags = PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE; + break; + }
- if (ptp->rx_filter) - flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_ENABLE; - else - flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_RX_TS_CAPTURE_DISABLE; if (ptp->tx_tstamp_en) flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_ENABLE; else flags |= PORT_MAC_CFG_REQ_FLAGS_PTP_TX_TS_CAPTURE_DISABLE; - req->flags = cpu_to_le32(flags); - req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_RX_TS_CAPTURE_PTP_MSG_TYPE); - req->rx_ts_capture_ptp_msg_type = cpu_to_le16(ptp->rxctl);
- return hwrm_req_send(bp, req); + ptp->tstamp_filters = flags; + + if (netif_running(bp->dev)) { + rc = bnxt_close_nic(bp, false, false); + if (!rc) + rc = bnxt_open_nic(bp, false, false); + if (!rc && !ptp->tstamp_filters) + rc = -EIO; + } + + return rc; }
int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h index 530b9922608c..4ce0a14c1e23 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h @@ -113,6 +113,7 @@ struct bnxt_ptp_cfg { BNXT_PTP_MSG_PDELAY_RESP) u8 tx_tstamp_en:1; int rx_filter; + u32 tstamp_filters;
u32 refclk_regs[2]; u32 refclk_mapped_regs[2]; @@ -133,6 +134,7 @@ do { \ int bnxt_ptp_parse(struct sk_buff *skb, u16 *seq_id, u16 *hdr_off); void bnxt_ptp_update_current_time(struct bnxt *bp); void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2); +void bnxt_ptp_cfg_tstamp_filters(struct bnxt *bp); void bnxt_ptp_reapply_pps(struct bnxt *bp); int bnxt_hwtstamp_set(struct net_device *dev, struct ifreq *ifr); int bnxt_hwtstamp_get(struct net_device *dev, struct ifreq *ifr);
From: Yunfei Dong yunfei.dong@mediatek.com
[ Upstream commit c10c0086db688c95bb4e0e378e523818dff1551d ]
If the driver support subdev mode, the parameter "dev->pm.dev" will be NULL in mtk_vcodec_dec_remove. Kernel will crash when try to rmmod mtk-vcodec-dec.ko.
[ 4380.702726] pc : do_raw_spin_trylock+0x4/0x80 [ 4380.707075] lr : _raw_spin_lock_irq+0x90/0x14c [ 4380.711509] sp : ffff80000819bc10 [ 4380.714811] x29: ffff80000819bc10 x28: ffff3600c03e4000 x27: 0000000000000000 [ 4380.721934] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000 [ 4380.729057] x23: ffff3600c0f34930 x22: ffffd5e923549000 x21: 0000000000000220 [ 4380.736179] x20: 0000000000000208 x19: ffffd5e9213e8ebc x18: 0000000000000020 [ 4380.743298] x17: 0000002000000000 x16: ffffd5e9213e8e90 x15: 696c346f65646976 [ 4380.750420] x14: 0000000000000000 x13: 0000000000000001 x12: 0000000000000040 [ 4380.757542] x11: 0000000000000000 x10: 0000000000000000 x9 : 0000000000000000 [ 4380.764664] x8 : 0000000000000000 x7 : ffff3600c7273ae8 x6 : ffffd5e9213e8ebc [ 4380.771786] x5 : 0000000000000000 x4 : 0000000000000001 x3 : 0000000000000000 [ 4380.778908] x2 : 0000000000000000 x1 : ffff3600c03e4000 x0 : 0000000000000208 [ 4380.786031] Call trace: [ 4380.788465] do_raw_spin_trylock+0x4/0x80 [ 4380.792462] __pm_runtime_disable+0x2c/0x1b0 [ 4380.796723] mtk_vcodec_dec_remove+0x5c/0xa0 [mtk_vcodec_dec] [ 4380.802466] platform_remove+0x2c/0x60 [ 4380.806204] __device_release_driver+0x194/0x250 [ 4380.810810] driver_detach+0xc8/0x15c [ 4380.814462] bus_remove_driver+0x5c/0xb0 [ 4380.818375] driver_unregister+0x34/0x64 [ 4380.822288] platform_driver_unregister+0x18/0x24 [ 4380.826979] mtk_vcodec_dec_driver_exit+0x1c/0x888 [mtk_vcodec_dec] [ 4380.833240] __arm64_sys_delete_module+0x190/0x224 [ 4380.838020] invoke_syscall+0x48/0x114 [ 4380.841760] el0_svc_common.constprop.0+0x60/0x11c [ 4380.846540] do_el0_svc+0x28/0x90 [ 4380.849844] el0_svc+0x4c/0x100 [ 4380.852975] el0t_64_sync_handler+0xec/0xf0 [ 4380.857148] el0t_64_sync+0x190/0x194 [ 4380.860801] Code: 94431515 17ffffca d503201f d503245f (b9400004)
Signed-off-by: Yunfei Dong yunfei.dong@mediatek.com Tested-by: Nícolas F. R. A. Prado nfraprado@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_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 df7b25e9cbc8..128edcf541e1 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -487,7 +487,8 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev) video_unregister_device(dev->vfd_dec);
v4l2_device_unregister(&dev->v4l2_dev); - pm_runtime_disable(dev->pm.dev); + if (!dev->vdec_pdata->is_subdev_supported) + pm_runtime_disable(dev->pm.dev); mtk_vcodec_fw_release(dev->fw_handler); return 0; }
From: Jason A. Donenfeld Jason@zx2c4.com
[ Upstream commit 516dd4aacd67a0f27da94f3fe63fe0f4dbab6e2b ]
In order to measure the boot process, the timer should be switched on as early in boot as possible. As well, the commit defines the get_cycles macro, like the previous patches in this series, so that generic code is aware that it's implemented by the platform, as is done on other archs.
Cc: Thomas Gleixner tglx@linutronix.de Cc: Arnd Bergmann arnd@arndb.de Cc: Jonas Bonn jonas@southpole.se Cc: Stefan Kristiansson stefan.kristiansson@saunalahti.fi Acked-by: Stafford Horne shorne@gmail.com Reported-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/openrisc/include/asm/timex.h | 1 + arch/openrisc/kernel/head.S | 9 +++++++++ 2 files changed, 10 insertions(+)
diff --git a/arch/openrisc/include/asm/timex.h b/arch/openrisc/include/asm/timex.h index d52b4e536e3f..5487fa93dd9b 100644 --- a/arch/openrisc/include/asm/timex.h +++ b/arch/openrisc/include/asm/timex.h @@ -23,6 +23,7 @@ static inline cycles_t get_cycles(void) { return mfspr(SPR_TTCR); } +#define get_cycles get_cycles
/* This isn't really used any more */ #define CLOCK_TICK_RATE 1000 diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S index 15f1b38dfe03..871f4c858859 100644 --- a/arch/openrisc/kernel/head.S +++ b/arch/openrisc/kernel/head.S @@ -521,6 +521,15 @@ _start: l.ori r3,r0,0x1 l.mtspr r0,r3,SPR_SR
+ /* + * Start the TTCR as early as possible, so that the RNG can make use of + * measurements of boot time from the earliest opportunity. Especially + * important is that the TTCR does not return zero by the time we reach + * rand_initialize(). + */ + l.movhi r3,hi(SPR_TTMR_CR) + l.mtspr r0,r3,SPR_TTMR + CLEAR_GPR(r1) CLEAR_GPR(r2) CLEAR_GPR(r3)
From: Smith, Kyle Miller (Nimble Kernel) kyles@hpe.com
[ Upstream commit da42761181627e9bdc37d18368b827948a583929 ]
In nvme_alloc_admin_tags, the admin_q can be set to an error (typically -ENOMEM) if the blk_mq_init_queue call fails to set up the queue, which is checked immediately after the call. However, when we return the error message up the stack, to nvme_reset_work the error takes us to nvme_remove_dead_ctrl() nvme_dev_disable() nvme_suspend_queue(&dev->queues[0]).
Here, we only check that the admin_q is non-NULL, rather than not an error or NULL, and begin quiescing a queue that never existed, leading to bad / NULL pointer dereference.
Signed-off-by: Kyle Smith kyles@hpe.com Reviewed-by: Chaitanya Kulkarni kch@nvidia.com Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/pci.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 3aacf1c0d5a5..17aeb7d5c485 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1775,6 +1775,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) dev->ctrl.admin_q = blk_mq_init_queue(&dev->admin_tagset); if (IS_ERR(dev->ctrl.admin_q)) { blk_mq_free_tag_set(&dev->admin_tagset); + dev->ctrl.admin_q = NULL; return -ENOMEM; } if (!blk_get_queue(dev->ctrl.admin_q)) {
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 2def44d3aec59e38d2701c568d65540783f90f2f ]
There is a logic error when removing rt5645 device as the function rt5645_i2c_remove() first cancel the &rt5645->jack_detect_work and delete the &rt5645->btn_check_timer latter. However, since the timer handler rt5645_btn_check_callback() will re-queue the jack_detect_work, this cleanup order is buggy.
That is, once the del_timer_sync in rt5645_i2c_remove is concurrently run with the rt5645_btn_check_callback, the canceled jack_detect_work will be rescheduled again, leading to possible use-after-free.
This patch fix the issue by placing the del_timer_sync function before the cancel_delayed_work_sync.
Signed-off-by: Lin Ma linma@zju.edu.cn Link: https://lore.kernel.org/r/20220516092035.28283-1-linma@zju.edu.cn Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt5645.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 197c56047947..4b2e027c1033 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -4154,9 +4154,14 @@ static int rt5645_i2c_remove(struct i2c_client *i2c) if (i2c->irq) free_irq(i2c->irq, rt5645);
+ /* + * Since the rt5645_btn_check_callback() can queue jack_detect_work, + * the timer need to be delted first + */ + del_timer_sync(&rt5645->btn_check_timer); + cancel_delayed_work_sync(&rt5645->jack_detect_work); cancel_delayed_work_sync(&rt5645->rcclock_work); - del_timer_sync(&rt5645->btn_check_timer);
regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
From: Xie Yongji xieyongji@bytedance.com
[ Upstream commit 491bf8f236fdeec698fa6744993f1ecf3fafd1a5 ]
When userspace closes the socket before sending a disconnect request, the following I/O requests will be blocked in wait_for_reconnect() until dead timeout. This will cause the following disconnect request also hung on blk_mq_quiesce_queue(). That means we have no way to disconnect a nbd device if there are some I/O requests waiting for reconnecting until dead timeout. It's not expected. So let's wake up the thread waiting for reconnecting directly when a disconnect request is sent.
Reported-by: Xu Jianhai zero.xu@bytedance.com Signed-off-by: Xie Yongji xieyongji@bytedance.com Reviewed-by: Josef Bacik josef@toxicpanda.com Link: https://lore.kernel.org/r/20220322080639.142-1-xieyongji@bytedance.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/nbd.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 5a1f98494ddd..284557041336 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -947,11 +947,15 @@ static int wait_for_reconnect(struct nbd_device *nbd) struct nbd_config *config = nbd->config; if (!config->dead_conn_timeout) return 0; - if (test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags)) + + if (!wait_event_timeout(config->conn_wait, + test_bit(NBD_RT_DISCONNECTED, + &config->runtime_flags) || + atomic_read(&config->live_connections) > 0, + config->dead_conn_timeout)) return 0; - return wait_event_timeout(config->conn_wait, - atomic_read(&config->live_connections) > 0, - config->dead_conn_timeout) > 0; + + return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags); }
static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) @@ -2082,6 +2086,7 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd) mutex_lock(&nbd->config_lock); nbd_disconnect(nbd); sock_shutdown(nbd); + wake_up(&nbd->config->conn_wait); /* * Make sure recv thread has finished, we can safely call nbd_clear_que() * to cancel the inflight I/Os.
From: Sathishkumar S sathishkumar.sundararaju@amd.com
[ Upstream commit 138292f1dc00e7e0724f44769f9da39cf2f3bf0b ]
smartshift apu and dgpu power boost are reported as percentage with respect to their power limits. This value[0-100] reflects the boost for the respective device.
Signed-off-by: Sathishkumar S sathishkumar.sundararaju@amd.com Reviewed-by: Lijo Lazar lijo.lazar@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 60 ++++++++++++++----- 1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index fd6c44ece168..012e3bd99cc2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1119,6 +1119,39 @@ static int renoir_get_power_profile_mode(struct smu_context *smu, return size; }
+static void renoir_get_ss_power_percent(SmuMetrics_t *metrics, + uint32_t *apu_percent, uint32_t *dgpu_percent) +{ + uint32_t apu_boost = 0; + uint32_t dgpu_boost = 0; + uint16_t apu_limit = 0; + uint16_t dgpu_limit = 0; + uint16_t apu_power = 0; + uint16_t dgpu_power = 0; + + apu_power = metrics->ApuPower; + apu_limit = metrics->StapmOriginalLimit; + if (apu_power > apu_limit && apu_limit != 0) + apu_boost = ((apu_power - apu_limit) * 100) / apu_limit; + apu_boost = (apu_boost > 100) ? 100 : apu_boost; + + dgpu_power = metrics->dGpuPower; + if (metrics->StapmCurrentLimit > metrics->StapmOriginalLimit) + dgpu_limit = metrics->StapmCurrentLimit - metrics->StapmOriginalLimit; + if (dgpu_power > dgpu_limit && dgpu_limit != 0) + dgpu_boost = ((dgpu_power - dgpu_limit) * 100) / dgpu_limit; + dgpu_boost = (dgpu_boost > 100) ? 100 : dgpu_boost; + + if (dgpu_boost >= apu_boost) + apu_boost = 0; + else + dgpu_boost = 0; + + *apu_percent = apu_boost; + *dgpu_percent = dgpu_boost; +} + + static int renoir_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) @@ -1127,6 +1160,9 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu,
SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; + uint32_t apu_percent = 0; + uint32_t dgpu_percent = 0; +
ret = smu_cmn_get_metrics_table(smu, NULL, @@ -1171,26 +1207,18 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, *value = metrics->Voltage[1]; break; case METRICS_SS_APU_SHARE: - /* return the percentage of APU power with respect to APU's power limit. - * percentage is reported, this isn't boost value. Smartshift power - * boost/shift is only when the percentage is more than 100. + /* return the percentage of APU power boost + * with respect to APU's power limit. */ - if (metrics->StapmOriginalLimit > 0) - *value = (metrics->ApuPower * 100) / metrics->StapmOriginalLimit; - else - *value = 0; + renoir_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent); + *value = apu_percent; break; case METRICS_SS_DGPU_SHARE: - /* return the percentage of dGPU power with respect to dGPU's power limit. - * percentage is reported, this isn't boost value. Smartshift power - * boost/shift is only when the percentage is more than 100. + /* return the percentage of dGPU power boost + * with respect to dGPU's power limit. */ - if ((metrics->dGpuPower > 0) && - (metrics->StapmCurrentLimit > metrics->StapmOriginalLimit)) - *value = (metrics->dGpuPower * 100) / - (metrics->StapmCurrentLimit - metrics->StapmOriginalLimit); - else - *value = 0; + renoir_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent); + *value = dgpu_percent; break; default: *value = UINT_MAX;
From: Sathishkumar S sathishkumar.sundararaju@amd.com
[ Upstream commit cdf4c8ec39872a61a58d62f19b4db80f0f7bc586 ]
smartshift apu and dgpu power boost are reported as percentage with respect to their power limits. adjust the units of power before calculating the percentage of boost.
Signed-off-by: Sathishkumar S sathishkumar.sundararaju@amd.com Reviewed-by: Lijo Lazar lijo.lazar@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index e2d099409123..87257b1b028f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -276,6 +276,42 @@ static int yellow_carp_mode2_reset(struct smu_context *smu) return yellow_carp_mode_reset(smu, SMU_RESET_MODE_2); }
+ +static void yellow_carp_get_ss_power_percent(SmuMetrics_t *metrics, + uint32_t *apu_percent, uint32_t *dgpu_percent) +{ + uint32_t apu_boost = 0; + uint32_t dgpu_boost = 0; + uint16_t apu_limit = 0; + uint16_t dgpu_limit = 0; + uint16_t apu_power = 0; + uint16_t dgpu_power = 0; + + /* APU and dGPU power values are reported in milli Watts + * and STAPM power limits are in Watts */ + apu_power = metrics->ApuPower/1000; + apu_limit = metrics->StapmOpnLimit; + if (apu_power > apu_limit && apu_limit != 0) + apu_boost = ((apu_power - apu_limit) * 100) / apu_limit; + apu_boost = (apu_boost > 100) ? 100 : apu_boost; + + dgpu_power = metrics->dGpuPower/1000; + if (metrics->StapmCurrentLimit > metrics->StapmOpnLimit) + dgpu_limit = metrics->StapmCurrentLimit - metrics->StapmOpnLimit; + if (dgpu_power > dgpu_limit && dgpu_limit != 0) + dgpu_boost = ((dgpu_power - dgpu_limit) * 100) / dgpu_limit; + dgpu_boost = (dgpu_boost > 100) ? 100 : dgpu_boost; + + if (dgpu_boost >= apu_boost) + apu_boost = 0; + else + dgpu_boost = 0; + + *apu_percent = apu_boost; + *dgpu_percent = dgpu_boost; + +} + static int yellow_carp_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) @@ -284,6 +320,8 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu,
SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; + uint32_t apu_percent = 0; + uint32_t dgpu_percent = 0;
ret = smu_cmn_get_metrics_table(smu, NULL, false); if (ret) @@ -332,26 +370,18 @@ static int yellow_carp_get_smu_metrics_data(struct smu_context *smu, *value = metrics->Voltage[1]; break; case METRICS_SS_APU_SHARE: - /* return the percentage of APU power with respect to APU's power limit. - * percentage is reported, this isn't boost value. Smartshift power - * boost/shift is only when the percentage is more than 100. + /* return the percentage of APU power boost + * with respect to APU's power limit. */ - if (metrics->StapmOpnLimit > 0) - *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit; - else - *value = 0; + yellow_carp_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent); + *value = apu_percent; break; case METRICS_SS_DGPU_SHARE: - /* return the percentage of dGPU power with respect to dGPU's power limit. - * percentage is reported, this isn't boost value. Smartshift power - * boost/shift is only when the percentage is more than 100. + /* return the percentage of dGPU power boost + * with respect to dGPU's power limit. */ - if ((metrics->dGpuPower > 0) && - (metrics->StapmCurrentLimit > metrics->StapmOpnLimit)) - *value = (metrics->dGpuPower * 100) / - (metrics->StapmCurrentLimit - metrics->StapmOpnLimit); - else - *value = 0; + yellow_carp_get_ss_power_percent(metrics, &apu_percent, &dgpu_percent); + *value = dgpu_percent; break; default: *value = UINT_MAX;
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 4b9caaa0281972ca5ea4e1cdac2e12b9df1ae00b ]
Lockdep complains about the smu->message_lock mutex being used before it is initialized through the following call path:
amdgpu_device_init() amdgpu_dpm_mode2_reset() smu_mode2_reset() smu_v12_0_mode2_reset() smu_cmn_send_smc_msg_with_param()
Move the mutex_init() call to smu_early_init() to fix the mutex being used before it is initialized.
This fixes the following lockdep splat:
[ 3.867331] ------------[ cut here ]------------ [ 3.867335] fbcon: Taking over console [ 3.867338] DEBUG_LOCKS_WARN_ON(lock->magic != lock) [ 3.867340] WARNING: CPU: 14 PID: 491 at kernel/locking/mutex.c:579 __mutex_lock+0x44c/0x830 [ 3.867349] Modules linked in: amdgpu(+) crct10dif_pclmul drm_ttm_helper crc32_pclmul ttm crc32c_intel ghash_clmulni_intel hid_lg_g15 iommu_v2 sp5100_tco nvme gpu_sched drm_dp_helper nvme_core ccp wmi video hid_logitech_dj ip6_tables ip_tables ipmi_devintf ipmi_msghandler fuse i2c_dev [ 3.867363] CPU: 14 PID: 491 Comm: systemd-udevd Tainted: G I 5.18.0-rc5+ #33 [ 3.867366] Hardware name: Micro-Star International Co., Ltd. MS-7C95/B550M PRO-VDH WIFI (MS-7C95), BIOS 2.90 12/23/2021 [ 3.867369] RIP: 0010:__mutex_lock+0x44c/0x830 [ 3.867372] Code: ff 85 c0 0f 84 33 fc ff ff 8b 0d b7 50 25 01 85 c9 0f 85 25 fc ff ff 48 c7 c6 fb 41 82 99 48 c7 c7 6b 63 80 99 e8 88 2a f8 ff <0f> 0b e9 0b fc ff ff f6 83 b9 0c 00 00 01 0f 85 64 ff ff ff 4c 89 [ 3.867377] RSP: 0018:ffffaef8c0fc79f0 EFLAGS: 00010286 [ 3.867380] RAX: 0000000000000028 RBX: 0000000000000000 RCX: 0000000000000027 [ 3.867382] RDX: ffff9ccc0dda0928 RSI: 0000000000000001 RDI: ffff9ccc0dda0920 [ 3.867384] RBP: ffffaef8c0fc7a80 R08: 0000000000000000 R09: ffffaef8c0fc7820 [ 3.867386] R10: 0000000000000003 R11: ffff9ccc2a2fffe8 R12: 0000000000000002 [ 3.867388] R13: ffff9cc990808058 R14: 0000000000000000 R15: ffff9cc98bfc0000 [ 3.867390] FS: 00007fc4d830f580(0000) GS:ffff9ccc0dd80000(0000) knlGS:0000000000000000 [ 3.867394] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3.867396] CR2: 0000560a77031410 CR3: 000000010f522000 CR4: 0000000000750ee0 [ 3.867398] PKRU: 55555554 [ 3.867399] Call Trace: [ 3.867401] <TASK> [ 3.867403] ? smu_cmn_send_smc_msg_with_param+0x98/0x240 [amdgpu] [ 3.867533] ? __mutex_lock+0x90/0x830 [ 3.867535] ? amdgpu_dpm_mode2_reset+0x37/0x60 [amdgpu] [ 3.867653] ? smu_cmn_send_smc_msg_with_param+0x98/0x240 [amdgpu] [ 3.867758] smu_cmn_send_smc_msg_with_param+0x98/0x240 [amdgpu] [ 3.867857] smu_mode2_reset+0x2b/0x50 [amdgpu] [ 3.867953] amdgpu_dpm_mode2_reset+0x46/0x60 [amdgpu] [ 3.868096] amdgpu_device_init.cold+0x1069/0x1e78 [amdgpu] [ 3.868219] ? _raw_spin_unlock_irqrestore+0x30/0x50 [ 3.868222] ? pci_conf1_read+0x9b/0xf0 [ 3.868226] amdgpu_driver_load_kms+0x15/0x110 [amdgpu] [ 3.868314] amdgpu_pci_probe+0x1a9/0x3c0 [amdgpu] [ 3.868398] local_pci_probe+0x41/0x80 [ 3.868401] pci_device_probe+0xab/0x200 [ 3.868404] really_probe+0x1a1/0x370 [ 3.868407] __driver_probe_device+0xfc/0x170 [ 3.868410] driver_probe_device+0x1f/0x90 [ 3.868412] __driver_attach+0xbf/0x1a0 [ 3.868414] ? __device_attach_driver+0xe0/0xe0 [ 3.868416] bus_for_each_dev+0x65/0x90 [ 3.868419] bus_add_driver+0x151/0x1f0 [ 3.868421] driver_register+0x89/0xd0 [ 3.868423] ? 0xffffffffc0bd4000 [ 3.868425] do_one_initcall+0x5d/0x300 [ 3.868428] ? do_init_module+0x22/0x240 [ 3.868431] ? rcu_read_lock_sched_held+0x3c/0x70 [ 3.868434] ? trace_kmalloc+0x30/0xe0 [ 3.868437] ? kmem_cache_alloc_trace+0x1e6/0x3a0 [ 3.868440] do_init_module+0x4a/0x240 [ 3.868442] __do_sys_finit_module+0x93/0xf0 [ 3.868446] do_syscall_64+0x5b/0x80 [ 3.868449] ? rcu_read_lock_sched_held+0x3c/0x70 [ 3.868451] ? lockdep_hardirqs_on_prepare+0xd9/0x180 [ 3.868454] ? do_syscall_64+0x67/0x80 [ 3.868456] ? do_syscall_64+0x67/0x80 [ 3.868458] ? do_syscall_64+0x67/0x80 [ 3.868460] ? do_syscall_64+0x67/0x80 [ 3.868462] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 3.868465] RIP: 0033:0x7fc4d8ec1ced [ 3.868467] Code: 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d fb 70 0e 00 f7 d8 64 89 01 48 [ 3.868472] RSP: 002b:00007fff687ae6b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000139 [ 3.868475] RAX: ffffffffffffffda RBX: 0000560a76fbca60 RCX: 00007fc4d8ec1ced [ 3.868477] RDX: 0000000000000000 RSI: 00007fc4d902343c RDI: 0000000000000011 [ 3.868479] RBP: 00007fc4d902343c R08: 0000000000000000 R09: 0000560a76fb59c0 [ 3.868481] R10: 0000000000000011 R11: 0000000000000246 R12: 0000000000020000 [ 3.868484] R13: 0000560a76f8bfd0 R14: 0000000000000000 R15: 0000560a76fc2d10 [ 3.868487] </TASK> [ 3.868489] irq event stamp: 120617 [ 3.868490] hardirqs last enabled at (120617): [<ffffffff9817169e>] __up_console_sem+0x5e/0x70 [ 3.868494] hardirqs last disabled at (120616): [<ffffffff98171683>] __up_console_sem+0x43/0x70 [ 3.868497] softirqs last enabled at (119684): [<ffffffff980ee83a>] __irq_exit_rcu+0xca/0x100 [ 3.868501] softirqs last disabled at (119679): [<ffffffff980ee83a>] __irq_exit_rcu+0xca/0x100 [ 3.868504] ---[ end trace 0000000000000000 ]---
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index f10a0256413e..32cff21f261c 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -576,6 +576,8 @@ static int smu_early_init(void *handle) smu->smu_baco.platform_support = false; smu->user_dpm_profile.fan_mode = -1;
+ mutex_init(&smu->message_lock); + adev->powerplay.pp_handle = smu; adev->powerplay.pp_funcs = &swsmu_pm_funcs;
@@ -975,8 +977,6 @@ static int smu_sw_init(void *handle) bitmap_zero(smu->smu_feature.supported, SMU_FEATURE_MAX); bitmap_zero(smu->smu_feature.allowed, SMU_FEATURE_MAX);
- mutex_init(&smu->message_lock); - INIT_WORK(&smu->throttling_logging_work, smu_throttling_logging_work_fn); INIT_WORK(&smu->interrupt_work, smu_interrupt_work_fn); atomic64_set(&smu->throttle_int_counter, 0);
From: Omar Sandoval osandov@fb.com
[ Upstream commit 2256e901f5bddc56e24089c96f27b77da932dfcc ]
When btrfs_qgroup_inherit(), btrfs_alloc_tree_block, or btrfs_insert_root() fail in create_subvol(), we return without freeing anon_dev. Reorganize the error handling in create_subvol() to fix this.
Reviewed-by: Sweet Tea Dorminy sweettea-kernel@dorminy.me Signed-off-by: Omar Sandoval osandov@fb.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/ioctl.c | 49 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index be6c24577dbe..777801902511 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -561,7 +561,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, struct timespec64 cur_time = current_time(dir); struct inode *inode; int ret; - dev_t anon_dev = 0; + dev_t anon_dev; u64 objectid; u64 index = 0;
@@ -571,11 +571,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns,
ret = btrfs_get_free_objectid(fs_info->tree_root, &objectid); if (ret) - goto fail_free; - - ret = get_anon_bdev(&anon_dev); - if (ret < 0) - goto fail_free; + goto out_root_item;
/* * Don't create subvolume whose level is not zero. Or qgroup will be @@ -583,9 +579,13 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, */ if (btrfs_qgroup_level(objectid)) { ret = -ENOSPC; - goto fail_free; + goto out_root_item; }
+ ret = get_anon_bdev(&anon_dev); + if (ret < 0) + goto out_root_item; + btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); /* * The same as the snapshot creation, please see the comment @@ -593,26 +593,26 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, */ ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, 8, false); if (ret) - goto fail_free; + goto out_anon_dev;
trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { ret = PTR_ERR(trans); btrfs_subvolume_release_metadata(root, &block_rsv); - goto fail_free; + goto out_anon_dev; } trans->block_rsv = &block_rsv; trans->bytes_reserved = block_rsv.size;
ret = btrfs_qgroup_inherit(trans, 0, objectid, inherit); if (ret) - goto fail; + goto out;
leaf = btrfs_alloc_tree_block(trans, root, 0, objectid, NULL, 0, 0, 0, BTRFS_NESTING_NORMAL); if (IS_ERR(leaf)) { ret = PTR_ERR(leaf); - goto fail; + goto out; }
btrfs_mark_buffer_dirty(leaf); @@ -667,7 +667,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, btrfs_tree_unlock(leaf); btrfs_free_tree_block(trans, objectid, leaf, 0, 1); free_extent_buffer(leaf); - goto fail; + goto out; }
free_extent_buffer(leaf); @@ -676,19 +676,18 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, key.offset = (u64)-1; new_root = btrfs_get_new_fs_root(fs_info, objectid, anon_dev); if (IS_ERR(new_root)) { - free_anon_bdev(anon_dev); ret = PTR_ERR(new_root); btrfs_abort_transaction(trans, ret); - goto fail; + goto out; } - /* Freeing will be done in btrfs_put_root() of new_root */ + /* anon_dev is owned by new_root now. */ anon_dev = 0;
ret = btrfs_record_root_in_trans(trans, new_root); if (ret) { btrfs_put_root(new_root); btrfs_abort_transaction(trans, ret); - goto fail; + goto out; }
ret = btrfs_create_subvol_root(trans, new_root, root, mnt_userns); @@ -696,7 +695,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, if (ret) { /* We potentially lose an unused inode item here */ btrfs_abort_transaction(trans, ret); - goto fail; + goto out; }
/* @@ -705,28 +704,28 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, ret = btrfs_set_inode_index(BTRFS_I(dir), &index); if (ret) { btrfs_abort_transaction(trans, ret); - goto fail; + goto out; }
ret = btrfs_insert_dir_item(trans, name, namelen, BTRFS_I(dir), &key, BTRFS_FT_DIR, index); if (ret) { btrfs_abort_transaction(trans, ret); - goto fail; + goto out; }
btrfs_i_size_write(BTRFS_I(dir), dir->i_size + namelen * 2); ret = btrfs_update_inode(trans, root, BTRFS_I(dir)); if (ret) { btrfs_abort_transaction(trans, ret); - goto fail; + goto out; }
ret = btrfs_add_root_ref(trans, objectid, root->root_key.objectid, btrfs_ino(BTRFS_I(dir)), index, name, namelen); if (ret) { btrfs_abort_transaction(trans, ret); - goto fail; + goto out; }
ret = btrfs_uuid_tree_add(trans, root_item->uuid, @@ -734,8 +733,7 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, if (ret) btrfs_abort_transaction(trans, ret);
-fail: - kfree(root_item); +out: trans->block_rsv = NULL; trans->bytes_reserved = 0; btrfs_subvolume_release_metadata(root, &block_rsv); @@ -751,11 +749,10 @@ static noinline int create_subvol(struct user_namespace *mnt_userns, return PTR_ERR(inode); d_instantiate(dentry, inode); } - return ret; - -fail_free: +out_anon_dev: if (anon_dev) free_anon_bdev(anon_dev); +out_root_item: kfree(root_item); return ret; }
From: Daniel Latypov dlatypov@google.com
[ Upstream commit dbf0b0d53a2b5afa6ef7372dcedf52302669fc2c ]
Consider this invocation $ ./tools/testing/kunit/kunit.py parse <<EOF TAP version 14 1..2 ok 1 - suite # Subtest: no_tests_suite # catastrophic error! not ok 1 - no_tests_suite EOF
It will have a 0 exit code even though there's a "not ok".
Consider this one: $ ./tools/testing/kunit/kunit.py parse <<EOF TAP version 14 1..2 ok 1 - suite not ok 1 - no_tests_suite EOF
It will a non-zero exit code.
Why? We have this line in the kunit_parser.py
parent_test = parse_test_header(lines, test)
where we have special handling when we see "# Subtest" and we ignore the explicit reported "not ok 1" status!
Also, NO_TESTS at a suite-level only results in a non-zero status code where then there's only one suite atm.
This change is the minimal one to make sure we don't overwrite it.
Signed-off-by: Daniel Latypov dlatypov@google.com Reviewed-by: David Gow davidgow@google.com Reviewed-by: Brendan Higgins brendanhiggins@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/kunit/kunit_parser.py | 7 +++++-- .../test_data/test_is_test_passed-no_tests_no_plan.log | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py index 05ff334761dd..2f93ed1d7f99 100644 --- a/tools/testing/kunit/kunit_parser.py +++ b/tools/testing/kunit/kunit_parser.py @@ -789,8 +789,11 @@ def parse_test(lines: LineStream, expected_num: int, log: List[str]) -> Test:
# Check for there being no tests if parent_test and len(subtests) == 0: - test.status = TestStatus.NO_TESTS - test.add_error('0 tests run!') + # Don't override a bad status if this test had one reported. + # Assumption: no subtests means CRASHED is from Test.__init__() + if test.status in (TestStatus.TEST_CRASHED, TestStatus.SUCCESS): + test.status = TestStatus.NO_TESTS + test.add_error('0 tests run!')
# Add statuses to TestCounts attribute in Test object bubble_up_test_results(test) diff --git a/tools/testing/kunit/test_data/test_is_test_passed-no_tests_no_plan.log b/tools/testing/kunit/test_data/test_is_test_passed-no_tests_no_plan.log index dd873c981108..4f81876ee6f1 100644 --- a/tools/testing/kunit/test_data/test_is_test_passed-no_tests_no_plan.log +++ b/tools/testing/kunit/test_data/test_is_test_passed-no_tests_no_plan.log @@ -3,5 +3,5 @@ TAP version 14 # Subtest: suite 1..1 # Subtest: case - ok 1 - case # SKIP + ok 1 - case ok 1 - suite
From: Fabio Estevam festevam@denx.de
[ Upstream commit f2ef6f7539c68c6bd6c32323d8845ee102b7c450 ]
Currently, if the .probe element is present in the phy_driver structure and the .driver_data is not, a NULL pointer dereference happens.
Allow passing .probe without .driver_data by inserting NULL checks for priv->type.
Signed-off-by: Fabio Estevam festevam@denx.de Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://lore.kernel.org/r/20220513114613.762810-1-festevam@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/micrel.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index cd9aa353b653..48c7d715a9e3 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -497,7 +497,7 @@ static int kszphy_config_reset(struct phy_device *phydev) } }
- if (priv->led_mode >= 0) + if (priv->type && priv->led_mode >= 0) kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode);
return 0; @@ -513,10 +513,10 @@ static int kszphy_config_init(struct phy_device *phydev)
type = priv->type;
- if (type->has_broadcast_disable) + if (type && type->has_broadcast_disable) kszphy_broadcast_disable(phydev);
- if (type->has_nand_tree_disable) + if (type && type->has_nand_tree_disable) kszphy_nand_tree_disable(phydev);
return kszphy_config_reset(phydev); @@ -1514,7 +1514,7 @@ static int kszphy_probe(struct phy_device *phydev)
priv->type = type;
- if (type->led_mode_reg) { + if (type && type->led_mode_reg) { ret = of_property_read_u32(np, "micrel,led-mode", &priv->led_mode); if (ret) @@ -1535,7 +1535,8 @@ static int kszphy_probe(struct phy_device *phydev) unsigned long rate = clk_get_rate(clk); bool rmii_ref_clk_sel_25_mhz;
- priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; + if (type) + priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; rmii_ref_clk_sel_25_mhz = of_property_read_bool(np, "micrel,rmii-reference-clock-select-25-mhz");
From: Kwanghoon Son k.son@samsung.com
[ Upstream commit e080f5c1f2b6d02c02ee5d674e0e392ccf63bbaf ]
Declare static on function 'fimc_isp_video_device_unregister'.
When VIDEO_EXYNOS4_ISP_DMA_CAPTURE=n, compiler warns about warning: no previous prototype for function [-Wmissing-prototypes]
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Kwanghoon Son k.son@samsung.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/platform/samsung/exynos4-is/fimc-isp-video.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.h b/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.h index edcb3a5e3cb9..2dd4ddbc748a 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-isp-video.h @@ -32,7 +32,7 @@ static inline int fimc_isp_video_device_register(struct fimc_isp *isp, return 0; }
-void fimc_isp_video_device_unregister(struct fimc_isp *isp, +static inline void fimc_isp_video_device_unregister(struct fimc_isp *isp, enum v4l2_buf_type type) { }
From: Nicolas Dufresne nicolas.dufresne@collabora.com
[ Upstream commit 831410700909f4e29d5af1ef26b8c59fc2d1988e ]
The hardware expects FrameNumWrap or long_term_frame_idx. Picture numbers are per field, and are mostly used during the memory management process, which is done in userland. This fixes two ITU conformance tests:
- MR6_BT_B - MR8_BT_B
Signed-off-by: Nicolas Dufresne nicolas.dufresne@collabora.com Reviewed-by: Sebastian Fricke sebastian.fricke@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_h264.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_h264.c b/drivers/staging/media/hantro/hantro_h264.c index 0b4d2491be3b..228629fb3cdf 100644 --- a/drivers/staging/media/hantro/hantro_h264.c +++ b/drivers/staging/media/hantro/hantro_h264.c @@ -354,8 +354,6 @@ u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, unsigned int dpb_idx)
if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) return 0; - if (dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) - return dpb->pic_num; return dpb->frame_num; }
From: Ping-Ke Shih pkshih@realtek.com
[ Upstream commit 97df85871a5b187609d30fca6d85b912d9e02f29 ]
Somehow, hardware reports incorrect mac_id and pollute memory. Check index before we access the array.
UBSAN: array-index-out-of-bounds in rtw89/phy.c:2517:23 index 188 is out of range for type 's32 [64]' CPU: 1 PID: 51550 Comm: irq/35-rtw89_pc Tainted: G OE Call Trace: <IRQ> show_stack+0x52/0x58 dump_stack_lvl+0x4c/0x63 dump_stack+0x10/0x12 ubsan_epilogue+0x9/0x45 __ubsan_handle_out_of_bounds.cold+0x44/0x49 ? __alloc_skb+0x92/0x1d0 rtw89_phy_cfo_parse+0x44/0x7f [rtw89_core] rtw89_core_rx+0x261/0x871 [rtw89_core] ? __alloc_skb+0xee/0x1d0 rtw89_pci_napi_poll+0x3fa/0x4ea [rtw89_pci] __napi_poll+0x33/0x1a0 net_rx_action+0x126/0x260 ? __queue_work+0x217/0x4c0 __do_softirq+0xd9/0x315 ? disable_irq_nosync+0x10/0x10 do_softirq.part.0+0x6d/0x90 </IRQ> <TASK> __local_bh_enable_ip+0x62/0x70 rtw89_pci_interrupt_threadfn+0x182/0x1a6 [rtw89_pci] irq_thread_fn+0x28/0x60 irq_thread+0xc8/0x190 ? irq_thread_fn+0x60/0x60 kthread+0x16b/0x190 ? irq_thread_check_affinity+0xe0/0xe0 ? set_kthread_struct+0x50/0x50 ret_from_fork+0x22/0x30 </TASK>
Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220516005215.5878-4-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw89/phy.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index ac211d897311..8414f30184b9 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -2213,6 +2213,11 @@ void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val, struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking; u8 macid = phy_ppdu->mac_id;
+ if (macid >= CFO_TRACK_MAX_USER) { + rtw89_warn(rtwdev, "mac_id %d is out of range\n", macid); + return; + } + cfo->cfo_tail[macid] += cfo_val; cfo->cfo_cnt[macid]++; cfo->packet_count++;
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit df5cd369876114f91f9ae60658fea80acfb15890 ]
When we boot a machine using a devicetree, the generic DT code goes through all nodes with a 'device_type = "memory"' property, and collects all memory banks mentioned there. However it does not check for the status property, so any nodes which are explicitly "disabled" will still be added as a memblock. This ends up badly for QEMU, when booting with secure firmware on arm/arm64 machines, because QEMU adds a node describing secure-only memory: =================== secram@e000000 { secure-status = "okay"; status = "disabled"; reg = <0x00 0xe000000 0x00 0x1000000>; device_type = "memory"; }; ===================
The kernel will eventually use that memory block (which is located below the main DRAM bank), but accesses to that will be answered with an SError: =================== [ 0.000000] Internal error: synchronous external abort: 96000050 [#1] PREEMPT SMP [ 0.000000] Modules linked in: [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc6-00014-g10c8acb8b679 #524 [ 0.000000] Hardware name: linux,dummy-virt (DT) [ 0.000000] pstate: 200000c5 (nzCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 0.000000] pc : new_slab+0x190/0x340 [ 0.000000] lr : new_slab+0x184/0x340 [ 0.000000] sp : ffff80000a4b3d10 .... ================== The actual crash location and call stack will be somewhat random, and depend on the specific allocation of that physical memory range.
As the DT spec[1] explicitly mentions standard properties, add a simple check to skip over disabled memory nodes, so that we only use memory that is meant for non-secure code to use.
That fixes booting a QEMU arm64 VM with EL3 enabled ("secure=on"), when not using UEFI. In this case the QEMU generated DT will be handed on to the kernel, which will see the secram node. This issue is reproducible when using TF-A together with U-Boot as firmware, then booting with the "booti" command.
When using U-Boot as an UEFI provider, the code there [2] explicitly filters for disabled nodes when generating the UEFI memory map, so we are safe. EDK/2 only reads the first bank of the first DT memory node [3] to learn about memory, so we got lucky there.
[1] https://github.com/devicetree-org/devicetree-specification/blob/main/source/... (after the table) [2] https://source.denx.de/u-boot/u-boot/-/blob/master/lib/fdtdec.c#L1061-1063 [3] https://github.com/tianocore/edk2/blob/master/ArmVirtPkg/PrePi/FdtParser.c
Reported-by: Ross Burton ross.burton@arm.com Signed-off-by: Andre Przywara andre.przywara@arm.com Signed-off-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20220517101410.3493781-1-andre.przywara@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/fdt.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index ec315b060cd5..0f30496ce80b 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -1105,6 +1105,9 @@ int __init early_init_dt_scan_memory(void) if (type == NULL || strcmp(type, "memory") != 0) continue;
+ if (!of_fdt_device_is_available(fdt, node)) + continue; + reg = of_get_flat_dt_prop(node, "linux,usable-memory", &l); if (reg == NULL) reg = of_get_flat_dt_prop(node, "reg", &l);
From: Laibin Qiu qiulaibin@huawei.com
[ Upstream commit 5a011f889b4832aa80c2a872a5aade5c48d2756f ]
1.In current process, all bio will set the BIO_THROTTLED flag after __blk_throtl_bio().
2.If bio needs to be throttled, it will start the timer and stop submit bio directly. Bio will submit in blk_throtl_dispatch_work_fn() when the timer expires.But in the current process, if bio is throttled. The BIO_THROTTLED will be set to bio after timer start. If the bio has been completed, it may cause use-after-free blow.
BUG: KASAN: use-after-free in blk_throtl_bio+0x12f0/0x2c70 Read of size 2 at addr ffff88801b8902d4 by task fio/26380
dump_stack+0x9b/0xce print_address_description.constprop.6+0x3e/0x60 kasan_report.cold.9+0x22/0x3a blk_throtl_bio+0x12f0/0x2c70 submit_bio_checks+0x701/0x1550 submit_bio_noacct+0x83/0xc80 submit_bio+0xa7/0x330 mpage_readahead+0x380/0x500 read_pages+0x1c1/0xbf0 page_cache_ra_unbounded+0x471/0x6f0 do_page_cache_ra+0xda/0x110 ondemand_readahead+0x442/0xae0 page_cache_async_ra+0x210/0x300 generic_file_buffered_read+0x4d9/0x2130 generic_file_read_iter+0x315/0x490 blkdev_read_iter+0x113/0x1b0 aio_read+0x2ad/0x450 io_submit_one+0xc8e/0x1d60 __se_sys_io_submit+0x125/0x350 do_syscall_64+0x2d/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Allocated by task 26380: kasan_save_stack+0x19/0x40 __kasan_kmalloc.constprop.2+0xc1/0xd0 kmem_cache_alloc+0x146/0x440 mempool_alloc+0x125/0x2f0 bio_alloc_bioset+0x353/0x590 mpage_alloc+0x3b/0x240 do_mpage_readpage+0xddf/0x1ef0 mpage_readahead+0x264/0x500 read_pages+0x1c1/0xbf0 page_cache_ra_unbounded+0x471/0x6f0 do_page_cache_ra+0xda/0x110 ondemand_readahead+0x442/0xae0 page_cache_async_ra+0x210/0x300 generic_file_buffered_read+0x4d9/0x2130 generic_file_read_iter+0x315/0x490 blkdev_read_iter+0x113/0x1b0 aio_read+0x2ad/0x450 io_submit_one+0xc8e/0x1d60 __se_sys_io_submit+0x125/0x350 do_syscall_64+0x2d/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Freed by task 0: kasan_save_stack+0x19/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x1b/0x30 __kasan_slab_free+0x111/0x160 kmem_cache_free+0x94/0x460 mempool_free+0xd6/0x320 bio_free+0xe0/0x130 bio_put+0xab/0xe0 bio_endio+0x3a6/0x5d0 blk_update_request+0x590/0x1370 scsi_end_request+0x7d/0x400 scsi_io_completion+0x1aa/0xe50 scsi_softirq_done+0x11b/0x240 blk_mq_complete_request+0xd4/0x120 scsi_mq_done+0xf0/0x200 virtscsi_vq_done+0xbc/0x150 vring_interrupt+0x179/0x390 __handle_irq_event_percpu+0xf7/0x490 handle_irq_event_percpu+0x7b/0x160 handle_irq_event+0xcc/0x170 handle_edge_irq+0x215/0xb20 common_interrupt+0x60/0x120 asm_common_interrupt+0x1e/0x40
Fix this by move BIO_THROTTLED set into the queue_lock.
Signed-off-by: Laibin Qiu qiulaibin@huawei.com Reviewed-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20220301123919.2381579-1-qiulaibin@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-throttle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 469c483719be..5c5f2741a95f 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -2189,13 +2189,14 @@ bool __blk_throtl_bio(struct bio *bio) }
out_unlock: - spin_unlock_irq(&q->queue_lock); bio_set_flag(bio, BIO_THROTTLED);
#ifdef CONFIG_BLK_DEV_THROTTLING_LOW if (throttled || !td->track_bio_latency) bio->bi_issue.value |= BIO_ISSUE_THROTL_SKIP_LATENCY; #endif + spin_unlock_irq(&q->queue_lock); + rcu_read_unlock(); return throttled; }
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 21ca3274333f5c1cbbf9d91e5b33f4f2463859b2 ]
commit dcc2c012c7691 ("ASoC: Fix gpiolib dependencies") removed a series of unnecessary dependencies on GPIOLIB when the gpio was optional.
A similar simplification seems valid for max98357a, so remove the dependency as well. This will avoid the following warning
WARNING: unmet direct dependencies detected for SND_SOC_MAX98357A Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && GPIOLIB [=n] Selected by [y]: - SND_SOC_INTEL_SOF_CS42L42_MACH [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && SND_SOC_INTEL_MACH [=y] && (SND_SOC_SOF_HDA_LINK [=y] || SND_SOC_SOF_BAYTRAIL [=n]) && I2C [=y] && ACPI [=y] && SND_HDA_CODEC_HDMI [=y] && SND_SOC_SOF_HDA_AUDIO_CODEC [=y] && (MFD_INTEL_LPSS [=y] || COMPILE_TEST [=n])
Reported-by: kernel test robot yujie.liu@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20220517172647.468244-2-pierre-louis.bossart@linux... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/Kconfig | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f46a22660103..156f2519459d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -953,7 +953,6 @@ config SND_SOC_MAX98095
config SND_SOC_MAX98357A tristate "Maxim MAX98357A CODEC" - depends on GPIOLIB
config SND_SOC_MAX98371 tristate
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit b390c25c6757b9d56cecdfbf6d55f15fc89a6386 ]
commit dcc2c012c7691 ("ASoC: Fix gpiolib dependencies") removed a series of unnecessary dependencies on GPIOLIB when the gpio was optional.
A similar simplification seems valid for rt1015p, so remove the dependency as well. This will avoid the following warning
WARNING: unmet direct dependencies detected for SND_SOC_RT1015P
Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && GPIOLIB [=n]
Selected by [y]:
- SND_SOC_INTEL_SOF_RT5682_MACH [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && SND_SOC_INTEL_MACH [=y] && (SND_SOC_SOF_HDA_LINK [=y] || SND_SOC_SOF_BAYTRAIL [=n]) && I2C [=y] && ACPI [=y] && (SND_HDA_CODEC_HDMI [=y] && SND_SOC_SOF_HDA_AUDIO_CODEC [=y] && (MFD_INTEL_LPSS [=y] || COMPILE_TEST [=y]) || SND_SOC_SOF_BAYTRAIL [=n] && (X86_INTEL_LPSS [=n] || COMPILE_TEST [=y]))
Reported-by: kernel test robot yujie.liu@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20220517172647.468244-3-pierre-louis.bossart@linux... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/Kconfig | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 156f2519459d..3dea20b2c405 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1212,7 +1212,6 @@ config SND_SOC_RT1015
config SND_SOC_RT1015P tristate - depends on GPIOLIB
config SND_SOC_RT1019 tristate
From: Pierre Gondois Pierre.Gondois@arm.com
[ Upstream commit 6380b7b2b29da9d9c5ab2d4a265901cd93ba3696 ]
The transition_delay_us (struct cpufreq_policy) is currently defined as: Preferred average time interval between consecutive invocations of the driver to set the frequency for this policy. To be set by the scaling driver (0, which is the default, means no preference). The transition_latency represents the amount of time necessary for a CPU to change its frequency.
A PCCT table advertises mutliple values: - pcc_nominal: Expected latency to process a command, in microseconds - pcc_mpar: The maximum number of periodic requests that the subspace channel can support, reported in commands per minute. 0 indicates no limitation. - pcc_mrtt: The minimum amount of time that OSPM must wait after the completion of a command before issuing the next command, in microseconds. cppc_get_transition_latency() allows to get the max of them.
commit d4f3388afd48 ("cpufreq / CPPC: Set platform specific transition_delay_us") allows to select transition_delay_us based on the platform, and fallbacks to cppc_get_transition_latency() otherwise.
If _CPC objects are not using PCC channels (no PPCT table), the transition_delay_us is set to CPUFREQ_ETERNAL, leading to really long periods between frequency updates (~4s).
If the desired_reg, where performance requests are written, is in SystemMemory or SystemIo ACPI address space, there is no delay in requests. So return 0 instead of CPUFREQ_ETERNAL, leading to transition_delay_us being set to LATENCY_MULTIPLIER us (1000 us).
This patch also adds two macros to check the address spaces.
Signed-off-by: Pierre Gondois pierre.gondois@arm.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/cppc_acpi.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index bc1454789a06..34576ab0e2e1 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -100,6 +100,16 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); (cpc)->cpc_entry.reg.space_id == \ ACPI_ADR_SPACE_PLATFORM_COMM)
+/* Check if a CPC register is in SystemMemory */ +#define CPC_IN_SYSTEM_MEMORY(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ + (cpc)->cpc_entry.reg.space_id == \ + ACPI_ADR_SPACE_SYSTEM_MEMORY) + +/* Check if a CPC register is in SystemIo */ +#define CPC_IN_SYSTEM_IO(cpc) ((cpc)->type == ACPI_TYPE_BUFFER && \ + (cpc)->cpc_entry.reg.space_id == \ + ACPI_ADR_SPACE_SYSTEM_IO) + /* Evaluates to True if reg is a NULL register descriptor */ #define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \ (reg)->address == 0 && \ @@ -1447,6 +1457,9 @@ EXPORT_SYMBOL_GPL(cppc_set_perf); * transition latency for performance change requests. The closest we have * is the timing information from the PCCT tables which provides the info * on the number and frequency of PCC commands the platform can handle. + * + * If desired_reg is in the SystemMemory or SystemIo ACPI address space, + * then assume there is no latency. */ unsigned int cppc_get_transition_latency(int cpu_num) { @@ -1472,7 +1485,9 @@ unsigned int cppc_get_transition_latency(int cpu_num) return CPUFREQ_ETERNAL;
desired_reg = &cpc_desc->cpc_regs[DESIRED_PERF]; - if (!CPC_IN_PCC(desired_reg)) + if (CPC_IN_SYSTEM_MEMORY(desired_reg) || CPC_IN_SYSTEM_IO(desired_reg)) + return 0; + else if (!CPC_IN_PCC(desired_reg)) return CPUFREQ_ETERNAL;
if (pcc_ss_id < 0)
From: Chaitanya Kulkarni kch@nvidia.com
[ Upstream commit 78288665b5d0154978fed431985310cb4f166836 ]
In current implementation we set the non-mdts limits by calling nvme_init_non_mdts_limits() from nvme_init_ctrl_finish(). This also tries to set the limits for the discovery controller which has no I/O queues resulting in the warning message reported by the nvme_log_error() when running blktest nvme/002: -
[ 2005.155946] run blktests nvme/002 at 2022-04-09 16:57:47 [ 2005.192223] loop: module loaded [ 2005.196429] nvmet: adding nsid 1 to subsystem blktests-subsystem-0 [ 2005.200334] nvmet: adding nsid 1 to subsystem blktests-subsystem-1
<------------------------------SNIP---------------------------------->
[ 2008.958108] nvmet: adding nsid 1 to subsystem blktests-subsystem-997 [ 2008.962082] nvmet: adding nsid 1 to subsystem blktests-subsystem-998 [ 2008.966102] nvmet: adding nsid 1 to subsystem blktests-subsystem-999 [ 2008.973132] nvmet: creating discovery controller 1 for subsystem nqn.2014-08.org.nvmexpress.discovery for NQN testhostnqn. *[ 2008.973196] nvme1: Identify(0x6), Invalid Field in Command (sct 0x0 / sc 0x2) MORE DNR* [ 2008.974595] nvme nvme1: new ctrl: "nqn.2014-08.org.nvmexpress.discovery" [ 2009.103248] nvme nvme1: Removing ctrl: NQN "nqn.2014-08.org.nvmexpress.discovery"
Move the call of nvme_init_non_mdts_limits() to nvme_scan_work() after we verify that I/O queues are created since that is a converging point for each transport where these limits are actually used.
1. FC : nvme_fc_create_association() ... nvme_fc_create_io_queues(ctrl); ... nvme_start_ctrl() nvme_scan_queue() nvme_scan_work()
2. PCIe:- nvme_reset_work() ... nvme_setup_io_queues() nvme_create_io_queues() nvme_alloc_queue() ... nvme_start_ctrl() nvme_scan_queue() nvme_scan_work()
3. RDMA :- nvme_rdma_setup_ctrl ... nvme_rdma_configure_io_queues ... nvme_start_ctrl() nvme_scan_queue() nvme_scan_work()
4. TCP :- nvme_tcp_setup_ctrl ... nvme_tcp_configure_io_queues ... nvme_start_ctrl() nvme_scan_queue() nvme_scan_work()
* nvme_scan_work() ... nvme_validate_or_alloc_ns() nvme_alloc_ns() nvme_update_ns_info() nvme_update_disk_info() nvme_config_discard() <--- blk_queue_max_write_zeroes_sectors() <---
Signed-off-by: Chaitanya Kulkarni kch@nvidia.com Reviewed-by: Keith Busch kbusch@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index e1846d04817f..ac32d1cd8477 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3080,10 +3080,6 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl) if (ret) return ret;
- ret = nvme_init_non_mdts_limits(ctrl); - if (ret < 0) - return ret; - ret = nvme_configure_apst(ctrl); if (ret < 0) return ret; @@ -4237,11 +4233,26 @@ static void nvme_scan_work(struct work_struct *work) { struct nvme_ctrl *ctrl = container_of(work, struct nvme_ctrl, scan_work); + int ret;
/* No tagset on a live ctrl means IO queues could not created */ if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset) return;
+ /* + * Identify controller limits can change at controller reset due to + * new firmware download, even though it is not common we cannot ignore + * such scenario. Controller's non-mdts limits are reported in the unit + * of logical blocks that is dependent on the format of attached + * namespace. Hence re-read the limits at the time of ns allocation. + */ + ret = nvme_init_non_mdts_limits(ctrl); + if (ret < 0) { + dev_warn(ctrl->device, + "reading non-mdts-limits failed: %d\n", ret); + return; + } + if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) { dev_info(ctrl->device, "rescanning namespaces.\n"); nvme_clear_changed_ns_log(ctrl);
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit 1a6dd9996699889313327be03981716a8337656b ]
clang emits a -Wunaligned-access warning on union mcp251xfd_tx_ojb_load_buf.
The reason is that field hw_tx_obj (not declared as packed) is being packed right after a 16 bits field inside a packed struct:
| union mcp251xfd_tx_obj_load_buf { | struct __packed { | struct mcp251xfd_buf_cmd cmd; | /* ^ 16 bits fields */ | struct mcp251xfd_hw_tx_obj_raw hw_tx_obj; | /* ^ not declared as packed */ | } nocrc; | struct __packed { | struct mcp251xfd_buf_cmd_crc cmd; | struct mcp251xfd_hw_tx_obj_raw hw_tx_obj; | __be16 crc; | } crc; | } ____cacheline_aligned;
Starting from LLVM 14, having an unpacked struct nested in a packed struct triggers a warning. c.f. [1].
This is a false positive because the field is always being accessed with the relevant put_unaligned_*() function. Adding __packed to the structure declaration silences the warning.
[1] https://github.com/llvm/llvm-project/issues/55520
Link: https://lore.kernel.org/all/20220518114357.55452-1-mailhol.vincent@wanadoo.f... Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Reported-by: kernel test robot lkp@intel.com Tested-by: Nathan Chancellor nathan@kernel.org # build Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/spi/mcp251xfd/mcp251xfd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h index 9cb6b5ad8dda..60e56fa4601d 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd.h +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd.h @@ -441,7 +441,7 @@ struct mcp251xfd_hw_tef_obj { /* The tx_obj_raw version is used in spi async, i.e. without * regmap. We have to take care of endianness ourselves. */ -struct mcp251xfd_hw_tx_obj_raw { +struct __packed mcp251xfd_hw_tx_obj_raw { __le32 id; __le32 flags; u8 data[sizeof_field(struct canfd_frame, data)];
From: Borislav Petkov bp@suse.de
[ Upstream commit 9c55d99e099bd7aa6b91fce8718505c35d5dfc65 ]
Add an explicit dependency to the respective CPU vendor so that the respective microcode support for it gets built only when that support is enabled.
Reported-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/8ead0da9-9545-b10d-e3db-7df1a1f219e4@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4bed3abf444d..b2c65f573353 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1313,7 +1313,7 @@ config MICROCODE
config MICROCODE_INTEL bool "Intel microcode loading support" - depends on MICROCODE + depends on CPU_SUP_INTEL && MICROCODE default MICROCODE help This options enables microcode patch loading support for Intel @@ -1325,7 +1325,7 @@ config MICROCODE_INTEL
config MICROCODE_AMD bool "AMD microcode loading support" - depends on MICROCODE + depends on CPU_SUP_AMD && MICROCODE help If you select this option, microcode patch loading support for AMD processors will be enabled.
From: Alex Elder elder@linaro.org
[ Upstream commit 332ef7c814bdd60f08d0d9013d0e1104798b2d23 ]
If we program an RX endpoint to have no header (header length is 0), header-related endpoint configuration values are meaningless and are ignored.
The only case we support that defines a header is QMAP endpoints. In ipa_endpoint_init_hdr_ext() we set the endianness mask value unconditionally, but it should not be done if there is no header (meaning it is not configured for QMAP).
Set the endianness conditionally, and rearrange the logic in that function slightly to avoid testing the qmap flag twice.
Delete an incorrect comment in ipa_endpoint_init_aggr().
Signed-off-by: Alex Elder elder@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipa/ipa_endpoint.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index 53764f3c0c7e..55322800ba58 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -587,19 +587,23 @@ static void ipa_endpoint_init_hdr_ext(struct ipa_endpoint *endpoint) struct ipa *ipa = endpoint->ipa; u32 val = 0;
- val |= HDR_ENDIANNESS_FMASK; /* big endian */ - - /* A QMAP header contains a 6 bit pad field at offset 0. The RMNet - * driver assumes this field is meaningful in packets it receives, - * and assumes the header's payload length includes that padding. - * The RMNet driver does *not* pad packets it sends, however, so - * the pad field (although 0) should be ignored. - */ - if (endpoint->data->qmap && !endpoint->toward_ipa) { - val |= HDR_TOTAL_LEN_OR_PAD_VALID_FMASK; - /* HDR_TOTAL_LEN_OR_PAD is 0 (pad, not total_len) */ - val |= HDR_PAYLOAD_LEN_INC_PADDING_FMASK; - /* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0 */ + if (endpoint->data->qmap) { + /* We have a header, so we must specify its endianness */ + val |= HDR_ENDIANNESS_FMASK; /* big endian */ + + /* A QMAP header contains a 6 bit pad field at offset 0. + * The RMNet driver assumes this field is meaningful in + * packets it receives, and assumes the header's payload + * length includes that padding. The RMNet driver does + * *not* pad packets it sends, however, so the pad field + * (although 0) should be ignored. + */ + if (!endpoint->toward_ipa) { + val |= HDR_TOTAL_LEN_OR_PAD_VALID_FMASK; + /* HDR_TOTAL_LEN_OR_PAD is 0 (pad, not total_len) */ + val |= HDR_PAYLOAD_LEN_INC_PADDING_FMASK; + /* HDR_TOTAL_LEN_OR_PAD_OFFSET is 0 */ + } }
/* HDR_PAYLOAD_LEN_INC_PADDING is 0 */ @@ -759,8 +763,6 @@ static void ipa_endpoint_init_aggr(struct ipa_endpoint *endpoint)
close_eof = rx_data->aggr_close_eof; val |= aggr_sw_eof_active_encoded(version, close_eof); - - /* AGGR_HARD_BYTE_LIMIT_ENABLE is 0 */ } else { val |= u32_encode_bits(IPA_ENABLE_DEAGGR, AGGR_EN_FMASK);
From: Yuntao Wang ytcoode@gmail.com
[ Upstream commit b23316aabffa835ecc516cb81daeef5b9155e8a5 ]
Currently the trampoline_count test doesn't include any fmod_ret bpf programs, fix it to make the test cover all possible trampoline program types.
Since fmod_ret bpf programs can't be attached to __set_task_comm function, as it's neither whitelisted for error injection nor a security hook, change it to bpf_modify_return_test.
This patch also does some other cleanups such as removing duplicate code, dropping inconsistent comments, etc.
Signed-off-by: Yuntao Wang ytcoode@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20220519150610.601313-1-ytcoode@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/bpf.h | 2 +- .../bpf/prog_tests/trampoline_count.c | 134 +++++++----------- .../bpf/progs/test_trampoline_count.c | 16 ++- 3 files changed, 61 insertions(+), 91 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index bdb5298735ce..f084b251fce7 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -672,7 +672,7 @@ struct btf_func_model { #define BPF_TRAMP_F_RET_FENTRY_RET BIT(4)
/* Each call __bpf_prog_enter + call bpf_func + call __bpf_prog_exit is ~50 - * bytes on x86. Pick a number to fit into BPF_IMAGE_SIZE / 2 + * bytes on x86. */ #define BPF_MAX_TRAMP_PROGS 38
diff --git a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c index 9c795ee52b7b..b0acbda6dbf5 100644 --- a/tools/testing/selftests/bpf/prog_tests/trampoline_count.c +++ b/tools/testing/selftests/bpf/prog_tests/trampoline_count.c @@ -1,126 +1,94 @@ // SPDX-License-Identifier: GPL-2.0-only #define _GNU_SOURCE -#include <sched.h> -#include <sys/prctl.h> #include <test_progs.h>
#define MAX_TRAMP_PROGS 38
struct inst { struct bpf_object *obj; - struct bpf_link *link_fentry; - struct bpf_link *link_fexit; + struct bpf_link *link; };
-static int test_task_rename(void) -{ - int fd, duration = 0, err; - char buf[] = "test_overhead"; - - fd = open("/proc/self/comm", O_WRONLY|O_TRUNC); - if (CHECK(fd < 0, "open /proc", "err %d", errno)) - return -1; - err = write(fd, buf, sizeof(buf)); - if (err < 0) { - CHECK(err < 0, "task rename", "err %d", errno); - close(fd); - return -1; - } - close(fd); - return 0; -} - -static struct bpf_link *load(struct bpf_object *obj, const char *name) +static struct bpf_program *load_prog(char *file, char *name, struct inst *inst) { + struct bpf_object *obj; struct bpf_program *prog; - int duration = 0; + int err; + + obj = bpf_object__open_file(file, NULL); + if (!ASSERT_OK_PTR(obj, "obj_open_file")) + return NULL; + + inst->obj = obj; + + err = bpf_object__load(obj); + if (!ASSERT_OK(err, "obj_load")) + return NULL;
prog = bpf_object__find_program_by_name(obj, name); - if (CHECK(!prog, "find_probe", "prog '%s' not found\n", name)) - return ERR_PTR(-EINVAL); - return bpf_program__attach_trace(prog); + if (!ASSERT_OK_PTR(prog, "obj_find_prog")) + return NULL; + + return prog; }
/* TODO: use different target function to run in concurrent mode */ void serial_test_trampoline_count(void) { - const char *fentry_name = "prog1"; - const char *fexit_name = "prog2"; - const char *object = "test_trampoline_count.o"; - struct inst inst[MAX_TRAMP_PROGS] = {}; - int err, i = 0, duration = 0; - struct bpf_object *obj; + char *file = "test_trampoline_count.o"; + char *const progs[] = { "fentry_test", "fmod_ret_test", "fexit_test" }; + struct inst inst[MAX_TRAMP_PROGS + 1] = {}; + struct bpf_program *prog; struct bpf_link *link; - char comm[16] = {}; + int prog_fd, err, i; + LIBBPF_OPTS(bpf_test_run_opts, opts);
/* attach 'allowed' trampoline programs */ for (i = 0; i < MAX_TRAMP_PROGS; i++) { - obj = bpf_object__open_file(object, NULL); - if (!ASSERT_OK_PTR(obj, "obj_open_file")) { - obj = NULL; + prog = load_prog(file, progs[i % ARRAY_SIZE(progs)], &inst[i]); + if (!prog) goto cleanup; - }
- err = bpf_object__load(obj); - if (CHECK(err, "obj_load", "err %d\n", err)) + link = bpf_program__attach(prog); + if (!ASSERT_OK_PTR(link, "attach_prog")) goto cleanup; - inst[i].obj = obj; - obj = NULL; - - if (rand() % 2) { - link = load(inst[i].obj, fentry_name); - if (!ASSERT_OK_PTR(link, "attach_prog")) { - link = NULL; - goto cleanup; - } - inst[i].link_fentry = link; - } else { - link = load(inst[i].obj, fexit_name); - if (!ASSERT_OK_PTR(link, "attach_prog")) { - link = NULL; - goto cleanup; - } - inst[i].link_fexit = link; - } + + inst[i].link = link; }
/* and try 1 extra.. */ - obj = bpf_object__open_file(object, NULL); - if (!ASSERT_OK_PTR(obj, "obj_open_file")) { - obj = NULL; + prog = load_prog(file, "fmod_ret_test", &inst[i]); + if (!prog) goto cleanup; - } - - err = bpf_object__load(obj); - if (CHECK(err, "obj_load", "err %d\n", err)) - goto cleanup_extra;
/* ..that needs to fail */ - link = load(obj, fentry_name); - err = libbpf_get_error(link); - if (!ASSERT_ERR_PTR(link, "cannot attach over the limit")) { - bpf_link__destroy(link); - goto cleanup_extra; + link = bpf_program__attach(prog); + if (!ASSERT_ERR_PTR(link, "attach_prog")) { + inst[i].link = link; + goto cleanup; }
/* with E2BIG error */ - ASSERT_EQ(err, -E2BIG, "proper error check"); - ASSERT_EQ(link, NULL, "ptr_is_null"); + if (!ASSERT_EQ(libbpf_get_error(link), -E2BIG, "E2BIG")) + goto cleanup; + if (!ASSERT_EQ(link, NULL, "ptr_is_null")) + goto cleanup;
/* and finaly execute the probe */ - if (CHECK_FAIL(prctl(PR_GET_NAME, comm, 0L, 0L, 0L))) - goto cleanup_extra; - CHECK_FAIL(test_task_rename()); - CHECK_FAIL(prctl(PR_SET_NAME, comm, 0L, 0L, 0L)); + prog_fd = bpf_program__fd(prog); + if (!ASSERT_GE(prog_fd, 0, "bpf_program__fd")) + goto cleanup; + + err = bpf_prog_test_run_opts(prog_fd, &opts); + if (!ASSERT_OK(err, "bpf_prog_test_run_opts")) + goto cleanup; + + ASSERT_EQ(opts.retval & 0xffff, 4, "bpf_modify_return_test.result"); + ASSERT_EQ(opts.retval >> 16, 1, "bpf_modify_return_test.side_effect");
-cleanup_extra: - bpf_object__close(obj); cleanup: - if (i >= MAX_TRAMP_PROGS) - i = MAX_TRAMP_PROGS - 1; for (; i >= 0; i--) { - bpf_link__destroy(inst[i].link_fentry); - bpf_link__destroy(inst[i].link_fexit); + bpf_link__destroy(inst[i].link); bpf_object__close(inst[i].obj); } } diff --git a/tools/testing/selftests/bpf/progs/test_trampoline_count.c b/tools/testing/selftests/bpf/progs/test_trampoline_count.c index f030e469d05b..7765720da7d5 100644 --- a/tools/testing/selftests/bpf/progs/test_trampoline_count.c +++ b/tools/testing/selftests/bpf/progs/test_trampoline_count.c @@ -1,20 +1,22 @@ // SPDX-License-Identifier: GPL-2.0 -#include <stdbool.h> -#include <stddef.h> #include <linux/bpf.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h>
-struct task_struct; +SEC("fentry/bpf_modify_return_test") +int BPF_PROG(fentry_test, int a, int *b) +{ + return 0; +}
-SEC("fentry/__set_task_comm") -int BPF_PROG(prog1, struct task_struct *tsk, const char *buf, bool exec) +SEC("fmod_ret/bpf_modify_return_test") +int BPF_PROG(fmod_ret_test, int a, int *b, int ret) { return 0; }
-SEC("fexit/__set_task_comm") -int BPF_PROG(prog2, struct task_struct *tsk, const char *buf, bool exec) +SEC("fexit/bpf_modify_return_test") +int BPF_PROG(fexit_test, int a, int *b, int ret) { return 0; }
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 30b5e6ef4a32ea4985b99200e06d6660a69f9246 ]
The macros implementing Atari ROM port I/O writes do not cast away their output, unlike similar implementations for other I/O buses. When they are combined using conditional expressions in the definitions of outb() and friends, this triggers sparse warnings like:
drivers/net/appletalk/cops.c:382:17: error: incompatible types in conditional expression (different base types): drivers/net/appletalk/cops.c:382:17: unsigned char drivers/net/appletalk/cops.c:382:17: void
Fix this by adding casts to "void".
Reported-by: kernel test robot lkp@intel.com Reported-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Guenter Roeck linux@roeck-us.net Reviewed-by: Michael Schmitz schmitzmic@gmail.com Link: https://lore.kernel.org/r/c15bedc83d90a14fffcd5b1b6bfb32b8a80282c5.165305709... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/m68k/include/asm/raw_io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h index 80eb2396d01e..3ba40bc1dfaa 100644 --- a/arch/m68k/include/asm/raw_io.h +++ b/arch/m68k/include/asm/raw_io.h @@ -80,14 +80,14 @@ ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
#define rom_out_8(addr, b) \ - ({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \ + (void)({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \ __w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); }) #define rom_out_be16(addr, w) \ - ({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \ + (void)({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \ __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \ __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); }) #define rom_out_le16(addr, w) \ - ({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \ + (void)({u16 __maybe_unused __w, __v = (w); u32 _addr = ((u32) (addr)); \ __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \ __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); })
From: Mårten Lindahl marten.lindahl@axis.com
[ Upstream commit 28bf22ef93eceb42c7583f0909bc9dedc07770e3 ]
The pmbus core does not have operations for getting or setting voltage. Add functions get/set voltage for the dynamic regulator framework.
Signed-off-by: Mårten Lindahl marten.lindahl@axis.com Link: https://lore.kernel.org/r/20220503104631.3515715-5-marten.lindahl@axis.com [groeck: cosmetic alignment / empty line fixes] Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/pmbus_core.c | 67 ++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index d93574d6a1fb..5a1796650f5b 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2548,11 +2548,78 @@ static int pmbus_regulator_get_error_flags(struct regulator_dev *rdev, unsigned return 0; }
+static int pmbus_regulator_get_voltage(struct regulator_dev *rdev) +{ + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor s = { + .page = rdev_get_id(rdev), + .class = PSC_VOLTAGE_OUT, + .convert = true, + }; + + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_READ_VOUT); + if (s.data < 0) + return s.data; + + return (int)pmbus_reg2data(data, &s) * 1000; /* unit is uV */ +} + +static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv, + int max_uv, unsigned int *selector) +{ + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); + struct pmbus_sensor s = { + .page = rdev_get_id(rdev), + .class = PSC_VOLTAGE_OUT, + .convert = true, + .data = -1, + }; + int val = DIV_ROUND_CLOSEST(min_uv, 1000); /* convert to mV */ + int low, high; + + *selector = 0; + + if (pmbus_check_word_register(client, s.page, PMBUS_MFR_VOUT_MIN)) + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_MFR_VOUT_MIN); + if (s.data < 0) { + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_VOUT_MARGIN_LOW); + if (s.data < 0) + return s.data; + } + low = pmbus_reg2data(data, &s); + + s.data = -1; + if (pmbus_check_word_register(client, s.page, PMBUS_MFR_VOUT_MAX)) + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_MFR_VOUT_MAX); + if (s.data < 0) { + s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_VOUT_MARGIN_HIGH); + if (s.data < 0) + return s.data; + } + high = pmbus_reg2data(data, &s); + + /* Make sure we are within margins */ + if (low > val) + val = low; + if (high < val) + val = high; + + val = pmbus_data2reg(data, &s, val); + + return _pmbus_write_word_data(client, s.page, PMBUS_VOUT_COMMAND, (u16)val); +} + const struct regulator_ops pmbus_regulator_ops = { .enable = pmbus_regulator_enable, .disable = pmbus_regulator_disable, .is_enabled = pmbus_regulator_is_enabled, .get_error_flags = pmbus_regulator_get_error_flags, + .get_voltage = pmbus_regulator_get_voltage, + .set_voltage = pmbus_regulator_set_voltage, }; EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, PMBUS);
From: David Howells dhowells@redhat.com
[ Upstream commit 4ba68c5192554876bd8c3afd904e3064d2915341 ]
If at the end of rxrpc sendmsg() or rxrpc_kernel_send_data() the call that was being given data was aborted remotely or otherwise failed, return an error rather than returning the amount of data buffered for transmission.
The call (presumably) did not complete, so there's not much point continuing with it. AF_RXRPC considers it "complete" and so will be unwilling to do anything else with it - and won't send a notification for it, deeming the return from sendmsg sufficient.
Not returning an error causes afs to incorrectly handle a StoreData operation that gets interrupted by a change of address due to NAT reconfiguration.
This doesn't normally affect most operations since their request parameters tend to fit into a single UDP packet and afs_make_call() returns before the server responds; StoreData is different as it involves transmission of a lot of data.
This can be triggered on a client by doing something like:
dd if=/dev/zero of=/afs/example.com/foo bs=1M count=512
at one prompt, and then changing the network address at another prompt, e.g.:
ifconfig enp6s0 inet 192.168.6.2 && route add 192.168.6.1 dev enp6s0
Tracing packets on an Auristor fileserver looks something like:
192.168.6.1 -> 192.168.6.3 RX 107 ACK Idle Seq: 0 Call: 4 Source Port: 7000 Destination Port: 7001 192.168.6.3 -> 192.168.6.1 AFS (RX) 1482 FS Request: Unknown(64538) (64538) 192.168.6.3 -> 192.168.6.1 AFS (RX) 1482 FS Request: Unknown(64538) (64538) 192.168.6.1 -> 192.168.6.3 RX 107 ACK Idle Seq: 0 Call: 4 Source Port: 7000 Destination Port: 7001 <ARP exchange for 192.168.6.2> 192.168.6.2 -> 192.168.6.1 AFS (RX) 1482 FS Request: Unknown(0) (0) 192.168.6.2 -> 192.168.6.1 AFS (RX) 1482 FS Request: Unknown(0) (0) 192.168.6.1 -> 192.168.6.2 RX 107 ACK Exceeds Window Seq: 0 Call: 4 Source Port: 7000 Destination Port: 7001 192.168.6.1 -> 192.168.6.2 RX 74 ABORT Seq: 0 Call: 4 Source Port: 7000 Destination Port: 7001 192.168.6.1 -> 192.168.6.2 RX 74 ABORT Seq: 29321 Call: 4 Source Port: 7000 Destination Port: 7001
The Auristor fileserver logs code -453 (RXGEN_SS_UNMARSHAL), but the abort code received by kafs is -5 (RX_PROTOCOL_ERROR) as the rx layer sees the condition and generates an abort first and the unmarshal error is a consequence of that at the application layer.
Reported-by: Marc Dionne marc.dionne@auristor.com Signed-off-by: David Howells dhowells@redhat.com cc: linux-afs@lists.infradead.org Link: http://lists.infradead.org/pipermail/linux-afs/2021-December/004810.html # v1 Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/sendmsg.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index af8ad6c30b9f..1d38e279e2ef 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -444,6 +444,12 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
success: ret = copied; + if (READ_ONCE(call->state) == RXRPC_CALL_COMPLETE) { + read_lock_bh(&call->state_lock); + if (call->error < 0) + ret = call->error; + read_unlock_bh(&call->state_lock); + } out: call->tx_pending = skb; _leave(" = %d", ret);
From: David Howells dhowells@redhat.com
[ Upstream commit de696c4784f0706884458893c5a6c39b3a3ff65c ]
The RX_USER_ABORT code should really only be used to indicate that the user of the rxrpc service (ie. userspace) implicitly caused a call to be aborted - for instance if the AF_RXRPC socket is closed whilst the call was in progress. (The user may also explicitly abort a call and specify the abort code to use).
Change some of the points of generation to use other abort codes instead:
(1) Abort the call with RXGEN_SS_UNMARSHAL or RXGEN_CC_UNMARSHAL if we see ENOMEM and EFAULT during received data delivery and abort with RX_CALL_DEAD in the default case.
(2) Abort with RXGEN_SS_MARSHAL if we get ENOMEM whilst trying to send a reply.
(3) Abort with RX_CALL_DEAD if we stop hearing from the peer if we had heard from the peer and abort with RX_CALL_TIMEOUT if we hadn't.
(4) Abort with RX_CALL_DEAD if we try to disconnect a call that's not completed successfully or been aborted.
Reported-by: Jeffrey Altman jaltman@auristor.com Signed-off-by: David Howells dhowells@redhat.com cc: Marc Dionne marc.dionne@auristor.com cc: linux-afs@lists.infradead.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- fs/afs/rxrpc.c | 8 +++++--- net/rxrpc/call_event.c | 4 ++-- net/rxrpc/conn_object.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index 23a1a92d64bb..a5434f3e57c6 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -537,6 +537,8 @@ static void afs_deliver_to_call(struct afs_call *call) case -ENODATA: case -EBADMSG: case -EMSGSIZE: + case -ENOMEM: + case -EFAULT: abort_code = RXGEN_CC_UNMARSHAL; if (state != AFS_CALL_CL_AWAIT_REPLY) abort_code = RXGEN_SS_UNMARSHAL; @@ -544,7 +546,7 @@ static void afs_deliver_to_call(struct afs_call *call) abort_code, ret, "KUM"); goto local_abort; default: - abort_code = RX_USER_ABORT; + abort_code = RX_CALL_DEAD; rxrpc_kernel_abort_call(call->net->socket, call->rxcall, abort_code, ret, "KER"); goto local_abort; @@ -836,7 +838,7 @@ void afs_send_empty_reply(struct afs_call *call) case -ENOMEM: _debug("oom"); rxrpc_kernel_abort_call(net->socket, call->rxcall, - RX_USER_ABORT, -ENOMEM, "KOO"); + RXGEN_SS_MARSHAL, -ENOMEM, "KOO"); fallthrough; default: _leave(" [error]"); @@ -878,7 +880,7 @@ void afs_send_simple_reply(struct afs_call *call, const void *buf, size_t len) if (n == -ENOMEM) { _debug("oom"); rxrpc_kernel_abort_call(net->socket, call->rxcall, - RX_USER_ABORT, -ENOMEM, "KOO"); + RXGEN_SS_MARSHAL, -ENOMEM, "KOO"); } _leave(" [error]"); } diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index 22e05de5d1ca..e426f6831aab 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c @@ -377,9 +377,9 @@ void rxrpc_process_call(struct work_struct *work) if (test_bit(RXRPC_CALL_RX_HEARD, &call->flags) && (int)call->conn->hi_serial - (int)call->rx_serial > 0) { trace_rxrpc_call_reset(call); - rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ECONNRESET); + rxrpc_abort_call("EXP", call, 0, RX_CALL_DEAD, -ECONNRESET); } else { - rxrpc_abort_call("EXP", call, 0, RX_USER_ABORT, -ETIME); + rxrpc_abort_call("EXP", call, 0, RX_CALL_TIMEOUT, -ETIME); } set_bit(RXRPC_CALL_EV_ABORT, &call->events); goto recheck_state; diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index b2159dbf5412..660cd9b1a465 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c @@ -183,7 +183,7 @@ void __rxrpc_disconnect_call(struct rxrpc_connection *conn, chan->last_type = RXRPC_PACKET_TYPE_ABORT; break; default: - chan->last_abort = RX_USER_ABORT; + chan->last_abort = RX_CALL_DEAD; chan->last_type = RXRPC_PACKET_TYPE_ABORT; break; }
From: David Howells dhowells@redhat.com
[ Upstream commit adc9613ff66c26ebaff9814973181ac178beb90b ]
If a client's address changes, say if it is NAT'd, this can disrupt an in progress operation. For most operations, this is not much of a problem, but StoreData can be different as some servers modify the target file as the data comes in, so if a store request is disrupted, the file can get corrupted on the server.
The problem is that the server doesn't recognise packets that come after the change of address as belonging to the original client and will bounce them, either by sending an OUT_OF_SEQUENCE ACK to the apparent new call if the packet number falls within the initial sequence number window of a call or by sending an EXCEEDS_WINDOW ACK if it falls outside and then aborting it. In both cases, firstPacket will be 1 and previousPacket will be 0 in the ACK information.
Fix this by the following means:
(1) If a client call receives an EXCEEDS_WINDOW ACK with firstPacket as 1 and previousPacket as 0, assume this indicates that the server saw the incoming packets from a different peer and thus as a different call. Fail the call with error -ENETRESET.
(2) Also fail the call if a similar OUT_OF_SEQUENCE ACK occurs if the first packet has been hard-ACK'd. If it hasn't been hard-ACK'd, the ACK packet will cause it to get retransmitted, so the call will just be repeated.
(3) Make afs_select_fileserver() treat -ENETRESET as a straight fail of the operation.
(4) Prioritise the error code over things like -ECONNRESET as the server did actually respond.
(5) Make writeback treat -ENETRESET as a retryable error and make it redirty all the pages involved in a write so that the VM will retry.
Note that there is still a circumstance that I can't easily deal with: if the operation is fully received and processed by the server, but the reply is lost due to address change. There's no way to know if the op happened. We can examine the server, but a conflicting change could have been made by a third party - and we can't tell the difference. In such a case, a message like:
kAFS: vnode modified {100058:146266} b7->b8 YFS.StoreData64 (op=2646a)
will be logged to dmesg on the next op to touch the file and the client will reset the inode state, including invalidating clean parts of the pagecache.
Reported-by: Marc Dionne marc.dionne@auristor.com Signed-off-by: David Howells dhowells@redhat.com cc: linux-afs@lists.infradead.org Link: http://lists.infradead.org/pipermail/linux-afs/2021-December/004811.html # v1 Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- fs/afs/misc.c | 5 ++++- fs/afs/rotate.c | 4 ++++ fs/afs/write.c | 1 + net/rxrpc/input.c | 27 +++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/fs/afs/misc.c b/fs/afs/misc.c index 1d1a8debe472..933e67fcdab1 100644 --- a/fs/afs/misc.c +++ b/fs/afs/misc.c @@ -163,8 +163,11 @@ void afs_prioritise_error(struct afs_error *e, int error, u32 abort_code) return;
case -ECONNABORTED: + error = afs_abort_to_error(abort_code); + fallthrough; + case -ENETRESET: /* Responded, but we seem to have changed address */ e->responded = true; - e->error = afs_abort_to_error(abort_code); + e->error = error; return; } } diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c index 79e1a5f6701b..a840c3588ebb 100644 --- a/fs/afs/rotate.c +++ b/fs/afs/rotate.c @@ -292,6 +292,10 @@ bool afs_select_fileserver(struct afs_operation *op) op->error = error; goto iterate_address;
+ case -ENETRESET: + pr_warn("kAFS: Peer reset %s (op=%x)\n", + op->type ? op->type->name : "???", op->debug_id); + fallthrough; case -ECONNRESET: _debug("call reset"); op->error = error; diff --git a/fs/afs/write.c b/fs/afs/write.c index 4763132ca57e..c1bc52ac7de1 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -636,6 +636,7 @@ static ssize_t afs_write_back_from_locked_folio(struct address_space *mapping, case -EKEYEXPIRED: case -EKEYREJECTED: case -EKEYREVOKED: + case -ENETRESET: afs_redirty_pages(wbc, mapping, start, len); mapping_set_error(mapping, ret); break; diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index dc201363f2c4..67d3eba60dc7 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c @@ -903,6 +903,33 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) rxrpc_propose_ack_respond_to_ack); }
+ /* If we get an EXCEEDS_WINDOW ACK from the server, it probably + * indicates that the client address changed due to NAT. The server + * lost the call because it switched to a different peer. + */ + if (unlikely(buf.ack.reason == RXRPC_ACK_EXCEEDS_WINDOW) && + first_soft_ack == 1 && + prev_pkt == 0 && + rxrpc_is_client_call(call)) { + rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED, + 0, -ENETRESET); + return; + } + + /* If we get an OUT_OF_SEQUENCE ACK from the server, that can also + * indicate a change of address. However, we can retransmit the call + * if we still have it buffered to the beginning. + */ + if (unlikely(buf.ack.reason == RXRPC_ACK_OUT_OF_SEQUENCE) && + first_soft_ack == 1 && + prev_pkt == 0 && + call->tx_hard_ack == 0 && + rxrpc_is_client_call(call)) { + rxrpc_set_call_completion(call, RXRPC_CALL_REMOTELY_ABORTED, + 0, -ENETRESET); + return; + } + /* Discard any out-of-order or duplicate ACKs (outside lock). */ if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial,
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 9dec850fd7c210a04b4707df8e6c95bfafdd6a4b ]
GCC 12 currently generates a rather inconsistent warning:
drivers/net/ethernet/broadcom/tg3.c:17795:51: warning: array subscript 5 is above array bounds of ‘struct tg3_napi[5]’ [-Warray-bounds] 17795 | struct tg3_napi *tnapi = &tp->napi[i]; | ~~~~~~~~^~~
i is guaranteed < tp->irq_max which in turn is either 1 or 5. There are more loops like this one in the driver, but strangely GCC 12 dislikes only this single one.
Silence this silliness for now.
Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/Makefile | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile index 0ddfb5b5d53c..2e6c5f258a1f 100644 --- a/drivers/net/ethernet/broadcom/Makefile +++ b/drivers/net/ethernet/broadcom/Makefile @@ -17,3 +17,8 @@ obj-$(CONFIG_BGMAC_BCMA) += bgmac-bcma.o bgmac-bcma-mdio.o obj-$(CONFIG_BGMAC_PLATFORM) += bgmac-platform.o obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o obj-$(CONFIG_BNXT) += bnxt/ + +# FIXME: temporarily silence -Warray-bounds on non W=1+ builds +ifndef KBUILD_EXTRA_WARN +CFLAGS_tg3.o += -Wno-array-bounds +endif
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
[ Upstream commit e0687fe958f763f1790f22ed5483025b7624e744 ]
Returning an error value in an i2c remove callback results in an error message being emitted by the i2c core, but otherwise it doesn't make a difference. The device goes away anyhow and the devm cleanups are called.
As tpm_cr50_i2c_remove() emits an error message already and the additional error message by the i2c core doesn't add any useful information, change the return value to zero to suppress this error message.
Note that if i2c_clientdata is NULL, there is something really fishy. Assuming no memory corruption happened (then all bets are lost anyhow), tpm_cr50_i2c_remove() is only called after tpm_cr50_i2c_probe() returned successfully. So there was a tpm chip registered before and after tpm_cr50_i2c_remove() its privdata is freed but the associated character device isn't removed. If after that happened userspace accesses the character device it's likely that the freed memory is accessed. For that reason the warning message is made a bit more frightening.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_i2c_cr50.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_i2c_cr50.c b/drivers/char/tpm/tpm_tis_i2c_cr50.c index f6c0affbb456..bf608b6af339 100644 --- a/drivers/char/tpm/tpm_tis_i2c_cr50.c +++ b/drivers/char/tpm/tpm_tis_i2c_cr50.c @@ -768,8 +768,8 @@ static int tpm_cr50_i2c_remove(struct i2c_client *client) struct device *dev = &client->dev;
if (!chip) { - dev_err(dev, "Could not get client data at remove\n"); - return -ENODEV; + dev_crit(dev, "Could not get client data at remove, memory corruption ahead\n"); + return 0; }
tpm_chip_unregister(chip);
From: Yonghong Song yhs@fb.com
[ Upstream commit 4050764cbaa25760aab40857f723393c07898474 ]
Latest llvm-project upstream had a change of behavior related to qualifiers on function return type ([1]). This caused selftests btf_dump/btf_dump failure. The following example shows what changed.
$ cat t.c typedef const char * const (* const (* const fn_ptr_arr2_t[5])())(char * (*)(int)); struct t { int a; fn_ptr_arr2_t l; }; int foo(struct t *arg) { return arg->a; }
Compiled with latest upstream llvm15, $ clang -O2 -g -target bpf -S -emit-llvm t.c The related generated debuginfo IR looks like: !16 = !DIDerivedType(tag: DW_TAG_typedef, name: "fn_ptr_arr2_t", file: !1, line: 1, baseType: !17) !17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, size: 320, elements: !32) !18 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !19) !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) !20 = !DISubroutineType(types: !21) !21 = !{!22, null} !22 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !23, size: 64) !23 = !DISubroutineType(types: !24) !24 = !{!25, !28} !25 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !26, size: 64) !26 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !27) !27 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) You can see two intermediate const qualifier to pointer are dropped in debuginfo IR.
With llvm14, we have following debuginfo IR: !16 = !DIDerivedType(tag: DW_TAG_typedef, name: "fn_ptr_arr2_t", file: !1, line: 1, baseType: !17) !17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, size: 320, elements: !34) !18 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !19) !19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64) !20 = !DISubroutineType(types: !21) !21 = !{!22, null} !22 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !23) !23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64) !24 = !DISubroutineType(types: !25) !25 = !{!26, !30} !26 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !27) !27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !28, size: 64) !28 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !29) !29 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) All const qualifiers are preserved.
To adapt the selftest to both old and new llvm, this patch removed the intermediate const qualifier in const-to-ptr types, to make the test succeed again.
[1] https://reviews.llvm.org/D125919
Reported-by: Mykola Lysenko mykolal@fb.com Signed-off-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/r/20220523152044.3905809-1-yhs@fb.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c b/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c index 1c7105fcae3c..4ee4748133fe 100644 --- a/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c +++ b/tools/testing/selftests/bpf/progs/btf_dump_test_case_syntax.c @@ -94,7 +94,7 @@ typedef void (* (*signal_t)(int, void (*)(int)))(int);
typedef char * (*fn_ptr_arr1_t[10])(int **);
-typedef char * (* const (* const fn_ptr_arr2_t[5])())(char * (*)(int)); +typedef char * (* (* const fn_ptr_arr2_t[5])())(char * (*)(int));
struct struct_w_typedefs { int_t a;
From: Bob Peterson rpeterso@redhat.com
[ Upstream commit 5fcff61eea9efd1f4b60e89d2d686b5feaea100f ]
Before this patch, functions gfs2_qa_get and _put used the i_rw_mutex to prevent simultaneous access to its i_qadata. But i_rw_mutex is now used for many other things, including iomap_begin and end, which causes a conflict according to lockdep. We cannot just remove the lock since simultaneous opens (gfs2_open -> gfs2_open_common -> gfs2_qa_get) can then stomp on each others values for i_qadata.
This patch solves the conflict by using the i_lock spin_lock in the inode to prevent simultaneous access.
Signed-off-by: Bob Peterson rpeterso@redhat.com Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/quota.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index be0997e24d60..dc77080a82bb 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -531,34 +531,42 @@ static void qdsb_put(struct gfs2_quota_data *qd) */ int gfs2_qa_get(struct gfs2_inode *ip) { - int error = 0; struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); + struct inode *inode = &ip->i_inode;
if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) return 0;
- down_write(&ip->i_rw_mutex); + spin_lock(&inode->i_lock); if (ip->i_qadata == NULL) { - ip->i_qadata = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS); - if (!ip->i_qadata) { - error = -ENOMEM; - goto out; - } + struct gfs2_qadata *tmp; + + spin_unlock(&inode->i_lock); + tmp = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS); + if (!tmp) + return -ENOMEM; + + spin_lock(&inode->i_lock); + if (ip->i_qadata == NULL) + ip->i_qadata = tmp; + else + kmem_cache_free(gfs2_qadata_cachep, tmp); } ip->i_qadata->qa_ref++; -out: - up_write(&ip->i_rw_mutex); - return error; + spin_unlock(&inode->i_lock); + return 0; }
void gfs2_qa_put(struct gfs2_inode *ip) { - down_write(&ip->i_rw_mutex); + struct inode *inode = &ip->i_inode; + + spin_lock(&inode->i_lock); if (ip->i_qadata && --ip->i_qadata->qa_ref == 0) { kmem_cache_free(gfs2_qadata_cachep, ip->i_qadata); ip->i_qadata = NULL; } - up_write(&ip->i_rw_mutex); + spin_unlock(&inode->i_lock); }
int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit caa28984163cb63ea0be4cb8dbf05defdc7303f9 ]
Commit c724c866bb70 ("linux/types.h: remove unnecessary __bitwise__") was right that there are no users of __bitwise__ in the kernel, but it turns out there are user space users of it that do expect it.
It is, after all, in the uapi directory, so user space usage is to be expected.
Instead of reverting the commit completely, let's just clarify the situation so that it doesn't happen again, and have some in-code explanations for why that "__bitwise__" still exists.
Reported-by: Jiri Slaby jirislaby@kernel.org Cc: Bjorn Helgaas helgaas@kernel.org Link: https://lore.kernel.org/all/b5c0a68d-8387-4909-beea-f70ab9e6e3d5@kernel.org/ Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/types.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/include/uapi/linux/types.h b/include/uapi/linux/types.h index c4dc597f3dcf..308433be33c2 100644 --- a/include/uapi/linux/types.h +++ b/include/uapi/linux/types.h @@ -26,6 +26,9 @@ #define __bitwise #endif
+/* The kernel doesn't use this legacy form, but user space does */ +#define __bitwise__ __bitwise + typedef __u16 __bitwise __le16; typedef __u16 __bitwise __be16; typedef __u32 __bitwise __le32;
From: Bodo Stroesser bostroesser@gmail.com
[ Upstream commit 325d5c5fb216674296f3902a8902b942da3adc5b ]
In tcmu_blocks_release(), lock_page() is called to prevent a race causing possible data corruption. Since lock_page() might sleep, calling it while holding XArray lock is a bug.
To fix this, replace the xas_for_each() call with xa_for_each_range(). Since the latter does its own handling of XArray locking, the xas_lock() and xas_unlock() calls around the original loop are no longer necessary.
The switch to xa_for_each_range() slows down the loop slightly. This is acceptable since tcmu_blocks_release() is not relevant for performance.
Link: https://lore.kernel.org/r/20220517192913.21405-1-bostroesser@gmail.com Fixes: bb9b9eb0ae2e ("scsi: target: tcmu: Fix possible data corruption") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Bodo Stroesser bostroesser@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_user.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index b1fd06edea59..3deaeecb712e 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -1661,13 +1661,14 @@ static int tcmu_check_and_free_pending_cmd(struct tcmu_cmd *cmd) static u32 tcmu_blocks_release(struct tcmu_dev *udev, unsigned long first, unsigned long last) { - XA_STATE(xas, &udev->data_pages, first * udev->data_pages_per_blk); struct page *page; + unsigned long dpi; u32 pages_freed = 0;
- xas_lock(&xas); - xas_for_each(&xas, page, (last + 1) * udev->data_pages_per_blk - 1) { - xas_store(&xas, NULL); + first = first * udev->data_pages_per_blk; + last = (last + 1) * udev->data_pages_per_blk - 1; + xa_for_each_range(&udev->data_pages, dpi, page, first, last) { + xa_erase(&udev->data_pages, dpi); /* * While reaching here there may be page faults occurring on * the to-be-released pages. A race condition may occur if @@ -1691,7 +1692,6 @@ static u32 tcmu_blocks_release(struct tcmu_dev *udev, unsigned long first, __free_page(page); pages_freed++; } - xas_unlock(&xas);
atomic_sub(pages_freed, &global_page_count);
From: Daniel Latypov dlatypov@google.com
[ Upstream commit 1b11063d32d7e11366e48be64215ff517ce32217 ]
The existing logic happens to work fine on UML, but is not correct when running on other arches.
1. We didn't initialize `int err`, and kunit_filter_suites() doesn't explicitly set it to 0 on success. So we had false "failures". Note: it doesn't happen on UML, causing this to get overlooked. 2. If we error out, we do not call kunit_handle_shutdown(). This makes kunit.py timeout when using a non-UML arch, since the QEMU process doesn't ever exit.
Fixes: a02353f49162 ("kunit: bail out of test filtering logic quicker if OOM") Signed-off-by: Daniel Latypov dlatypov@google.com Reviewed-by: Brendan Higgins brendanhiggins@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/kunit/executor.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index 2f73a6a35a7e..96f96e42ce06 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c @@ -247,13 +247,13 @@ int kunit_run_all_tests(void) .start = __kunit_suites_start, .end = __kunit_suites_end, }; - int err; + int err = 0;
if (filter_glob_param) { suite_set = kunit_filter_suites(&suite_set, filter_glob_param, &err); if (err) { pr_err("kunit executor: error filtering suites: %d\n", err); - return err; + goto out; } }
@@ -268,9 +268,10 @@ int kunit_run_all_tests(void) kunit_free_suite_set(suite_set); }
- kunit_handle_shutdown();
- return 0; +out: + kunit_handle_shutdown(); + return err; }
#if IS_BUILTIN(CONFIG_KUNIT_TEST)
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 22cbc6c2681a0a4fe76150270426e763d52353a4 ]
The documentation of the function rvt_error_qp says both r_lock and s_lock need to be held when calling that function. It also asserts using lockdep that both of those locks are held. rvt_error_qp is called form rvt_send_cq, which is called from rvt_qp_complete_swqe, which is called from rvt_send_complete, which is called from rvt_ruc_loopback in two places. Both of these places do not hold r_lock. Fix this by acquiring a spin_lock of r_lock in both of these places. The r_lock acquiring cannot be added in rvt_qp_complete_swqe because some of its other callers already have r_lock acquired.
Link: https://lore.kernel.org/r/20220228195144.71946-1-dossche.niels@gmail.com Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rdmavt/qp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 8ef112f883a7..3acab569fbb9 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -2775,7 +2775,7 @@ void rvt_qp_iter(struct rvt_dev_info *rdi, EXPORT_SYMBOL(rvt_qp_iter);
/* - * This should be called with s_lock held. + * This should be called with s_lock and r_lock held. */ void rvt_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe, enum ib_wc_status status) @@ -3134,7 +3134,9 @@ void rvt_ruc_loopback(struct rvt_qp *sqp) rvp->n_loop_pkts++; flush_send: sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; + spin_lock(&sqp->r_lock); rvt_send_complete(sqp, wqe, send_status); + spin_unlock(&sqp->r_lock); if (local_ops) { atomic_dec(&sqp->local_ops_pending); local_ops = 0; @@ -3188,7 +3190,9 @@ void rvt_ruc_loopback(struct rvt_qp *sqp) spin_unlock_irqrestore(&qp->r_lock, flags); serr_no_r_lock: spin_lock_irqsave(&sqp->s_lock, flags); + spin_lock(&sqp->r_lock); rvt_send_complete(sqp, wqe, send_status); + spin_unlock(&sqp->r_lock); if (sqp->ibqp.qp_type == IB_QPT_RC) { int lastwqe;
From: Mika Westerberg mika.westerberg@linux.intel.com
[ Upstream commit 03038d84ace72678a9944524508f218a00377dc0 ]
Intel DG2 discrete graphics PCIe endpoints advertise L1 acceptable exit latency to be < 1us even though they can actually tolerate unlimited exit latencies just fine. Quirk the L1 acceptable exit latency for these endpoints to be unlimited so ASPM L1 can be enabled.
[bhelgaas: use FIELD_GET/FIELD_PREP, wordsmith comment & commit log] Link: https://lore.kernel.org/r/20220405093810.76613-1-mika.westerberg@linux.intel... Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/quirks.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index da829274fc66..41aeaa235132 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -12,6 +12,7 @@ * file, where their drivers can use them. */
+#include <linux/bitfield.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/export.h> @@ -5895,3 +5896,49 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1533, rom_bar_overlap_defect); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1536, rom_bar_overlap_defect); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1537, rom_bar_overlap_defect); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1538, rom_bar_overlap_defect); + +#ifdef CONFIG_PCIEASPM +/* + * Several Intel DG2 graphics devices advertise that they can only tolerate + * 1us latency when transitioning from L1 to L0, which may prevent ASPM L1 + * from being enabled. But in fact these devices can tolerate unlimited + * latency. Override their Device Capabilities value to allow ASPM L1 to + * be enabled. + */ +static void aspm_l1_acceptable_latency(struct pci_dev *dev) +{ + u32 l1_lat = FIELD_GET(PCI_EXP_DEVCAP_L1, dev->devcap); + + if (l1_lat < 7) { + dev->devcap |= FIELD_PREP(PCI_EXP_DEVCAP_L1, 7); + pci_info(dev, "ASPM: overriding L1 acceptable latency from %#x to 0x7\n", + l1_lat); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f80, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f81, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f82, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f83, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f84, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f85, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f86, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f87, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x4f88, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5690, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5691, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5692, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5693, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5694, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5695, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a0, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a1, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a2, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a3, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a4, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a5, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56a6, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56b0, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56b1, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c0, aspm_l1_acceptable_latency); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x56c1, aspm_l1_acceptable_latency); +#endif
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit fbcd5ad7a419ad40644a0bb8b4152bc660172d8a ]
Fixes dtbs_check warnings like:
gic@1000: $nodename:0: 'gic@1000' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Acked-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/20220317115705.450427-1-krzysztof.kozlowski@canoni... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ox820.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/ox820.dtsi b/arch/arm/boot/dts/ox820.dtsi index 90846a7655b4..dde4364892bf 100644 --- a/arch/arm/boot/dts/ox820.dtsi +++ b/arch/arm/boot/dts/ox820.dtsi @@ -287,7 +287,7 @@ clocks = <&armclk>; };
- gic: gic@1000 { + gic: interrupt-controller@1000 { compatible = "arm,arm11mp-gic"; interrupt-controller; #interrupt-cells = <3>;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit c9bdd50d2019f78bf4c1f6a79254c27771901023 ]
Fixes dtbs_check warnings like:
$nodename:0: 'intc@fffed000' does not match '^interrupt-controller(@[0-9a-f,]+)*$'
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Acked-by: Dinh Nguyen dinguyen@kernel.org Link: https://lore.kernel.org/r/20220317115705.450427-2-krzysztof.kozlowski@canoni... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/socfpga.dtsi | 2 +- arch/arm/boot/dts/socfpga_arria10.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 7c1d6423d7f8..b8c5dd7860cb 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -46,7 +46,7 @@ <0xff113000 0x1000>; };
- intc: intc@fffed000 { + intc: interrupt-controller@fffed000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi index 3ba431dfa8c9..f1e50d2e623a 100644 --- a/arch/arm/boot/dts/socfpga_arria10.dtsi +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -38,7 +38,7 @@ <0xff113000 0x1000>; };
- intc: intc@ffffd000 { + intc: interrupt-controller@ffffd000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller;
From: Krzysztof Kozlowski krzk@kernel.org
[ Upstream commit 9e916fb9bc3d16066286f19fc9c51d26a6aec6bd ]
dtschema expects DMA channels in specific order (tx, rx and tx-sec). The order actually should not matter because dma-names is used however let's make it aligned with dtschema to suppress warnings like:
i2s@eee30000: dma-names: ['rx', 'tx', 'tx-sec'] is not valid under any of the given schemas
Signed-off-by: Krzysztof Kozlowski krzk@kernel.org Co-developed-by: Jonathan Bakker xc-racer2@live.ca Signed-off-by: Jonathan Bakker xc-racer2@live.ca Link: https://lore.kernel.org/r/CY4PR04MB056779A9C50DC95987C5272ACB1C9@CY4PR04MB05... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/s5pv210-aries.dtsi | 2 +- arch/arm/boot/dts/s5pv210.dtsi | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/s5pv210-aries.dtsi b/arch/arm/boot/dts/s5pv210-aries.dtsi index 26f2be2d9faa..c44fdf535795 100644 --- a/arch/arm/boot/dts/s5pv210-aries.dtsi +++ b/arch/arm/boot/dts/s5pv210-aries.dtsi @@ -636,7 +636,7 @@ };
&i2s0 { - dmas = <&pdma0 9>, <&pdma0 10>, <&pdma0 11>; + dmas = <&pdma0 10>, <&pdma0 9>, <&pdma0 11>; status = "okay"; };
diff --git a/arch/arm/boot/dts/s5pv210.dtsi b/arch/arm/boot/dts/s5pv210.dtsi index 353ba7b09a0c..c5265f3ae31d 100644 --- a/arch/arm/boot/dts/s5pv210.dtsi +++ b/arch/arm/boot/dts/s5pv210.dtsi @@ -239,8 +239,8 @@ reg = <0xeee30000 0x1000>; interrupt-parent = <&vic2>; interrupts = <16>; - dma-names = "rx", "tx", "tx-sec"; - dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>; + dma-names = "tx", "rx", "tx-sec"; + dmas = <&pdma1 10>, <&pdma1 9>, <&pdma1 11>; clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; @@ -259,8 +259,8 @@ reg = <0xe2100000 0x1000>; interrupt-parent = <&vic2>; interrupts = <17>; - dma-names = "rx", "tx"; - dmas = <&pdma1 12>, <&pdma1 13>; + dma-names = "tx", "rx"; + dmas = <&pdma1 13>, <&pdma1 12>; clock-names = "iis", "i2s_opclk0"; clocks = <&clocks CLK_I2S1>, <&clocks SCLK_AUDIO1>; pinctrl-names = "default"; @@ -274,8 +274,8 @@ reg = <0xe2a00000 0x1000>; interrupt-parent = <&vic2>; interrupts = <18>; - dma-names = "rx", "tx"; - dmas = <&pdma1 14>, <&pdma1 15>; + dma-names = "tx", "rx"; + dmas = <&pdma1 15>, <&pdma1 14>; clock-names = "iis", "i2s_opclk0"; clocks = <&clocks CLK_I2S2>, <&clocks SCLK_AUDIO2>; pinctrl-names = "default";
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit e521f087780d07731e8c950f2f34d08358c86bc9 ]
Currently all of the quirked systems use the same card and so the DMI quirk list doesn't contain driver data.
Add driver data to these quirks and then check the data was present or not. This will allow potentially setting quirks for systems with faulty firmware that claims to have a DMIC but doesn't really.
Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://lore.kernel.org/r/20220411134532.13538-2-mario.limonciello@amd.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/yc/acp6x-mach.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 9a767f47b89f..959b70e8baf2 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -45,108 +45,126 @@ static struct snd_soc_card acp6x_card = {
static const struct dmi_system_id yc_acp_quirk_table[] = { { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21D2"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21D3"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21D4"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21D5"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CF"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CG"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CQ"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CR"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21AW"), } }, { + .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"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CH"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CJ"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "21CK"), } }, { + .driver_data = &acp6x_card, .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), 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"), @@ -157,18 +175,21 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
static int acp6x_probe(struct platform_device *pdev) { + const struct dmi_system_id *dmi_id; struct acp6x_pdm *machine = NULL; struct snd_soc_card *card; int ret; - const struct dmi_system_id *dmi_id;
+ /* check for any DMI overrides */ dmi_id = dmi_first_match(yc_acp_quirk_table); - if (!dmi_id) + if (dmi_id) + platform_set_drvdata(pdev, dmi_id->driver_data); + + card = platform_get_drvdata(pdev); + if (!card) return -ENODEV; - card = &acp6x_card; acp6x_card.dev = &pdev->dev;
- platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) {
From: Konrad Dybcio konrad.dybcio@somainline.org
[ Upstream commit 049c46f31a726bf8d202ff1681661513447fac84 ]
The default memory map places cont_splash_mem at 3401000, which was overlooked.. Fix it!
Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220319174645.340379-9-konrad.dybcio@somainline.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index 8c1dc5155b71..c65618b95ce0 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -183,8 +183,8 @@ no-map; };
- cont_splash_mem: memory@3800000 { - reg = <0 0x03800000 0 0x2400000>; + cont_splash_mem: memory@3401000 { + reg = <0 0x03401000 0 0x2200000>; no-map; };
From: Konrad Dybcio konrad.dybcio@somainline.org
[ Upstream commit 1ae438d26b620979ed004d559c304d31c42173ae ]
MSM8994 actually features 24 DMA channels for each BLSP, fix it!
Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220319174645.340379-14-konrad.dybcio@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index c65618b95ce0..b1e595cb4b90 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -498,7 +498,7 @@ #dma-cells = <1>; qcom,ee = <0>; qcom,controlled-remotely; - num-channels = <18>; + num-channels = <24>; qcom,num-ees = <4>; };
@@ -634,7 +634,7 @@ #dma-cells = <1>; qcom,ee = <0>; qcom,controlled-remotely; - num-channels = <18>; + num-channels = <24>; qcom,num-ees = <4>; };
From: Brian Norris briannorris@chromium.org
[ Upstream commit 2fccf9e6050e0e3b8b4cd275d41daf7f7fa22804 ]
Otherwise we hit an unablanced enable-count when unbinding the DFI device:
[ 1279.659119] ------------[ cut here ]------------ [ 1279.659179] WARNING: CPU: 2 PID: 5638 at drivers/devfreq/devfreq-event.c:360 devfreq_event_remove_edev+0x84/0x8c ... [ 1279.659352] Hardware name: Google Kevin (DT) [ 1279.659363] pstate: 80400005 (Nzcv daif +PAN -UAO -TCO BTYPE=--) [ 1279.659371] pc : devfreq_event_remove_edev+0x84/0x8c [ 1279.659380] lr : devm_devfreq_event_release+0x1c/0x28 ... [ 1279.659571] Call trace: [ 1279.659582] devfreq_event_remove_edev+0x84/0x8c [ 1279.659590] devm_devfreq_event_release+0x1c/0x28 [ 1279.659602] release_nodes+0x1cc/0x244 [ 1279.659611] devres_release_all+0x44/0x60 [ 1279.659621] device_release_driver_internal+0x11c/0x1ac [ 1279.659629] device_driver_detach+0x20/0x2c [ 1279.659641] unbind_store+0x7c/0xb0 [ 1279.659650] drv_attr_store+0x2c/0x40 [ 1279.659663] sysfs_kf_write+0x44/0x58 [ 1279.659672] kernfs_fop_write_iter+0xf4/0x190 [ 1279.659684] vfs_write+0x2b0/0x2e4 [ 1279.659693] ksys_write+0x80/0xec [ 1279.659701] __arm64_sys_write+0x24/0x30 [ 1279.659714] el0_svc_common+0xf0/0x1d8 [ 1279.659724] do_el0_svc_compat+0x28/0x3c [ 1279.659738] el0_svc_compat+0x10/0x1c [ 1279.659746] el0_sync_compat_handler+0xa8/0xcc [ 1279.659758] el0_sync_compat+0x188/0x1c0 [ 1279.659768] ---[ end trace cec200e5094155b4 ]---
Signed-off-by: Brian Norris briannorris@chromium.org Signed-off-by: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/devfreq/rk3399_dmc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c index 293857ebfd75..538e8dc74f40 100644 --- a/drivers/devfreq/rk3399_dmc.c +++ b/drivers/devfreq/rk3399_dmc.c @@ -477,6 +477,8 @@ static int rk3399_dmcfreq_remove(struct platform_device *pdev) { struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
+ devfreq_event_disable_edev(dmcfreq->edev); + /* * Before remove the opp table we need to unregister the opp notifier. */
From: Gilad Ben-Yossef gilad@benyossef.com
[ Upstream commit a260436c98171cd825955a84a7f6e62bc8f4f00d ]
Use a fine grained specification of DMA mapping directions in certain cases, allowing both a more optimized operation as well as shushing out a harmless, though persky dma-debug warning.
Signed-off-by: Gilad Ben-Yossef gilad@benyossef.com Reported-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/ccree/cc_buffer_mgr.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c index 11e0278c8631..6140e4927322 100644 --- a/drivers/crypto/ccree/cc_buffer_mgr.c +++ b/drivers/crypto/ccree/cc_buffer_mgr.c @@ -356,12 +356,14 @@ void cc_unmap_cipher_request(struct device *dev, void *ctx, req_ctx->mlli_params.mlli_dma_addr); }
- dma_unmap_sg(dev, src, req_ctx->in_nents, DMA_BIDIRECTIONAL); - dev_dbg(dev, "Unmapped req->src=%pK\n", sg_virt(src)); - if (src != dst) { - dma_unmap_sg(dev, dst, req_ctx->out_nents, DMA_BIDIRECTIONAL); + dma_unmap_sg(dev, src, req_ctx->in_nents, DMA_TO_DEVICE); + dma_unmap_sg(dev, dst, req_ctx->out_nents, DMA_FROM_DEVICE); dev_dbg(dev, "Unmapped req->dst=%pK\n", sg_virt(dst)); + dev_dbg(dev, "Unmapped req->src=%pK\n", sg_virt(src)); + } else { + dma_unmap_sg(dev, src, req_ctx->in_nents, DMA_BIDIRECTIONAL); + dev_dbg(dev, "Unmapped req->src=%pK\n", sg_virt(src)); } }
@@ -377,6 +379,7 @@ int cc_map_cipher_request(struct cc_drvdata *drvdata, void *ctx, u32 dummy = 0; int rc = 0; u32 mapped_nents = 0; + int src_direction = (src != dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL);
req_ctx->dma_buf_type = CC_DMA_BUF_DLLI; mlli_params->curr_pool = NULL; @@ -399,7 +402,7 @@ int cc_map_cipher_request(struct cc_drvdata *drvdata, void *ctx, }
/* Map the src SGL */ - rc = cc_map_sg(dev, src, nbytes, DMA_BIDIRECTIONAL, &req_ctx->in_nents, + rc = cc_map_sg(dev, src, nbytes, src_direction, &req_ctx->in_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents); if (rc) goto cipher_exit; @@ -416,7 +419,7 @@ int cc_map_cipher_request(struct cc_drvdata *drvdata, void *ctx, } } else { /* Map the dst sg */ - rc = cc_map_sg(dev, dst, nbytes, DMA_BIDIRECTIONAL, + rc = cc_map_sg(dev, dst, nbytes, DMA_FROM_DEVICE, &req_ctx->out_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents); if (rc) @@ -456,6 +459,7 @@ void cc_unmap_aead_request(struct device *dev, struct aead_request *req) struct aead_req_ctx *areq_ctx = aead_request_ctx(req); unsigned int hw_iv_size = areq_ctx->hw_iv_size; struct cc_drvdata *drvdata = dev_get_drvdata(dev); + int src_direction = (req->src != req->dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL);
if (areq_ctx->mac_buf_dma_addr) { dma_unmap_single(dev, areq_ctx->mac_buf_dma_addr, @@ -514,13 +518,11 @@ void cc_unmap_aead_request(struct device *dev, struct aead_request *req) sg_virt(req->src), areq_ctx->src.nents, areq_ctx->assoc.nents, areq_ctx->assoclen, req->cryptlen);
- dma_unmap_sg(dev, req->src, areq_ctx->src.mapped_nents, - DMA_BIDIRECTIONAL); + dma_unmap_sg(dev, req->src, areq_ctx->src.mapped_nents, src_direction); if (req->src != req->dst) { dev_dbg(dev, "Unmapping dst sgl: req->dst=%pK\n", sg_virt(req->dst)); - dma_unmap_sg(dev, req->dst, areq_ctx->dst.mapped_nents, - DMA_BIDIRECTIONAL); + dma_unmap_sg(dev, req->dst, areq_ctx->dst.mapped_nents, DMA_FROM_DEVICE); } if (drvdata->coherent && areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT && @@ -843,7 +845,7 @@ static int cc_aead_chain_data(struct cc_drvdata *drvdata, else size_for_map -= authsize;
- rc = cc_map_sg(dev, req->dst, size_for_map, DMA_BIDIRECTIONAL, + rc = cc_map_sg(dev, req->dst, size_for_map, DMA_FROM_DEVICE, &areq_ctx->dst.mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, &dst_last_bytes, &dst_mapped_nents); @@ -1056,7 +1058,8 @@ int cc_map_aead_request(struct cc_drvdata *drvdata, struct aead_request *req) size_to_map += authsize; }
- rc = cc_map_sg(dev, req->src, size_to_map, DMA_BIDIRECTIONAL, + rc = cc_map_sg(dev, req->src, size_to_map, + (req->src != req->dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL), &areq_ctx->src.mapped_nents, (LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES + LLI_MAX_NUM_OF_DATA_ENTRIES),
From: Marco Chiappero marco.chiappero@intel.com
[ Upstream commit dd3d081b7ea6754913222ed0313fcf644edcc7e6 ]
PFVF Block Message requests for CRC use 0-based values to indicate amounts, which have to be remapped to 1-based values on the receiving side.
This patch fixes one debug print which was however using the wire value.
Signed-off-by: Marco Chiappero marco.chiappero@intel.com Reviewed-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c index 588352de1ef0..d17318d3f63a 100644 --- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c +++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c @@ -154,7 +154,7 @@ static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info, if (FIELD_GET(ADF_VF2PF_BLOCK_CRC_REQ_MASK, req.data)) { dev_dbg(&GET_DEV(vf_info->accel_dev), "BlockMsg of type %d for CRC over %d bytes received from VF%d\n", - blk_type, blk_byte, vf_info->vf_nr); + blk_type, blk_byte + 1, vf_info->vf_nr);
if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte, byte_max, &resp_data,
From: QintaoShen unSimple1993@163.com
[ Upstream commit ba56291e297d28aa6eb82c5c1964fae2d7594746 ]
The allocation funciton devm_kcalloc may fail and return a null pointer, which would cause a null-pointer dereference later. It might be better to check it and directly return -ENOMEM just like the usage of devm_kcalloc in previous code.
Signed-off-by: QintaoShen unSimple1993@163.com Signed-off-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/1648107843-29077-1-git-send-email-unSimple1993@163... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/ti/ti_sci_pm_domains.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c index 8afb3f45d263..a33ec7eaf23d 100644 --- a/drivers/soc/ti/ti_sci_pm_domains.c +++ b/drivers/soc/ti/ti_sci_pm_domains.c @@ -183,6 +183,8 @@ static int ti_sci_pm_domain_probe(struct platform_device *pdev) devm_kcalloc(dev, max_id + 1, sizeof(*pd_provider->data.domains), GFP_KERNEL); + if (!pd_provider->data.domains) + return -ENOMEM;
pd_provider->data.num_domains = max_id + 1; pd_provider->data.xlate = ti_sci_pd_xlate;
From: Zixuan Fu r33s3n6@gmail.com
[ Upstream commit 0d4837fdb796f99369cf7691d33de1b856bcaf1f ]
In our fault-injection testing, the variable "nblocks" in dbFree() can be zero when kmalloc_array() fails in dtSearch(). In this case, the variable "mp" in dbFree() would be NULL and then it is dereferenced in "write_metapage(mp)".
The failure log is listed as follows:
[ 13.824137] BUG: kernel NULL pointer dereference, address: 0000000000000020 ... [ 13.827416] RIP: 0010:dbFree+0x5f7/0x910 [jfs] [ 13.834341] Call Trace: [ 13.834540] <TASK> [ 13.834713] txFreeMap+0x7b4/0xb10 [jfs] [ 13.835038] txUpdateMap+0x311/0x650 [jfs] [ 13.835375] jfs_lazycommit+0x5f2/0xc70 [jfs] [ 13.835726] ? sched_dynamic_update+0x1b0/0x1b0 [ 13.836092] kthread+0x3c2/0x4a0 [ 13.836355] ? txLockFree+0x160/0x160 [jfs] [ 13.836763] ? kthread_unuse_mm+0x160/0x160 [ 13.837106] ret_from_fork+0x1f/0x30 [ 13.837402] </TASK> ...
This patch adds a NULL check of "mp" before "write_metapage(mp)" is called.
Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Zixuan Fu r33s3n6@gmail.com Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jfs/jfs_dmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index d8502f4989d9..e75f31b81d63 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -385,7 +385,8 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) }
/* write the last buffer. */ - write_metapage(mp); + if (mp) + write_metapage(mp);
IREAD_UNLOCK(ipbmap);
From: Joel Selvaraj jo@jsfamily.in
[ Upstream commit 1f1c494082a1f10d03ce4ee1485ee96d212e22ff ]
vddio is misspelled with a "0" instead of "o". Fix it.
Signed-off-by: Joel Selvaraj jo@jsfamily.in Reviewed-by: Caleb Connolly caleb@connolly.tech Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/BY5PR02MB7009901651E6A8D5ACB0425ED91F9@BY5PR02MB70... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts index 367389526b41..a97f5e89e1d0 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium.dts @@ -218,7 +218,7 @@ panel@0 { compatible = "tianma,fhd-video"; reg = <0>; - vddi0-supply = <&vreg_l14a_1p8>; + vddio-supply = <&vreg_l14a_1p8>; vddpos-supply = <&lab>; vddneg-supply = <&ibb>;
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 0f1f7a6661394fe4a53db254c346d6aa2dd64397 ]
For making easier to test, add the new quirk_flags bits 17 and 18 to enable and disable the generic implicit feedback mode. The bit 17 is equivalent with implicit_fb=1 option, applying the generic implicit feedback sync mode. OTOH, the bit 18 disables the implicit fb mode forcibly.
Link: https://lore.kernel.org/r/20220421064101.12456-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/sound/alsa-configuration.rst | 4 +++- sound/usb/implicit.c | 5 ++++- sound/usb/usbaudio.h | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst index 34888d4fc4a8..21ab5e6f7062 100644 --- a/Documentation/sound/alsa-configuration.rst +++ b/Documentation/sound/alsa-configuration.rst @@ -2246,7 +2246,7 @@ implicit_fb Apply the generic implicit feedback sync mode. When this is set and the playback stream sync mode is ASYNC, the driver tries to tie an adjacent ASYNC capture stream as the implicit feedback - source. + source. This is equivalent with quirk_flags bit 17. use_vmalloc Use vmalloc() for allocations of the PCM buffers (default: yes). For architectures with non-coherent memory like ARM or MIPS, the @@ -2288,6 +2288,8 @@ quirk_flags * bit 14: Ignore errors for mixer access * bit 15: Support generic DSD raw U32_BE format * bit 16: Set up the interface at first like UAC1 + * bit 17: Apply the generic implicit feedback sync mode + * bit 18: Don't apply implicit feedback sync mode
This module supports multiple devices, autoprobe and hotplugging.
diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c index 2d444ec74202..1fd087128538 100644 --- a/sound/usb/implicit.c +++ b/sound/usb/implicit.c @@ -350,7 +350,8 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip, }
/* Try the generic implicit fb if available */ - if (chip->generic_implicit_fb) + if (chip->generic_implicit_fb || + (chip->quirk_flags & QUIRK_FLAG_GENERIC_IMPLICIT_FB)) return add_generic_implicit_fb(chip, fmt, alts);
/* No quirk */ @@ -387,6 +388,8 @@ int snd_usb_parse_implicit_fb_quirk(struct snd_usb_audio *chip, struct audioformat *fmt, struct usb_host_interface *alts) { + if (chip->quirk_flags & QUIRK_FLAG_SKIP_IMPLICIT_FB) + return 0; if (fmt->endpoint & USB_DIR_IN) return audioformat_capture_quirk(chip, fmt, alts); else diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index b8359a0aa008..044cd7ab27cb 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -164,6 +164,10 @@ extern bool snd_usb_skip_validation; * Support generic DSD raw U32_BE format * QUIRK_FLAG_SET_IFACE_FIRST: * Set up the interface at first like UAC1 + * QUIRK_FLAG_GENERIC_IMPLICIT_FB + * Apply the generic implicit feedback sync mode (same as implicit_fb=1 option) + * QUIRK_FLAG_SKIP_IMPLICIT_FB + * Don't apply implicit feedback sync mode */
#define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0) @@ -183,5 +187,7 @@ extern bool snd_usb_skip_validation; #define QUIRK_FLAG_IGNORE_CTL_ERROR (1U << 14) #define QUIRK_FLAG_DSD_RAW (1U << 15) #define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16) +#define QUIRK_FLAG_GENERIC_IMPLICIT_FB (1U << 17) +#define QUIRK_FLAG_SKIP_IMPLICIT_FB (1U << 18)
#endif /* __USBAUDIO_H */
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 67d64069bc0867e52e73a1e255b17462005ca9b4 ]
Use the new quirk bits to manage the generic implicit fb quirk entries. This makes easier to compare with other devices.
Link: https://lore.kernel.org/r/20220421064101.12456-2-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/implicit.c | 5 ----- sound/usb/quirks.c | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c index 1fd087128538..e1bf1b5da423 100644 --- a/sound/usb/implicit.c +++ b/sound/usb/implicit.c @@ -45,11 +45,6 @@ struct snd_usb_implicit_fb_match {
/* Implicit feedback quirk table for playback */ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = { - /* Generic matching */ - IMPLICIT_FB_GENERIC_DEV(0x0499, 0x1509), /* Steinberg UR22 */ - IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2030), /* M-Audio Fast Track C400 */ - IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2031), /* M-Audio Fast Track C600 */ - /* Fixed EP */ /* FIXME: check the availability of generic matching */ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */ diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index fbbe59054c3f..e8468f9b007d 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1793,6 +1793,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x046d, 0x09a4, /* Logitech QuickCam E 3500 */ QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */ QUIRK_FLAG_GET_SAMPLE_RATE), DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */ @@ -1826,6 +1828,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_GET_SAMPLE_RATE), DEVICE_FLG(0x074d, 0x3553, /* Outlaw RR2150 (Micronas UAC3553B) */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x0763, 0x2030, /* M-Audio Fast Track C400 */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */ QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */
From: Janusz Krzysztofik jmkrzyszt@gmail.com
[ Upstream commit 338d5d476cde853dfd97378d20496baabc2ce3c0 ]
Since its introduction to the mainline kernel, omap1_uart_recalc() helper makes incorrect use of clk->enable_bit as a ready to use bitmap mask while it only provides the bit number. Fix it.
Signed-off-by: Janusz Krzysztofik jmkrzyszt@gmail.com Acked-by: Tony Lindgren tony@atomide.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-omap1/clock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 9d4a0ab50a46..d63d5eb8d8fd 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -41,7 +41,7 @@ static DEFINE_SPINLOCK(clockfw_lock); unsigned long omap1_uart_recalc(struct clk *clk) { unsigned int val = __raw_readl(clk->enable_reg); - return val & clk->enable_bit ? 48000000 : 12000000; + return val & 1 << clk->enable_bit ? 48000000 : 12000000; }
unsigned long omap1_sossi_recalc(struct clk *clk)
From: Hari Bathini hbathini@linux.ibm.com
[ Upstream commit b74196af372f7cb4902179009265fe63ac81824f ]
Dump capture would fail if capture kernel is not of the endianess as the production kernel, because the in-memory data structure (struct opal_fadump_mem_struct) shared across production kernel and capture kernel assumes the same endianess for both the kernels, which doesn't have to be true always. Fix it by having a well-defined endianess for struct opal_fadump_mem_struct.
Signed-off-by: Hari Bathini hbathini@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/161902744901.86147.14719228311655123526.stgit@hbat... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/opal-fadump.c | 94 +++++++++++--------- arch/powerpc/platforms/powernv/opal-fadump.h | 10 +-- 2 files changed, 57 insertions(+), 47 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c index c8ad057c7221..9d74d3950a52 100644 --- a/arch/powerpc/platforms/powernv/opal-fadump.c +++ b/arch/powerpc/platforms/powernv/opal-fadump.c @@ -60,7 +60,7 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) addr = be64_to_cpu(addr); pr_debug("Kernel metadata addr: %llx\n", addr); opal_fdm_active = (void *)addr; - if (opal_fdm_active->registered_regions == 0) + if (be16_to_cpu(opal_fdm_active->registered_regions) == 0) return;
ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_BOOT_MEM, &addr); @@ -95,17 +95,17 @@ static int opal_fadump_unregister(struct fw_dump *fadump_conf); static void opal_fadump_update_config(struct fw_dump *fadump_conf, const struct opal_fadump_mem_struct *fdm) { - pr_debug("Boot memory regions count: %d\n", fdm->region_cnt); + pr_debug("Boot memory regions count: %d\n", be16_to_cpu(fdm->region_cnt));
/* * The destination address of the first boot memory region is the * destination address of boot memory regions. */ - fadump_conf->boot_mem_dest_addr = fdm->rgn[0].dest; + fadump_conf->boot_mem_dest_addr = be64_to_cpu(fdm->rgn[0].dest); pr_debug("Destination address of boot memory regions: %#016llx\n", fadump_conf->boot_mem_dest_addr);
- fadump_conf->fadumphdr_addr = fdm->fadumphdr_addr; + fadump_conf->fadumphdr_addr = be64_to_cpu(fdm->fadumphdr_addr); }
/* @@ -126,9 +126,9 @@ static void __init opal_fadump_get_config(struct fw_dump *fadump_conf, fadump_conf->boot_memory_size = 0;
pr_debug("Boot memory regions:\n"); - for (i = 0; i < fdm->region_cnt; i++) { - base = fdm->rgn[i].src; - size = fdm->rgn[i].size; + for (i = 0; i < be16_to_cpu(fdm->region_cnt); i++) { + base = be64_to_cpu(fdm->rgn[i].src); + size = be64_to_cpu(fdm->rgn[i].size); pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size);
fadump_conf->boot_mem_addr[i] = base; @@ -143,7 +143,7 @@ static void __init opal_fadump_get_config(struct fw_dump *fadump_conf, * Start address of reserve dump area (permanent reservation) for * re-registering FADump after dump capture. */ - fadump_conf->reserve_dump_area_start = fdm->rgn[0].dest; + fadump_conf->reserve_dump_area_start = be64_to_cpu(fdm->rgn[0].dest);
/* * Rarely, but it can so happen that system crashes before all @@ -155,13 +155,14 @@ static void __init opal_fadump_get_config(struct fw_dump *fadump_conf, * Hope the memory that could not be preserved only has pages * that are usually filtered out while saving the vmcore. */ - if (fdm->region_cnt > fdm->registered_regions) { + if (be16_to_cpu(fdm->region_cnt) > be16_to_cpu(fdm->registered_regions)) { pr_warn("Not all memory regions were saved!!!\n"); pr_warn(" Unsaved memory regions:\n"); - i = fdm->registered_regions; - while (i < fdm->region_cnt) { + i = be16_to_cpu(fdm->registered_regions); + while (i < be16_to_cpu(fdm->region_cnt)) { pr_warn("\t[%03d] base: 0x%llx, size: 0x%llx\n", - i, fdm->rgn[i].src, fdm->rgn[i].size); + i, be64_to_cpu(fdm->rgn[i].src), + be64_to_cpu(fdm->rgn[i].size)); i++; }
@@ -170,7 +171,7 @@ static void __init opal_fadump_get_config(struct fw_dump *fadump_conf, }
fadump_conf->boot_mem_top = (fadump_conf->boot_memory_size + hole_size); - fadump_conf->boot_mem_regs_cnt = fdm->region_cnt; + fadump_conf->boot_mem_regs_cnt = be16_to_cpu(fdm->region_cnt); opal_fadump_update_config(fadump_conf, fdm); }
@@ -178,35 +179,38 @@ static void __init opal_fadump_get_config(struct fw_dump *fadump_conf, static void opal_fadump_init_metadata(struct opal_fadump_mem_struct *fdm) { fdm->version = OPAL_FADUMP_VERSION; - fdm->region_cnt = 0; - fdm->registered_regions = 0; - fdm->fadumphdr_addr = 0; + fdm->region_cnt = cpu_to_be16(0); + fdm->registered_regions = cpu_to_be16(0); + fdm->fadumphdr_addr = cpu_to_be64(0); }
static u64 opal_fadump_init_mem_struct(struct fw_dump *fadump_conf) { u64 addr = fadump_conf->reserve_dump_area_start; + u16 reg_cnt; int i;
opal_fdm = __va(fadump_conf->kernel_metadata); opal_fadump_init_metadata(opal_fdm);
/* Boot memory regions */ + reg_cnt = be16_to_cpu(opal_fdm->region_cnt); for (i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) { - opal_fdm->rgn[i].src = fadump_conf->boot_mem_addr[i]; - opal_fdm->rgn[i].dest = addr; - opal_fdm->rgn[i].size = fadump_conf->boot_mem_sz[i]; + opal_fdm->rgn[i].src = cpu_to_be64(fadump_conf->boot_mem_addr[i]); + opal_fdm->rgn[i].dest = cpu_to_be64(addr); + opal_fdm->rgn[i].size = cpu_to_be64(fadump_conf->boot_mem_sz[i]);
- opal_fdm->region_cnt++; + reg_cnt++; addr += fadump_conf->boot_mem_sz[i]; } + opal_fdm->region_cnt = cpu_to_be16(reg_cnt);
/* * Kernel metadata is passed to f/w and retrieved in capture kerenl. * So, use it to save fadump header address instead of calculating it. */ - opal_fdm->fadumphdr_addr = (opal_fdm->rgn[0].dest + - fadump_conf->boot_memory_size); + opal_fdm->fadumphdr_addr = cpu_to_be64(be64_to_cpu(opal_fdm->rgn[0].dest) + + fadump_conf->boot_memory_size);
opal_fadump_update_config(fadump_conf, opal_fdm);
@@ -269,18 +273,21 @@ static u64 opal_fadump_get_bootmem_min(void) static int opal_fadump_register(struct fw_dump *fadump_conf) { s64 rc = OPAL_PARAMETER; + u16 registered_regs; int i, err = -EIO;
- for (i = 0; i < opal_fdm->region_cnt; i++) { + registered_regs = be16_to_cpu(opal_fdm->registered_regions); + for (i = 0; i < be16_to_cpu(opal_fdm->region_cnt); i++) { rc = opal_mpipl_update(OPAL_MPIPL_ADD_RANGE, - opal_fdm->rgn[i].src, - opal_fdm->rgn[i].dest, - opal_fdm->rgn[i].size); + be64_to_cpu(opal_fdm->rgn[i].src), + be64_to_cpu(opal_fdm->rgn[i].dest), + be64_to_cpu(opal_fdm->rgn[i].size)); if (rc != OPAL_SUCCESS) break;
- opal_fdm->registered_regions++; + registered_regs++; } + opal_fdm->registered_regions = cpu_to_be16(registered_regs);
switch (rc) { case OPAL_SUCCESS: @@ -291,7 +298,8 @@ static int opal_fadump_register(struct fw_dump *fadump_conf) case OPAL_RESOURCE: /* If MAX regions limit in f/w is hit, warn and proceed. */ pr_warn("%d regions could not be registered for MPIPL as MAX limit is reached!\n", - (opal_fdm->region_cnt - opal_fdm->registered_regions)); + (be16_to_cpu(opal_fdm->region_cnt) - + be16_to_cpu(opal_fdm->registered_regions))); fadump_conf->dump_registered = 1; err = 0; break; @@ -312,7 +320,7 @@ static int opal_fadump_register(struct fw_dump *fadump_conf) * If some regions were registered before OPAL_MPIPL_ADD_RANGE * OPAL call failed, unregister all regions. */ - if ((err < 0) && (opal_fdm->registered_regions > 0)) + if ((err < 0) && (be16_to_cpu(opal_fdm->registered_regions) > 0)) opal_fadump_unregister(fadump_conf);
return err; @@ -328,7 +336,7 @@ static int opal_fadump_unregister(struct fw_dump *fadump_conf) return -EIO; }
- opal_fdm->registered_regions = 0; + opal_fdm->registered_regions = cpu_to_be16(0); fadump_conf->dump_registered = 0; return 0; } @@ -563,19 +571,20 @@ static void opal_fadump_region_show(struct fw_dump *fadump_conf, else fdm_ptr = opal_fdm;
- for (i = 0; i < fdm_ptr->region_cnt; i++) { + for (i = 0; i < be16_to_cpu(fdm_ptr->region_cnt); i++) { /* * Only regions that are registered for MPIPL * would have dump data. */ if ((fadump_conf->dump_active) && - (i < fdm_ptr->registered_regions)) - dumped_bytes = fdm_ptr->rgn[i].size; + (i < be16_to_cpu(fdm_ptr->registered_regions))) + dumped_bytes = be64_to_cpu(fdm_ptr->rgn[i].size);
seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ", - fdm_ptr->rgn[i].src, fdm_ptr->rgn[i].dest); + be64_to_cpu(fdm_ptr->rgn[i].src), + be64_to_cpu(fdm_ptr->rgn[i].dest)); seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n", - fdm_ptr->rgn[i].size, dumped_bytes); + be64_to_cpu(fdm_ptr->rgn[i].size), dumped_bytes); }
/* Dump is active. Show reserved area start address. */ @@ -624,6 +633,7 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) { const __be32 *prop; unsigned long dn; + __be64 be_addr; u64 addr = 0; int i, len; s64 ret; @@ -680,13 +690,13 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) if (!prop) return;
- ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_KERNEL, &addr); - if ((ret != OPAL_SUCCESS) || !addr) { + ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_KERNEL, &be_addr); + if ((ret != OPAL_SUCCESS) || !be_addr) { pr_err("Failed to get Kernel metadata (%lld)\n", ret); return; }
- addr = be64_to_cpu(addr); + addr = be64_to_cpu(be_addr); pr_debug("Kernel metadata addr: %llx\n", addr);
opal_fdm_active = __va(addr); @@ -697,14 +707,14 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) }
/* Kernel regions not registered with f/w for MPIPL */ - if (opal_fdm_active->registered_regions == 0) { + if (be16_to_cpu(opal_fdm_active->registered_regions) == 0) { opal_fdm_active = NULL; return; }
- ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_CPU, &addr); - if (addr) { - addr = be64_to_cpu(addr); + ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_CPU, &be_addr); + if (be_addr) { + addr = be64_to_cpu(be_addr); pr_debug("CPU metadata addr: %llx\n", addr); opal_cpu_metadata = __va(addr); } diff --git a/arch/powerpc/platforms/powernv/opal-fadump.h b/arch/powerpc/platforms/powernv/opal-fadump.h index f1e9ecf548c5..3f715efb0aa6 100644 --- a/arch/powerpc/platforms/powernv/opal-fadump.h +++ b/arch/powerpc/platforms/powernv/opal-fadump.h @@ -31,14 +31,14 @@ * OPAL FADump kernel metadata * * The address of this structure will be registered with f/w for retrieving - * and processing during crash dump. + * in the capture kernel to process the crash dump. */ struct opal_fadump_mem_struct { u8 version; u8 reserved[3]; - u16 region_cnt; /* number of regions */ - u16 registered_regions; /* Regions registered for MPIPL */ - u64 fadumphdr_addr; + __be16 region_cnt; /* number of regions */ + __be16 registered_regions; /* Regions registered for MPIPL */ + __be64 fadumphdr_addr; struct opal_mpipl_region rgn[FADUMP_MAX_MEM_REGS]; } __packed;
@@ -135,7 +135,7 @@ static inline void opal_fadump_read_regs(char *bufp, unsigned int regs_cnt, for (i = 0; i < regs_cnt; i++, bufp += reg_entry_size) { reg_entry = (struct hdat_fadump_reg_entry *)bufp; val = (cpu_endian ? be64_to_cpu(reg_entry->reg_val) : - reg_entry->reg_val); + (u64)(reg_entry->reg_val)); opal_fadump_set_regval_regnum(regs, be32_to_cpu(reg_entry->reg_type), be32_to_cpu(reg_entry->reg_num),
From: OGAWA Hirofumi hirofumi@mail.parknet.co.jp
[ Upstream commit 183c3237c928109d2008c0456dff508baf692b20 ]
fat*_ent_bread() can be the cause of too many report on I/O error path. So use fat_msg_ratelimit() instead.
Link: https://lkml.kernel.org/r/87bkxogfeq.fsf@mail.parknet.co.jp Signed-off-by: OGAWA Hirofumi hirofumi@mail.parknet.co.jp Reported-by: qianfan qianfanguijin@163.com Tested-by: qianfan qianfanguijin@163.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fat/fatent.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c index 978ac6751aeb..1db348f8f887 100644 --- a/fs/fat/fatent.c +++ b/fs/fat/fatent.c @@ -94,7 +94,8 @@ static int fat12_ent_bread(struct super_block *sb, struct fat_entry *fatent, err_brelse: brelse(bhs[0]); err: - fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", (llu)blocknr); + fat_msg_ratelimit(sb, KERN_ERR, "FAT read failed (blocknr %llu)", + (llu)blocknr); return -EIO; }
@@ -107,8 +108,8 @@ static int fat_ent_bread(struct super_block *sb, struct fat_entry *fatent, fatent->fat_inode = MSDOS_SB(sb)->fat_inode; fatent->bhs[0] = sb_bread(sb, blocknr); if (!fatent->bhs[0]) { - fat_msg(sb, KERN_ERR, "FAT read failed (blocknr %llu)", - (llu)blocknr); + fat_msg_ratelimit(sb, KERN_ERR, "FAT read failed (blocknr %llu)", + (llu)blocknr); return -EIO; } fatent->nr_bhs = 1;
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 2f661477c2bb8068194dbba9738d05219f111c6e ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref. And use devm_platform_get_and_ioremap_resource() to simplify code.
Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20220429082637.1308182-2-yangyingliang@huawei.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/pinctrl-rzn1.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzn1.c b/drivers/pinctrl/renesas/pinctrl-rzn1.c index ef5fb25b6016..849d091205d4 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzn1.c +++ b/drivers/pinctrl/renesas/pinctrl-rzn1.c @@ -865,17 +865,15 @@ static int rzn1_pinctrl_probe(struct platform_device *pdev) ipctl->mdio_func[0] = -1; ipctl->mdio_func[1] = -1;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ipctl->lev1_protect_phys = (u32)res->start + 0x400; - ipctl->lev1 = devm_ioremap_resource(&pdev->dev, res); + ipctl->lev1 = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(ipctl->lev1)) return PTR_ERR(ipctl->lev1); + ipctl->lev1_protect_phys = (u32)res->start + 0x400;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - ipctl->lev2_protect_phys = (u32)res->start + 0x400; - ipctl->lev2 = devm_ioremap_resource(&pdev->dev, res); + ipctl->lev2 = devm_platform_get_and_ioremap_resource(pdev, 1, &res); if (IS_ERR(ipctl->lev2)) return PTR_ERR(ipctl->lev2); + ipctl->lev2_protect_phys = (u32)res->start + 0x400;
ipctl->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ipctl->clk))
From: Peng Wu wupeng58@huawei.com
[ Upstream commit 23b44f9c649bbef10b45fa33080cd8b4166800ae ]
The device_node pointer is returned by of_find_compatible_node with refcount incremented. We should use of_node_put() to avoid the refcount leak.
Signed-off-by: Peng Wu wupeng58@huawei.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20220428230356.69418-1-linus.walleij@linaro.org' Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-vexpress/dcscb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c index a0554d7d04f7..e1adc098f89a 100644 --- a/arch/arm/mach-vexpress/dcscb.c +++ b/arch/arm/mach-vexpress/dcscb.c @@ -144,6 +144,7 @@ static int __init dcscb_init(void) if (!node) return -ENODEV; dcscb_base = of_iomap(node, 0); + of_node_put(node); if (!dcscb_base) return -EADDRNOTAVAIL; cfg = readl_relaxed(dcscb_base + DCS_CFG_R);
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit f038e8186fbc5723d7d38c6fa1d342945107347e ]
The Samsung s524ad0xd1 EEPROM should use atmel,24c128 fallback, according to the AT24 EEPROM bindings.
Reported-by: Rob Herring robh@kernel.org Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220426183443.243113-1-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/exynos5250-smdk5250.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index 21fbbf3d8684..71293749ac48 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -129,7 +129,7 @@ samsung,i2c-max-bus-freq = <20000>;
eeprom@50 { - compatible = "samsung,s524ad0xd1"; + compatible = "samsung,s524ad0xd1", "atmel,24c128"; reg = <0x50>; };
@@ -289,7 +289,7 @@ samsung,i2c-max-bus-freq = <20000>;
eeprom@51 { - compatible = "samsung,s524ad0xd1"; + compatible = "samsung,s524ad0xd1", "atmel,24c128"; reg = <0x51>; };
From: Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com
[ Upstream commit 497b272759986af1aa5a25b5e903d082c67bd8f6 ]
WLAN rail was leaking power during RBSC/sleep even after turning BT off. Change active and sleep pinctrl configurations to handle same.
Signed-off-by: Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1650556567-4995-2-git-send-email-quic_vnivarth@qui... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280-idp.dtsi | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi index ecbf2b89d896..5ab3696af354 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi @@ -400,10 +400,13 @@
&qup_uart7_cts { /* - * Configure a pull-down on CTS to match the pull of - * the Bluetooth module. + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. */ - bias-pull-down; + bias-bus-hold; };
&qup_uart7_rts { @@ -495,10 +498,13 @@ pins = "gpio28"; function = "gpio"; /* - * Configure a pull-down on CTS to match the pull of - * the Bluetooth module. + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. */ - bias-pull-down; + bias-bus-hold; };
qup_uart7_sleep_rts: qup-uart7-sleep-rts {
From: Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com
[ Upstream commit 3d0e375bae55c2dfa6dd0762f45ad71f0b192f71 ]
WLAN rail was leaking power during RBSC/sleep even after turning BT off. Change active and sleep pinctrl configurations to handle same.
Signed-off-by: Vijaya Krishna Nivarthi quic_vnivarth@quicinc.com Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1650556567-4995-3-git-send-email-quic_vnivarth@qui... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi index b833ba1e8f4a..98b5cd70bca5 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi @@ -398,8 +398,14 @@ mos_bt_uart: &uart7 {
/* For mos_bt_uart */ &qup_uart7_cts { - /* Configure a pull-down on CTS to match the pull of the Bluetooth module. */ - bias-pull-down; + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; };
/* For mos_bt_uart */ @@ -490,10 +496,13 @@ mos_bt_uart: &uart7 { pins = "gpio28"; function = "gpio"; /* - * Configure a pull-down on CTS to match the pull of - * the Bluetooth module. + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. */ - bias-pull-down; + bias-bus-hold; };
/* For mos_bt_uart */
From: Peng Wu wupeng58@huawei.com
[ Upstream commit 9bc72e47d4630d58a840a66a869c56b29554cfe4 ]
of_find_compatible_node will increment the refcount of the returned device_node. Calling of_node_put() to avoid the refcount leak
Signed-off-by: Peng Wu wupeng58@huawei.com Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-hisi/platsmp.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c index a56cc64deeb8..9ce93e0b6cdc 100644 --- a/arch/arm/mach-hisi/platsmp.c +++ b/arch/arm/mach-hisi/platsmp.c @@ -67,14 +67,17 @@ static void __init hi3xxx_smp_prepare_cpus(unsigned int max_cpus) } ctrl_base = of_iomap(np, 0); if (!ctrl_base) { + of_node_put(np); pr_err("failed to map address\n"); return; } if (of_property_read_u32(np, "smp-offset", &offset) < 0) { + of_node_put(np); pr_err("failed to find smp-offset property\n"); return; } ctrl_base += offset; + of_node_put(np); } }
@@ -160,6 +163,7 @@ static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle) if (WARN_ON(!node)) return -1; ctrl_base = of_iomap(node, 0); + of_node_put(node);
/* set the secondary core boot from DDR */ remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL);
From: Viresh Kumar viresh.kumar@linaro.org
[ Upstream commit f55ae08c89873e140c7cac2a7fa161d31a0d60cf ]
For some platforms, the frequency returned by hardware may be slightly different from what is provided in the frequency table. For example, hardware may return 499 MHz instead of 500 MHz. In such cases it is better to avoid getting into unnecessary frequency updates, as we may end up switching policy->cur between the two and sending unnecessary pre/post update notifications, etc.
This patch has chosen allows the hardware frequency and table frequency to deviate by 1 MHz for now, we may want to increase it a bit later on if someone still complains.
Reported-by: Rex-BC Chen rex-bc.chen@mediatek.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Tested-by: Jia-wei Chang jia-wei.chang@mediatek.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/cpufreq.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 80f535cc8a75..fbaa8e6c7d23 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -28,6 +28,7 @@ #include <linux/suspend.h> #include <linux/syscore_ops.h> #include <linux/tick.h> +#include <linux/units.h> #include <trace/events/power.h>
static LIST_HEAD(cpufreq_policy_list); @@ -1707,6 +1708,16 @@ static unsigned int cpufreq_verify_current_freq(struct cpufreq_policy *policy, b return new_freq;
if (policy->cur != new_freq) { + /* + * For some platforms, the frequency returned by hardware may be + * slightly different from what is provided in the frequency + * table, for example hardware may return 499 MHz instead of 500 + * MHz. In such cases it is better to avoid getting into + * unnecessary frequency updates. + */ + if (abs(policy->cur - new_freq) < HZ_PER_MHZ) + return policy->cur; + cpufreq_out_of_sync(policy, new_freq); if (update) schedule_work(&policy->update);
From: Conor Dooley conor.dooley@microchip.com
[ Upstream commit 30097efa334a706f9021b9aee6efcddcfa44a78a ]
Two of the chained IRQ handlers miss their chained_irq_enter()/chained_irq_exit() calls, so add them in to avoid potentially lost interrupts.
Reported by: Bjorn Helgaas bhelgaas@google.com Link: https://lore.kernel.org/linux-pci/87h76b8nxc.wl-maz@kernel.org Link: https://lore.kernel.org/r/20220511095504.2273799-1-conor.dooley@microchip.co... Signed-off-by: Conor Dooley conor.dooley@microchip.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-microchip-host.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c index 29d8e81e4181..8175abed0f05 100644 --- a/drivers/pci/controller/pcie-microchip-host.c +++ b/drivers/pci/controller/pcie-microchip-host.c @@ -406,6 +406,7 @@ static void mc_pcie_enable_msi(struct mc_pcie *port, void __iomem *base) static void mc_handle_msi(struct irq_desc *desc) { struct mc_pcie *port = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); struct device *dev = port->dev; struct mc_msi *msi = &port->msi; void __iomem *bridge_base_addr = @@ -414,6 +415,8 @@ static void mc_handle_msi(struct irq_desc *desc) u32 bit; int ret;
+ chained_irq_enter(chip, desc); + status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL); if (status & PM_MSI_INT_MSI_MASK) { status = readl_relaxed(bridge_base_addr + ISTATUS_MSI); @@ -424,6 +427,8 @@ static void mc_handle_msi(struct irq_desc *desc) bit); } } + + chained_irq_exit(chip, desc); }
static void mc_msi_bottom_irq_ack(struct irq_data *data) @@ -563,6 +568,7 @@ static int mc_allocate_msi_domains(struct mc_pcie *port) static void mc_handle_intx(struct irq_desc *desc) { struct mc_pcie *port = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); struct device *dev = port->dev; void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; @@ -570,6 +576,8 @@ static void mc_handle_intx(struct irq_desc *desc) u32 bit; int ret;
+ chained_irq_enter(chip, desc); + status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL); if (status & PM_MSI_INT_INTX_MASK) { status &= PM_MSI_INT_INTX_MASK; @@ -581,6 +589,8 @@ static void mc_handle_intx(struct irq_desc *desc) bit); } } + + chained_irq_exit(chip, desc); }
static void mc_ack_intx_irq(struct irq_data *data)
From: Laurent Dufour ldufour@linux.ibm.com
[ Upstream commit b6b1c3ce06ca438eb24e0f45bf0e63ecad0369f5 ]
RTAS runs in real mode (MSR[DR] and MSR[IR] unset) and in 32-bit big endian mode (MSR[SF,LE] unset).
The change in MSR is done in enter_rtas() in a relatively complex way, since the MSR value could be hardcoded.
Furthermore, a panic has been reported when hitting the watchdog interrupt while running in RTAS, this leads to the following stack trace:
watchdog: CPU 24 Hard LOCKUP watchdog: CPU 24 TB:997512652051031, last heartbeat TB:997504470175378 (15980ms ago) ... Supported: No, Unreleased kernel CPU: 24 PID: 87504 Comm: drmgr Kdump: loaded Tainted: G E X 5.14.21-150400.71.1.bz196362_2-default #1 SLE15-SP4 (unreleased) 0d821077ef4faa8dfaf370efb5fdca1fa35f4e2c NIP: 000000001fb41050 LR: 000000001fb4104c CTR: 0000000000000000 REGS: c00000000fc33d60 TRAP: 0100 Tainted: G E X (5.14.21-150400.71.1.bz196362_2-default) MSR: 8000000002981000 <SF,VEC,VSX,ME> CR: 48800002 XER: 20040020 CFAR: 000000000000011c IRQMASK: 1 GPR00: 0000000000000003 ffffffffffffffff 0000000000000001 00000000000050dc GPR04: 000000001ffb6100 0000000000000020 0000000000000001 000000001fb09010 GPR08: 0000000020000000 0000000000000000 0000000000000000 0000000000000000 GPR12: 80040000072a40a8 c00000000ff8b680 0000000000000007 0000000000000034 GPR16: 000000001fbf6e94 000000001fbf6d84 000000001fbd1db0 000000001fb3f008 GPR20: 000000001fb41018 ffffffffffffffff 000000000000017f fffffffffffff68f GPR24: 000000001fb18fe8 000000001fb3e000 000000001fb1adc0 000000001fb1cf40 GPR28: 000000001fb26000 000000001fb460f0 000000001fb17f18 000000001fb17000 NIP [000000001fb41050] 0x1fb41050 LR [000000001fb4104c] 0x1fb4104c Call Trace: Instruction dump: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX Oops: Unrecoverable System Reset, sig: 6 [#1] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries ... Supported: No, Unreleased kernel CPU: 24 PID: 87504 Comm: drmgr Kdump: loaded Tainted: G E X 5.14.21-150400.71.1.bz196362_2-default #1 SLE15-SP4 (unreleased) 0d821077ef4faa8dfaf370efb5fdca1fa35f4e2c NIP: 000000001fb41050 LR: 000000001fb4104c CTR: 0000000000000000 REGS: c00000000fc33d60 TRAP: 0100 Tainted: G E X (5.14.21-150400.71.1.bz196362_2-default) MSR: 8000000002981000 <SF,VEC,VSX,ME> CR: 48800002 XER: 20040020 CFAR: 000000000000011c IRQMASK: 1 GPR00: 0000000000000003 ffffffffffffffff 0000000000000001 00000000000050dc GPR04: 000000001ffb6100 0000000000000020 0000000000000001 000000001fb09010 GPR08: 0000000020000000 0000000000000000 0000000000000000 0000000000000000 GPR12: 80040000072a40a8 c00000000ff8b680 0000000000000007 0000000000000034 GPR16: 000000001fbf6e94 000000001fbf6d84 000000001fbd1db0 000000001fb3f008 GPR20: 000000001fb41018 ffffffffffffffff 000000000000017f fffffffffffff68f GPR24: 000000001fb18fe8 000000001fb3e000 000000001fb1adc0 000000001fb1cf40 GPR28: 000000001fb26000 000000001fb460f0 000000001fb17f18 000000001fb17000 NIP [000000001fb41050] 0x1fb41050 LR [000000001fb4104c] 0x1fb4104c Call Trace: Instruction dump: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ---[ end trace 3ddec07f638c34a2 ]---
This happens because MSR[RI] is unset when entering RTAS but there is no valid reason to not set it here.
RTAS is expected to be called with MSR[RI] as specified in PAPR+ section "7.2.1 Machine State":
R1–7.2.1–9. If called with MSR[RI] equal to 1, then RTAS must protect its own critical regions from recursion by setting the MSR[RI] bit to 0 when in the critical regions.
Fixing this by reviewing the way MSR is compute before calling RTAS. Now a hardcoded value meaning real mode, 32 bits big endian mode and Recoverable Interrupt is loaded. In the case MSR[S] is set, it will remain set while entering RTAS as only urfid can unset it (thanks Fabiano).
In addition a check is added in do_enter_rtas() to detect calls made with MSR[RI] unset, as we are forcing it on later.
This patch has been tested on the following machines: Power KVM Guest P8 S822L (host Ubuntu kernel 5.11.0-49-generic) PowerVM LPAR P8 9119-MME (FW860.A1) p9 9008-22L (FW950.00) P10 9080-HEX (FW1010.00)
Suggested-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Laurent Dufour ldufour@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220504101244.12107-1-ldufour@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/entry_64.S | 24 ++++++++++++------------ arch/powerpc/kernel/rtas.c | 9 +++++++++ 2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 9581906b5ee9..da18f83ef883 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -330,22 +330,22 @@ _GLOBAL(enter_rtas) clrldi r4,r4,2 /* convert to realmode address */ mtlr r4
- li r0,0 - ori r0,r0,MSR_EE|MSR_SE|MSR_BE|MSR_RI - andc r0,r6,r0 - - li r9,1 - rldicr r9,r9,MSR_SF_LG,(63-MSR_SF_LG) - ori r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI|MSR_LE - andc r6,r0,r9 - __enter_rtas: - sync /* disable interrupts so SRR0/1 */ - mtmsrd r0 /* don't get trashed */ - LOAD_REG_ADDR(r4, rtas) ld r5,RTASENTRY(r4) /* get the rtas->entry value */ ld r4,RTASBASE(r4) /* get the rtas->base value */ + + /* + * RTAS runs in 32-bit big endian real mode, but leave MSR[RI] on as we + * may hit NMI (SRESET or MCE) while in RTAS. RTAS should disable RI in + * its critical regions (as specified in PAPR+ section 7.2.1). MSR[S] + * is not impacted by RFI_TO_KERNEL (only urfid can unset it). So if + * MSR[S] is set, it will remain when entering RTAS. + */ + LOAD_REG_IMMEDIATE(r6, MSR_ME | MSR_RI) + + li r0,0 + mtmsrd r0,1 /* disable RI before using SRR0/1 */ mtspr SPRN_SRR0,r5 mtspr SPRN_SRR1,r6 diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 1f42aabbbab3..6bc89d9ccf63 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -49,6 +49,15 @@ void enter_rtas(unsigned long);
static inline void do_enter_rtas(unsigned long args) { + unsigned long msr; + + /* + * Make sure MSR[RI] is currently enabled as it will be forced later + * in enter_rtas. + */ + msr = mfmsr(); + BUG_ON(!(msr & MSR_RI)); + enter_rtas(args);
srr_regs_clobbered(); /* rtas uses SRRs, invalidate */
From: Yicong Yang yangyicong@hisilicon.com
[ Upstream commit a91ee0e9fca9d7501286cfbced9b30a33e52740a ]
The sysfs sriov_numvfs_store() path acquires the device lock before the config space access lock:
sriov_numvfs_store device_lock # A (1) acquire device lock sriov_configure vfio_pci_sriov_configure # (for example) vfio_pci_core_sriov_configure pci_disable_sriov sriov_disable pci_cfg_access_lock pci_wait_cfg # B (4) wait for dev->block_cfg_access == 0
Previously, pci_dev_lock() acquired the config space access lock before the device lock:
pci_dev_lock pci_cfg_access_lock dev->block_cfg_access = 1 # B (2) set dev->block_cfg_access = 1 device_lock # A (3) wait for device lock
Any path that uses pci_dev_lock(), e.g., pci_reset_function(), may deadlock with sriov_numvfs_store() if the operations occur in the sequence (1) (2) (3) (4).
Avoid the deadlock by reversing the order in pci_dev_lock() so it acquires the device lock before the config space access lock, the same as the sriov_numvfs_store() path.
[bhelgaas: combined and adapted commit log from Jay Zhou's independent subsequent posting: https://lore.kernel.org/r/20220404062539.1710-1-jianjay.zhou@huawei.com] Link: https://lore.kernel.org/linux-pci/1583489997-17156-1-git-send-email-yangyico... Also-posted-by: Jay Zhou jianjay.zhou@huawei.com Signed-off-by: Yicong Yang yangyicong@hisilicon.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d25122fbe98a..1af69e298ac3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -5113,19 +5113,19 @@ static int pci_reset_bus_function(struct pci_dev *dev, bool probe)
void pci_dev_lock(struct pci_dev *dev) { - pci_cfg_access_lock(dev); /* block PM suspend, driver probe, etc. */ device_lock(&dev->dev); + pci_cfg_access_lock(dev); } EXPORT_SYMBOL_GPL(pci_dev_lock);
/* Return 1 on successful lock, 0 on contention */ int pci_dev_trylock(struct pci_dev *dev) { - if (pci_cfg_access_trylock(dev)) { - if (device_trylock(&dev->dev)) + if (device_trylock(&dev->dev)) { + if (pci_cfg_access_trylock(dev)) return 1; - pci_cfg_access_unlock(dev); + device_unlock(&dev->dev); }
return 0; @@ -5134,8 +5134,8 @@ EXPORT_SYMBOL_GPL(pci_dev_trylock);
void pci_dev_unlock(struct pci_dev *dev) { - device_unlock(&dev->dev); pci_cfg_access_unlock(dev); + device_unlock(&dev->dev); } EXPORT_SYMBOL_GPL(pci_dev_unlock);
From: Parshuram Thombare pthombar@cadence.com
[ Upstream commit 95b00f68209e2bc9f2ee9126afcebab451e0e9d8 ]
Clear FLR (Function Level Reset) from device capabilities registers for all physical functions.
During FLR, the Margining Lane Status and Margining Lane Control registers should not be reset, as per PCIe specification. However, the controller incorrectly resets these registers upon FLR. This causes PCISIG compliance FLR test to fail. Hence preventing all functions from advertising FLR support if flag quirk_disable_flr is set.
Link: https://lore.kernel.org/r/1635165075-89864-1-git-send-email-pthombar@cadence... Signed-off-by: Parshuram Thombare pthombar@cadence.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/cadence/pci-j721e.c | 3 +++ .../pci/controller/cadence/pcie-cadence-ep.c | 18 +++++++++++++++++- drivers/pci/controller/cadence/pcie-cadence.h | 3 +++ 3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 768d33f9ebc8..a82f845cc4b5 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -69,6 +69,7 @@ struct j721e_pcie_data { enum j721e_pcie_mode mode; unsigned int quirk_retrain_flag:1; unsigned int quirk_detect_quiet_flag:1; + unsigned int quirk_disable_flr:1; u32 linkdown_irq_regfield; unsigned int byte_access_allowed:1; }; @@ -307,6 +308,7 @@ static const struct j721e_pcie_data j7200_pcie_rc_data = { static const struct j721e_pcie_data j7200_pcie_ep_data = { .mode = PCI_MODE_EP, .quirk_detect_quiet_flag = true, + .quirk_disable_flr = true, };
static const struct j721e_pcie_data am64_pcie_rc_data = { @@ -405,6 +407,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) return -ENOMEM;
ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; + ep->quirk_disable_flr = data->quirk_disable_flr;
cdns_pcie = &ep->pcie; cdns_pcie->dev = dev; diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 88e05b9c2e5b..4b1c4bc4e003 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -565,7 +565,8 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) struct cdns_pcie_ep *ep = epc_get_drvdata(epc); struct cdns_pcie *pcie = &ep->pcie; struct device *dev = pcie->dev; - int ret; + int max_epfs = sizeof(epc->function_num_map) * 8; + int ret, value, epf;
/* * BIT(0) is hardwired to 1, hence function 0 is always enabled @@ -573,6 +574,21 @@ static int cdns_pcie_ep_start(struct pci_epc *epc) */ cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, epc->function_num_map);
+ if (ep->quirk_disable_flr) { + for (epf = 0; epf < max_epfs; epf++) { + if (!(epc->function_num_map & BIT(epf))) + continue; + + value = cdns_pcie_ep_fn_readl(pcie, epf, + CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET + + PCI_EXP_DEVCAP); + value &= ~PCI_EXP_DEVCAP_FLR; + cdns_pcie_ep_fn_writel(pcie, epf, + CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET + + PCI_EXP_DEVCAP, value); + } + } + ret = cdns_pcie_start_link(pcie); if (ret) { dev_err(dev, "Failed to start link\n"); diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h index c8a27b6290ce..d9c785365da3 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.h +++ b/drivers/pci/controller/cadence/pcie-cadence.h @@ -123,6 +123,7 @@
#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90 #define CDNS_PCIE_EP_FUNC_MSIX_CAP_OFFSET 0xb0 +#define CDNS_PCIE_EP_FUNC_DEV_CAP_OFFSET 0xc0 #define CDNS_PCIE_EP_FUNC_SRIOV_CAP_OFFSET 0x200
/* @@ -357,6 +358,7 @@ struct cdns_pcie_epf { * minimize time between read and write * @epf: Structure to hold info about endpoint function * @quirk_detect_quiet_flag: LTSSM Detect Quiet min delay set as quirk + * @quirk_disable_flr: Disable FLR (Function Level Reset) quirk flag */ struct cdns_pcie_ep { struct cdns_pcie pcie; @@ -372,6 +374,7 @@ struct cdns_pcie_ep { spinlock_t lock; struct cdns_pcie_epf *epf; unsigned int quirk_detect_quiet_flag:1; + unsigned int quirk_disable_flr:1; };
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit 2852ebfa10afdcefff35ec72c8da97141df9845c ]
The L1 should not be able to adjust LPES mode for the L2. Setting LPES if the L0 needs it clear would cause external interrupts to be sent to L2 and missed by the L0.
Clearing LPES when it may be set, as typically happens with XIVE enabled could cause a performance issue despite having no native XIVE support in the guest, because it will cause mediated interrupts for the L2 to be taken in HV mode, which then have to be injected.
Signed-off-by: Nicholas Piggin npiggin@gmail.com Reviewed-by: Fabiano Rosas farosas@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220303053315.1056880-7-npiggin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_hv.c | 4 ++++ arch/powerpc/kvm/book3s_hv_nested.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 6fa518f6501d..43af871383c2 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -5283,6 +5283,10 @@ static int kvmppc_core_init_vm_hv(struct kvm *kvm) kvm->arch.host_lpcr = lpcr = mfspr(SPRN_LPCR); lpcr &= LPCR_PECE | LPCR_LPES; } else { + /* + * The L2 LPES mode will be set by the L0 according to whether + * or not it needs to take external interrupts in HV mode. + */ lpcr = 0; } lpcr |= (4UL << LPCR_DPFD_SH) | LPCR_HDICE | diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index c943a051c6e7..265bb30a0af2 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -261,8 +261,7 @@ static void load_l2_hv_regs(struct kvm_vcpu *vcpu, /* * Don't let L1 change LPCR bits for the L2 except these: */ - mask = LPCR_DPFD | LPCR_ILE | LPCR_TC | LPCR_AIL | LPCR_LD | - LPCR_LPES | LPCR_MER; + mask = LPCR_DPFD | LPCR_ILE | LPCR_TC | LPCR_AIL | LPCR_LD | LPCR_MER;
/* * Additional filtering is required depending on hardware
From: Matthew Wilcox (Oracle) willy@infradead.org
[ Upstream commit f9c668d281aa20e38c9bda3b7b0adeb8891aa15e ]
Due to a typo, the final argument to alloc_page_vma() didn't refer to a real variable. This only affected CONFIG_NUMA, which was marked BROKEN in 2006 and removed from alpha in 2021. Found due to a refactoring patch.
Link: https://lkml.kernel.org/r/20220504182857.4013401-4-willy@infradead.org Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Reported-by: kernel test robot lkp@intel.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/alpha/include/asm/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/alpha/include/asm/page.h b/arch/alpha/include/asm/page.h index 18f48a6f2ff6..8f3f5eecba28 100644 --- a/arch/alpha/include/asm/page.h +++ b/arch/alpha/include/asm/page.h @@ -18,7 +18,7 @@ extern void clear_page(void *page); #define clear_user_page(page, vaddr, pg) clear_page(page)
#define alloc_zeroed_user_highpage_movable(vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER_MOVABLE | __GFP_ZERO, vma, vmaddr) + alloc_page_vma(GFP_HIGHUSER_MOVABLE | __GFP_ZERO, vma, vaddr) #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE_MOVABLE
extern void copy_page(void * _to, void * _from);
From: Vasily Averin vvs@openvz.org
[ Upstream commit 2b132903de7124dd9a758be0c27562e91a510848 ]
Fixes following sparse warnings:
CHECK mm/vmscan.c mm/vmscan.c: note: in included file (through include/trace/trace_events.h, include/trace/define_trace.h, include/trace/events/vmscan.h): ./include/trace/events/vmscan.h:281:1: sparse: warning: cast to restricted isolate_mode_t ./include/trace/events/vmscan.h:281:1: sparse: warning: restricted isolate_mode_t degrades to integer
Link: https://lkml.kernel.org/r/e85d7ff2-fd10-53f8-c24e-ba0458439c1b@openvz.org Signed-off-by: Vasily Averin vvs@openvz.org Acked-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/vmscan.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index de136dbd623a..e7d28dc549da 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -297,7 +297,7 @@ TRACE_EVENT(mm_vmscan_lru_isolate, __field(unsigned long, nr_scanned) __field(unsigned long, nr_skipped) __field(unsigned long, nr_taken) - __field(isolate_mode_t, isolate_mode) + __field(unsigned int, isolate_mode) __field(int, lru) ),
@@ -308,7 +308,7 @@ TRACE_EVENT(mm_vmscan_lru_isolate, __entry->nr_scanned = nr_scanned; __entry->nr_skipped = nr_skipped; __entry->nr_taken = nr_taken; - __entry->isolate_mode = isolate_mode; + __entry->isolate_mode = (__force unsigned int)isolate_mode; __entry->lru = lru; ),
From: Enzo Matsumiya ematsumiya@suse.de
[ Upstream commit 337b8b0e4343567221ef8d88aac5e418208d4ac1 ]
EEXIST didn't make sense to use when dfs_cache_find() couldn't find a cache entry nor retrieve a referral target.
It also doesn't make sense cifs_dfs_query_info_nonascii_quirk() to emulate ENOENT anymore.
Signed-off-by: Enzo Matsumiya ematsumiya@suse.de Reviewed-by: Paulo Alcantara (SUSE) pc@cjr.nz Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/connect.c | 6 ++++-- fs/cifs/dfs_cache.c | 6 +++--- fs/cifs/misc.c | 6 +----- 3 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2a639fc79c30..b28b1ff39fed 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3406,8 +3406,9 @@ cifs_are_all_path_components_accessible(struct TCP_Server_Info *server, }
/* - * Check if path is remote (e.g. a DFS share). Return -EREMOTE if it is, - * otherwise 0. + * Check if path is remote (i.e. a DFS share). + * + * Return -EREMOTE if it is, otherwise 0 or -errno. */ static int is_path_remote(struct mount_ctx *mnt_ctx) { @@ -3697,6 +3698,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) if (!isdfs) goto out;
+ /* proceed as DFS mount */ uuid_gen(&mnt_ctx.mount_id); rc = connect_dfs_root(&mnt_ctx, &tl); dfs_cache_free_tgts(&tl); diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 956f8e5cf3e7..c5dd6f7305bd 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -654,7 +654,7 @@ static struct cache_entry *__lookup_cache_entry(const char *path, unsigned int h return ce; } } - return ERR_PTR(-EEXIST); + return ERR_PTR(-ENOENT); }
/* @@ -662,7 +662,7 @@ static struct cache_entry *__lookup_cache_entry(const char *path, unsigned int h * * Use whole path components in the match. Must be called with htable_rw_lock held. * - * Return ERR_PTR(-EEXIST) if the entry is not found. + * Return ERR_PTR(-ENOENT) if the entry is not found. */ static struct cache_entry *lookup_cache_entry(const char *path) { @@ -710,7 +710,7 @@ static struct cache_entry *lookup_cache_entry(const char *path) while (e > s && *e != sep) e--; } - return ERR_PTR(-EEXIST); + return ERR_PTR(-ENOENT); }
/** diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 114810e563a9..5a803d686146 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1308,7 +1308,7 @@ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix) * for "<server><dfsname><linkpath>" DFS reference, * where <dfsname> contains non-ASCII unicode symbols. * - * Check such DFS reference and emulate -ENOENT if it is actual. + * Check such DFS reference. */ int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid, struct cifs_tcon *tcon, @@ -1340,10 +1340,6 @@ int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid, cifs_dbg(FYI, "DFS ref '%s' is found, emulate -EREMOTE\n", dfspath); rc = -EREMOTE; - } else if (rc == -EEXIST) { - cifs_dbg(FYI, "DFS ref '%s' is not found, emulate -ENOENT\n", - dfspath); - rc = -ENOENT; } else { cifs_dbg(FYI, "%s: dfs_cache_find returned %d\n", __func__, rc); }
From: Haren Myneni haren@linux.ibm.com
[ Upstream commit c127d130f6d59fa81701f6b04023cf7cd1972fb3 ]
In init_winctx_regs(), __pa() is called on winctx->rx_fifo and this function is called to initialize registers for receive and fault windows. But the real address is passed in winctx->rx_fifo for receive windows and the virtual address for fault windows which causes errors with DEBUG_VIRTUAL enabled. Fixes this issue by assigning only real address to rx_fifo in vas_rx_win_attr struct for both receive and fault windows.
Reported-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Haren Myneni haren@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/338e958c7ab8f3b266fa794a1f80f99b9671829e.camel@lin... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/vas.h | 2 +- arch/powerpc/platforms/powernv/vas-fault.c | 2 +- arch/powerpc/platforms/powernv/vas-window.c | 4 ++-- arch/powerpc/platforms/powernv/vas.h | 2 +- drivers/crypto/nx/nx-common-powernv.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index 83afcb6c194b..c36f71e01c0f 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -126,7 +126,7 @@ static inline void vas_user_win_add_mm_context(struct vas_user_win_ref *ref) * Receive window attributes specified by the (in-kernel) owner of window. */ struct vas_rx_win_attr { - void *rx_fifo; + u64 rx_fifo; int rx_fifo_size; int wcreds_max;
diff --git a/arch/powerpc/platforms/powernv/vas-fault.c b/arch/powerpc/platforms/powernv/vas-fault.c index a7aabc18039e..c1bfad56447d 100644 --- a/arch/powerpc/platforms/powernv/vas-fault.c +++ b/arch/powerpc/platforms/powernv/vas-fault.c @@ -216,7 +216,7 @@ int vas_setup_fault_window(struct vas_instance *vinst) vas_init_rx_win_attr(&attr, VAS_COP_TYPE_FAULT);
attr.rx_fifo_size = vinst->fault_fifo_size; - attr.rx_fifo = vinst->fault_fifo; + attr.rx_fifo = __pa(vinst->fault_fifo);
/* * Max creds is based on number of CRBs can fit in the FIFO. diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 0f8d39fbf2b2..0072682531d8 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -404,7 +404,7 @@ static void init_winctx_regs(struct pnv_vas_window *window, * * See also: Design note in function header. */ - val = __pa(winctx->rx_fifo); + val = winctx->rx_fifo; val = SET_FIELD(VAS_PAGE_MIGRATION_SELECT, val, 0); write_hvwc_reg(window, VREG(LFIFO_BAR), val);
@@ -739,7 +739,7 @@ static void init_winctx_for_rxwin(struct pnv_vas_window *rxwin, */ winctx->fifo_disable = true; winctx->intr_disable = true; - winctx->rx_fifo = NULL; + winctx->rx_fifo = 0; }
winctx->lnotify_lpid = rxattr->lnotify_lpid; diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index 8bb08e395de0..08d9d3d5a22b 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -376,7 +376,7 @@ struct pnv_vas_window { * is a container for the register fields in the window context. */ struct vas_winctx { - void *rx_fifo; + u64 rx_fifo; int rx_fifo_size; int wcreds_max; int rsvd_txbuf_count; diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c index 32a036ada5d0..f418817c0f43 100644 --- a/drivers/crypto/nx/nx-common-powernv.c +++ b/drivers/crypto/nx/nx-common-powernv.c @@ -827,7 +827,7 @@ static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, goto err_out;
vas_init_rx_win_attr(&rxattr, coproc->ct); - rxattr.rx_fifo = (void *)rx_fifo; + rxattr.rx_fifo = rx_fifo; rxattr.rx_fifo_size = fifo_size; rxattr.lnotify_lpid = lpid; rxattr.lnotify_pid = pid;
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit 5dd9e27ea4a39f7edd4bf81e9e70208e7ac0b7c9 ]
The of_find_compatible_node() function returns a node pointer with refcount incremented, use of_node_put() on it when done.
Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220402013419.2410298-1-lv.ruyi@zte.com.cn Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/sysdev/xics/icp-opal.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/sysdev/xics/icp-opal.c b/arch/powerpc/sysdev/xics/icp-opal.c index bda4c32582d9..4dae624b9f2f 100644 --- a/arch/powerpc/sysdev/xics/icp-opal.c +++ b/arch/powerpc/sysdev/xics/icp-opal.c @@ -196,6 +196,7 @@ int __init icp_opal_init(void)
printk("XICS: Using OPAL ICP fallbacks\n");
+ of_node_put(np); return 0; }
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit 3ffa9fd471f57f365bc54fc87824c530422f64a5 ]
of_find_compatible_node() returns node pointer with refcount incremented, use of_node_put() on it when done.
Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220407090043.2491854-1-lv.ruyi@zte.com.cn Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/ultravisor.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/powernv/ultravisor.c b/arch/powerpc/platforms/powernv/ultravisor.c index e4a00ad06f9d..67c8c4b2d8b1 100644 --- a/arch/powerpc/platforms/powernv/ultravisor.c +++ b/arch/powerpc/platforms/powernv/ultravisor.c @@ -55,6 +55,7 @@ static int __init uv_init(void) return -ENODEV;
uv_memcons = memcons_init(node, "memcons"); + of_node_put(node); if (!uv_memcons) return -ENOENT;
From: Finn Thain fthain@linux-m68k.org
[ Upstream commit 86ce436e30d86327c9f5260f718104ae7b21f506 ]
drivers/macintosh/via-pmu-event.o: In function `via_pmu_event': via-pmu-event.c:(.text+0x44): undefined reference to `input_event' via-pmu-event.c:(.text+0x68): undefined reference to `input_event' via-pmu-event.c:(.text+0x94): undefined reference to `input_event' via-pmu-event.c:(.text+0xb8): undefined reference to `input_event' drivers/macintosh/via-pmu-event.o: In function `via_pmu_event_init': via-pmu-event.c:(.init.text+0x20): undefined reference to `input_allocate_device' via-pmu-event.c:(.init.text+0xc4): undefined reference to `input_register_device' via-pmu-event.c:(.init.text+0xd4): undefined reference to `input_free_device' make[1]: *** [Makefile:1155: vmlinux] Error 1 make: *** [Makefile:350: __build_one_by_one] Error 2
Don't call into the input subsystem unless CONFIG_INPUT is built-in.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Finn Thain fthain@linux-m68k.org Tested-by: Randy Dunlap rdunlap@infradead.org Reviewed-by: Christophe Leroy christophe.leroy@csgroup.eu Acked-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/5edbe76ce68227f71e09af4614cc4c1bd61c7ec8.164932629... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/macintosh/Kconfig | 4 ++++ drivers/macintosh/Makefile | 3 ++- drivers/macintosh/via-pmu.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 5cdc361da37c..3942db15a2b8 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -67,6 +67,10 @@ config ADB_PMU this device; you should do so if your machine is one of those mentioned above.
+config ADB_PMU_EVENT + def_bool y + depends on ADB_PMU && INPUT=y + config ADB_PMU_LED bool "Support for the Power/iBook front LED" depends on PPC_PMAC && ADB_PMU diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index 49819b1b6f20..712edcb3e0b0 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -12,7 +12,8 @@ obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o obj-$(CONFIG_INPUT_ADBHID) += adbhid.o obj-$(CONFIG_ANSLCD) += ans-lcd.o
-obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o +obj-$(CONFIG_ADB_PMU) += via-pmu.o +obj-$(CONFIG_ADB_PMU_EVENT) += via-pmu-event.o obj-$(CONFIG_ADB_PMU_LED) += via-pmu-led.o obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o obj-$(CONFIG_ADB_CUDA) += via-cuda.o diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 4b98bc26a94b..2109129ea1bb 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -1459,7 +1459,7 @@ pmu_handle_data(unsigned char *data, int len) pmu_pass_intr(data, len); /* len == 6 is probably a bad check. But how do I * know what PMU versions send what events here? */ - if (len == 6) { + if (IS_ENABLED(CONFIG_ADB_PMU_EVENT) && len == 6) { via_pmu_event(PMU_EVT_POWER, !!(data[1]&8)); via_pmu_event(PMU_EVT_LID, data[1]&1); }
From: Peng Wu wupeng58@huawei.com
[ Upstream commit 57b742a5b8945118022973e6416b71351df512fb ]
The device_node pointer is returned by of_find_compatible_node with refcount incremented. We should use of_node_put() to avoid the refcount leak.
Signed-off-by: Peng Wu wupeng58@huawei.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220425081245.21705-1-wupeng58@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/sysdev/dart_iommu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index be6b99b1b352..9a02aed886a0 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -404,9 +404,10 @@ void __init iommu_init_early_dart(struct pci_controller_ops *controller_ops) }
/* Initialize the DART HW */ - if (dart_init(dn) != 0) + if (dart_init(dn) != 0) { + of_node_put(dn); return; - + } /* * U4 supports a DART bypass, we use it for 64-bit capable devices to * improve performance. However, that only works for devices connected @@ -419,6 +420,7 @@ void __init iommu_init_early_dart(struct pci_controller_ops *controller_ops)
/* Setup pci_dma ops */ set_pci_dma_ops(&dma_iommu_ops); + of_node_put(dn); }
#ifdef CONFIG_PM
From: Vasily Averin vvs@openvz.org
[ Upstream commit dccd855771b37820b6d976a99729c88259549f85 ]
Fixes sparce warnings: fs/notify/fanotify/fanotify_user.c:267:63: sparse: warning: restricted fmode_t degrades to integer fs/notify/fanotify/fanotify_user.c:1351:28: sparse: warning: restricted fmode_t degrades to integer
FMODE_NONTIFY have bitwise fmode_t type and requires __force attribute for any casts.
Signed-off-by: Vasily Averin vvs@openvz.org Reviewed-by: Christian Brauner (Microsoft) brauner@kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/9adfd6ac-1b89-791e-796b-49ada3293985@openvz.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/notify/fanotify/fanotify_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index a792e21c5309..16d8fc84713a 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -264,7 +264,7 @@ static int create_fd(struct fsnotify_group *group, struct path *path, * originally opened O_WRONLY. */ new_file = dentry_open(path, - group->fanotify_data.f_flags | FMODE_NONOTIFY, + group->fanotify_data.f_flags | __FMODE_NONOTIFY, current_cred()); if (IS_ERR(new_file)) { /* @@ -1348,7 +1348,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) (!(fid_mode & FAN_REPORT_NAME) || !(fid_mode & FAN_REPORT_FID))) return -EINVAL;
- f_flags = O_RDWR | FMODE_NONOTIFY; + f_flags = O_RDWR | __FMODE_NONOTIFY; if (flags & FAN_CLOEXEC) f_flags |= O_CLOEXEC; if (flags & FAN_NONBLOCK)
From: Steve French stfrench@microsoft.com
[ Upstream commit bbdf6cf56c88845fb0b713cbf5c6623c53fe40d8 ]
Although unlikely to be null, it is confusing to use a pointer before checking for it to be null so move the use down after null check.
Addresses-Coverity: 1517586 ("Null pointer dereferences (REVERSE_INULL)") Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/smb2ops.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 2df9aab12db7..861291662c95 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -760,8 +760,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, struct cached_fid **cfid) { - struct cifs_ses *ses = tcon->ses; - struct TCP_Server_Info *server = ses->server; + struct cifs_ses *ses; + struct TCP_Server_Info *server; struct cifs_open_parms oparms; struct smb2_create_rsp *o_rsp = NULL; struct smb2_query_info_rsp *qi_rsp = NULL; @@ -779,6 +779,9 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, if (tcon->nohandlecache) return -ENOTSUPP;
+ ses = tcon->ses; + server = ses->server; + if (cifs_sb->root == NULL) return -ENOENT;
From: Douglas Miller doug.miller@cornelisnetworks.com
[ Upstream commit 629e052d0c98e46dde9f0824f0aa437f678d9b8f ]
If the hfi1 module is loaded with HFI1_CAP_SDMA off, a call to hfi1_write_iter() will dereference a NULL pointer and panic. A typical stack frame is:
sdma_select_user_engine [hfi1] hfi1_user_sdma_process_request [hfi1] hfi1_write_iter [hfi1] do_iter_readv_writev do_iter_write vfs_writev do_writev do_syscall_64
The fix is to test for SDMA in hfi1_write_iter() and fail the I/O with EINVAL.
Link: https://lore.kernel.org/r/20220520183706.48973.79803.stgit@awfm-01.cornelisn... Signed-off-by: Douglas Miller doug.miller@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/file_ops.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index 1783a6ea5427..3ebdd42fec36 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -265,6 +265,8 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) unsigned long dim = from->nr_segs; int idx;
+ if (!HFI1_CAP_IS_KSET(SDMA)) + return -EINVAL; idx = srcu_read_lock(&fd->pq_srcu); pq = srcu_dereference(fd->pq, &fd->pq_srcu); if (!cq || !pq) {
From: Shyam Prasad N sprasad@microsoft.com
[ Upstream commit 1a6a41d4cedd9b302e2200e6f0e3c44dbbe13689 ]
Recent changes to multichannel to allow channel reconnects to work in parallel and independent of each other did so by making use of tcpStatus for the connection, and status for the session. However, this did not take into account the multiuser scenario, where same connection is used by multiple connections.
However, tcpStatus should be tracked only till the end of negotiate exchange, and not used for session setup. This change fixes this.
Signed-off-by: Shyam Prasad N sprasad@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/cifs/connect.c | 23 +++++++++++------------ fs/cifs/smb2pdu.c | 3 ++- fs/cifs/smb2transport.c | 3 ++- 3 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index b28b1ff39fed..aa2d4c49e2a5 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3956,7 +3956,7 @@ cifs_negotiate_protocol(const unsigned int xid, struct cifs_ses *ses, if (rc == 0) { spin_lock(&cifs_tcp_ses_lock); if (server->tcpStatus == CifsInNegotiate) - server->tcpStatus = CifsNeedSessSetup; + server->tcpStatus = CifsGood; else rc = -EHOSTDOWN; spin_unlock(&cifs_tcp_ses_lock); @@ -3979,19 +3979,18 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, bool is_binding = false;
/* only send once per connect */ + spin_lock(&ses->chan_lock); + is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses); + spin_unlock(&ses->chan_lock); + spin_lock(&cifs_tcp_ses_lock); - if ((server->tcpStatus != CifsNeedSessSetup) && - (ses->status == CifsGood)) { + if (ses->status == CifsExiting) { spin_unlock(&cifs_tcp_ses_lock); return 0; } - server->tcpStatus = CifsInSessSetup; + ses->status = CifsInSessSetup; spin_unlock(&cifs_tcp_ses_lock);
- spin_lock(&ses->chan_lock); - is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses); - spin_unlock(&ses->chan_lock); - if (!is_binding) { ses->capabilities = server->capabilities; if (!linuxExtEnabled) @@ -4015,13 +4014,13 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, if (rc) { cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc); spin_lock(&cifs_tcp_ses_lock); - if (server->tcpStatus == CifsInSessSetup) - server->tcpStatus = CifsNeedSessSetup; + if (ses->status == CifsInSessSetup) + ses->status = CifsNeedSessSetup; spin_unlock(&cifs_tcp_ses_lock); } else { spin_lock(&cifs_tcp_ses_lock); - if (server->tcpStatus == CifsInSessSetup) - server->tcpStatus = CifsGood; + if (ses->status == CifsInSessSetup) + ses->status = CifsGood; /* Even if one channel is active, session is in good state */ ses->status = CifsGood; spin_unlock(&cifs_tcp_ses_lock); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 1b7ad0c09566..f5321a3500f3 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3899,7 +3899,8 @@ SMB2_echo(struct TCP_Server_Info *server) cifs_dbg(FYI, "In echo request for conn_id %lld\n", server->conn_id);
spin_lock(&cifs_tcp_ses_lock); - if (server->tcpStatus == CifsNeedNegotiate) { + if (server->ops->need_neg && + server->ops->need_neg(server)) { spin_unlock(&cifs_tcp_ses_lock); /* No need to send echo on newly established connections */ mod_delayed_work(cifsiod_wq, &server->reconnect, 0); diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 2af79093b78b..01b732641edb 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -641,7 +641,8 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) if (!is_signed) return 0; spin_lock(&cifs_tcp_ses_lock); - if (server->tcpStatus == CifsNeedNegotiate) { + if (server->ops->need_neg && + server->ops->need_neg(server)) { spin_unlock(&cifs_tcp_ses_lock); return 0; }
From: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
[ Upstream commit cee409bbba0d1bd3fb73064fb480ff365f453b5d ]
gpio_keys module can either accept gpios or interrupts. The module initializes delayed work in case of gpios only and is only used if debounce timer is not used, so make sure cancel_delayed_work_sync() is called only when its gpio-backed and debounce_use_hrtimer is false.
This fixes the issue seen below when the gpio_keys module is unloaded and an interrupt pin is used instead of GPIO:
[ 360.297569] ------------[ cut here ]------------ [ 360.302303] WARNING: CPU: 0 PID: 237 at kernel/workqueue.c:3066 __flush_work+0x414/0x470 [ 360.310531] Modules linked in: gpio_keys(-) [ 360.314797] CPU: 0 PID: 237 Comm: rmmod Not tainted 5.18.0-rc5-arm64-renesas-00116-g73636105874d-dirty #166 [ 360.324662] Hardware name: Renesas SMARC EVK based on r9a07g054l2 (DT) [ 360.331270] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 360.338318] pc : __flush_work+0x414/0x470 [ 360.342385] lr : __cancel_work_timer+0x140/0x1b0 [ 360.347065] sp : ffff80000a7fba00 [ 360.350423] x29: ffff80000a7fba00 x28: ffff000012b9c5c0 x27: 0000000000000000 [ 360.357664] x26: ffff80000a7fbb80 x25: ffff80000954d0a8 x24: 0000000000000001 [ 360.364904] x23: ffff800009757000 x22: 0000000000000000 x21: ffff80000919b000 [ 360.372143] x20: ffff00000f5974e0 x19: ffff00000f5974e0 x18: ffff8000097fcf48 [ 360.379382] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000053f40 [ 360.386622] x14: ffff800009850e88 x13: 0000000000000002 x12: 000000000000a60c [ 360.393861] x11: 000000000000a610 x10: 0000000000000000 x9 : 0000000000000008 [ 360.401100] x8 : 0101010101010101 x7 : 00000000a473c394 x6 : 0080808080808080 [ 360.408339] x5 : 0000000000000001 x4 : 0000000000000000 x3 : ffff80000919b458 [ 360.415578] x2 : ffff8000097577f0 x1 : 0000000000000001 x0 : 0000000000000000 [ 360.422818] Call trace: [ 360.425299] __flush_work+0x414/0x470 [ 360.429012] __cancel_work_timer+0x140/0x1b0 [ 360.433340] cancel_delayed_work_sync+0x10/0x18 [ 360.437931] gpio_keys_quiesce_key+0x28/0x58 [gpio_keys] [ 360.443327] devm_action_release+0x10/0x18 [ 360.447481] release_nodes+0x8c/0x1a0 [ 360.451194] devres_release_all+0x90/0x100 [ 360.455346] device_unbind_cleanup+0x14/0x60 [ 360.459677] device_release_driver_internal+0xe8/0x168 [ 360.464883] driver_detach+0x4c/0x90 [ 360.468509] bus_remove_driver+0x54/0xb0 [ 360.472485] driver_unregister+0x2c/0x58 [ 360.476462] platform_driver_unregister+0x10/0x18 [ 360.481230] gpio_keys_exit+0x14/0x828 [gpio_keys] [ 360.486088] __arm64_sys_delete_module+0x1e0/0x270 [ 360.490945] invoke_syscall+0x40/0xf8 [ 360.494661] el0_svc_common.constprop.3+0xf0/0x110 [ 360.499515] do_el0_svc+0x20/0x78 [ 360.502877] el0_svc+0x48/0xf8 [ 360.505977] el0t_64_sync_handler+0x88/0xb0 [ 360.510216] el0t_64_sync+0x148/0x14c [ 360.513930] irq event stamp: 4306 [ 360.517288] hardirqs last enabled at (4305): [<ffff8000080b0300>] __cancel_work_timer+0x130/0x1b0 [ 360.526359] hardirqs last disabled at (4306): [<ffff800008d194fc>] el1_dbg+0x24/0x88 [ 360.534204] softirqs last enabled at (4278): [<ffff8000080104a0>] _stext+0x4a0/0x5e0 [ 360.542133] softirqs last disabled at (4267): [<ffff8000080932ac>] irq_exit_rcu+0x18c/0x1b0 [ 360.550591] ---[ end trace 0000000000000000 ]---
Signed-off-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Link: https://lore.kernel.org/r/20220524135822.14764-1-prabhakar.mahadev-lad.rj@bp... Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/keyboard/gpio_keys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index d75a8b179a8a..a5dc4ab87fa1 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -131,7 +131,7 @@ static void gpio_keys_quiesce_key(void *data)
if (!bdata->gpiod) hrtimer_cancel(&bdata->release_timer); - if (bdata->debounce_use_hrtimer) + else if (bdata->debounce_use_hrtimer) hrtimer_cancel(&bdata->debounce_timer); else cancel_delayed_work_sync(&bdata->work);
From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit 47f15561b69e226bfc034e94ff6dbec51a4662af ]
When building the kernel for arm with the "-mabi=apcs-gnu" option, gcc will force alignment of all structures and unions to a word boundary (see also STRUCTURE_SIZE_BOUNDARY and the "-mstructure-size-boundary=XX" option if you're a gcc person), even when the members of said structures do not want or need said alignment.
This completely messes up the structure alignment of 'struct edid' on those targets, because even though all the embedded structures are marked with "__attribute__((packed))", the unions that contain them are not.
This was exposed by commit f1e4c916f97f ("drm/edid: add EDID block count and size helpers"), but the bug is pre-existing. That commit just made the structure layout problem cause a build failure due to the addition of the
BUILD_BUG_ON(sizeof(*edid) != EDID_LENGTH);
sanity check in drivers/gpu/drm/drm_edid.c:edid_block_data().
This legacy union alignment should probably not be used in the first place, but we can fix the layout by adding the packed attribute to the union entries even when each member is already packed and it shouldn't matter in a sane build environment.
You can see this issue with a trivial test program:
union { struct { char c[5]; }; struct { char d; unsigned e; } __attribute__((packed)); } a = { "1234" };
where building this with a normal "gcc -S" will result in the expected 5-byte size of said union:
.type a, @object .size a, 5
but with an ARM compiler and the old ABI:
arm-linux-gnu-gcc -mabi=apcs-gnu -mfloat-abi=soft -S t.c
you get
.type a, %object .size a, 8
instead, because even though each member of the union is packed, the union itself still gets aligned.
This was reported by Sudip for the spear3xx_defconfig target.
Link: https://lore.kernel.org/lkml/YpCUzStDnSgQLNFN@debian/ Reported-by: Sudip Mukherjee sudipm.mukherjee@gmail.com Acked-by: Arnd Bergmann arnd@arndb.de Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Maxime Ripard mripard@kernel.org Cc: Thomas Zimmermann tzimmermann@suse.de Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/drm/drm_edid.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 144c495b99c4..d6b2aeb34211 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -121,7 +121,7 @@ struct detailed_data_monitor_range { u8 supported_scalings; u8 preferred_refresh; } __attribute__((packed)) cvt; - } formula; + } __attribute__((packed)) formula; } __attribute__((packed));
struct detailed_data_wpindex { @@ -154,7 +154,7 @@ struct detailed_non_pixel { struct detailed_data_wpindex color; struct std_timing timings[6]; struct cvt_timing cvt[4]; - } data; + } __attribute__((packed)) data; } __attribute__((packed));
#define EDID_DETAIL_EST_TIMINGS 0xf7 @@ -172,7 +172,7 @@ struct detailed_timing { union { struct detailed_pixel_timing pixel_data; struct detailed_non_pixel other_data; - } data; + } __attribute__((packed)) data; } __attribute__((packed));
#define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 0)
From: Nikita Yushchenko nikita.yoush@cogentembedded.com
[ Upstream commit 09077bc3116581f4d1cb961ec359ad56586e370b ]
Hotplug events reported by bridge drivers over drm_bridge_hpd_notify() get ignored unless somebody calls drm_bridge_hpd_enable(). When the connector for the bridge is bridge_connector, such a call is done from drm_bridge_connector_enable_hpd().
However drm_bridge_connector_enable_hpd() is never called on init paths, documentation suggests that it is intended for suspend/resume paths.
In result, once encoders are switched to bridge_connector, bridge-detected HPD stops working.
This patch adds a call to that API on init path.
This fixes HDMI HPD with rcar-du + adv7513 case when adv7513 reports HPD events via interrupts.
Fixes: c24110a8fd09 ("drm: rcar-du: Use drm_bridge_connector_init() helper") Signed-off-by: Nikita Yushchenko nikita.yoush@cogentembedded.com Signed-off-by: Paul Cercueil paul@crapouillou.net Tested-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Link: https://patchwork.freedesktop.org/patch/msgid/20211225063151.2110878-1-nikit... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_bridge_connector.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index 60923cdfe8e1..6b3dad03d77d 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -384,8 +384,10 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, connector_type, ddc); drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);
- if (bridge_connector->bridge_hpd) + if (bridge_connector->bridge_hpd) { connector->polled = DRM_CONNECTOR_POLL_HPD; + drm_bridge_connector_enable_hpd(connector); + } else if (bridge_connector->bridge_detect) connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 016d1ca3f6ad05676fd9e418715ddce1f4ab5a73 ]
Set the error code to -ENOMEM if drm_random_order() fails.
Fixes: e6ff5ef81170 ("drm/selftests: add drm buddy smoke testcase") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Arunpravin Arunpravin.PaneerSelvam@amd.com Signed-off-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20220307125458.GA16710@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/selftests/test-drm_buddy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/selftests/test-drm_buddy.c b/drivers/gpu/drm/selftests/test-drm_buddy.c index 913cbd7eae04..aca0c491040f 100644 --- a/drivers/gpu/drm/selftests/test-drm_buddy.c +++ b/drivers/gpu/drm/selftests/test-drm_buddy.c @@ -488,8 +488,10 @@ static int igt_buddy_alloc_smoke(void *arg) }
order = drm_random_order(mm.max_order + 1, &prng); - if (!order) + if (!order) { + err = -ENOMEM; goto out_fini; + }
for (i = 0; i <= mm.max_order; ++i) { struct drm_buddy_block *block;
From: Wan Jiabing wanjiabing@vivo.com
[ Upstream commit 8f2a3970c969d0d8d7289a4c65edcedafc16fd92 ]
Fix the following coccicheck warning: ./drivers/gpu/drm/omapdrm/omap_overlay.c:89:22-25: ERROR: r_ovl is NULL but dereferenced.
Here should be ovl->idx rather than r_ovl->idx.
Fixes: e02b5cc9e898ad ("drm/omap: Add a 'right overlay' to plane state") Signed-off-by: Wan Jiabing wanjiabing@vivo.com Signed-off-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Link: https://patchwork.freedesktop.org/patch/msgid/20220307095612.409090-1-wanjia... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/omapdrm/omap_overlay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_overlay.c b/drivers/gpu/drm/omapdrm/omap_overlay.c index 10730c9b2752..b0bc9ad2ef73 100644 --- a/drivers/gpu/drm/omapdrm/omap_overlay.c +++ b/drivers/gpu/drm/omapdrm/omap_overlay.c @@ -86,7 +86,7 @@ int omap_overlay_assign(struct drm_atomic_state *s, struct drm_plane *plane, r_ovl = omap_plane_find_free_overlay(s->dev, overlay_map, caps, fourcc); if (!r_ovl) { - overlay_map[r_ovl->idx] = NULL; + overlay_map[ovl->idx] = NULL; *overlay = NULL; return -ENOMEM; }
From: Noralf Trønnes noralf@tronnes.org
[ Upstream commit 471e201f543559e2cb19b182b680ebf04d80ee31 ]
The backlight property was lost during conversion to yaml in commit abdd9e3705c8 ("dt-bindings: display: sitronix,st7735r: Convert to DT schema"). Put it back.
Fixes: abdd9e3705c8 ("dt-bindings: display: sitronix,st7735r: Convert to DT schema") Signed-off-by: Noralf Trønnes noralf@tronnes.org Acked-by: Rob Herring robh@kernel.org Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Acked-by: David Lechner david@lechnology.com Link: https://patchwork.freedesktop.org/patch/msgid/20211124150757.17929-2-noralf@... Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/devicetree/bindings/display/sitronix,st7735r.yaml | 1 + 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml index 0cebaaefda03..419c3b2ac5a6 100644 --- a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml +++ b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml @@ -72,6 +72,7 @@ examples: dc-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; rotation = <270>; + backlight = <&backlight>; }; };
From: Tom Rix trix@redhat.com
[ Upstream commit d583e752732421b26fef0d65020565f3bef12248 ]
Clang static analysis reports this issue anx7625.c:876:13: warning: The left operand of '&' is a garbage value if (!(bcap & 0xOA01)) { ~~~~ ^
bcap is only set by a successful call to anx7625_aux_trans(). So check.
Fixes: cd1637c7e480 ("drm/bridge: anx7625: add HDCP support") Signed-off-by: Tom Rix trix@redhat.com Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux channel") Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220303201943.501746-1-trix@r... Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 31ecf5626f1d..8e1851a57638 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -874,7 +874,10 @@ static int anx7625_hdcp_enable(struct anx7625_data *ctx) }
/* Read downstream capability */ - anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, 0x68028, 1, &bcap); + ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, 0x68028, 1, &bcap); + if (ret < 0) + return ret; + if (!(bcap & 0x01)) { pr_warn("downstream not support HDCP 1.4, cap(%x).\n", bcap); return 0;
From: Chen-Yu Tsai wens@csie.org
[ Upstream commit efb37e66b7572ce4696aa0ac21675e17d6b9a17d ]
The SSD130x's command to toggle COM scan direction uses bit 3 and only bit 3 to set the direction of the scanout. The driver has an incorrect GENMASK(3, 2), causing the setting to be set on bit 2, rendering it ineffective.
Fix the mask to only bit 3, so that the requested setting is applied correctly.
Fixes: a61732e80867 ("drm: Add driver for Solomon SSD130x OLED displays") Signed-off-by: Chen-Yu Tsai wens@csie.org Acked-by: Javier Martinez Canillas javierm@redhat.com Tested-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220308160758.26060-1-wens@ke... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/ssd130x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index ce4dc20412e0..ccd378135589 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -61,7 +61,7 @@ #define SSD130X_SET_COM_PINS_CONFIG 0xda #define SSD130X_SET_VCOMH 0xdb
-#define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 2) +#define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 3) #define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val)) #define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0) #define SSD130X_SET_CLOCK_DIV_SET(val) FIELD_PREP(SSD130X_SET_CLOCK_DIV_MASK, (val))
From: Chen-Yu Tsai wens@csie.org
[ Upstream commit a134109c301736ea2ac5054ba3c29c30c87f6ba7 ]
Currently the ssd130x driver only sets the segment remap setting when the device tree requests it; it however does not clear the setting if it is not requested. This leads to the setting incorrectly persisting if the hardware is always on and has no reset GPIO wired. This might happen when a developer is trying to find the correct settings for an unknown module, and cause the developer to get confused because the settings from the device tree are not consistently applied.
Make the driver apply the segment remap setting consistently, setting the value correctly based on the device tree setting. This also makes this setting's behavior consistent with the other settings, which are always applied.
Fixes: a61732e80867 ("drm: Add driver for Solomon SSD130x OLED displays") Signed-off-by: Chen-Yu Tsai wens@csie.org Acked-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220308160758.26060-2-wens@ke... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/ssd130x.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index ccd378135589..d08d86ef07bc 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -48,7 +48,7 @@ #define SSD130X_CONTRAST 0x81 #define SSD130X_SET_LOOKUP_TABLE 0x91 #define SSD130X_CHARGE_PUMP 0x8d -#define SSD130X_SEG_REMAP_ON 0xa1 +#define SSD130X_SET_SEG_REMAP 0xa0 #define SSD130X_DISPLAY_OFF 0xae #define SSD130X_SET_MULTIPLEX_RATIO 0xa8 #define SSD130X_DISPLAY_ON 0xaf @@ -61,6 +61,8 @@ #define SSD130X_SET_COM_PINS_CONFIG 0xda #define SSD130X_SET_VCOMH 0xdb
+#define SSD130X_SET_SEG_REMAP_MASK GENMASK(0, 0) +#define SSD130X_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD130X_SET_SEG_REMAP_MASK, (val)) #define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 3) #define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val)) #define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0) @@ -235,7 +237,7 @@ static void ssd130x_power_off(struct ssd130x_device *ssd130x)
static int ssd130x_init(struct ssd130x_device *ssd130x) { - u32 precharge, dclk, com_invdir, compins, chargepump; + u32 precharge, dclk, com_invdir, compins, chargepump, seg_remap; int ret;
/* Set initial contrast */ @@ -244,11 +246,11 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) return ret;
/* Set segment re-map */ - if (ssd130x->seg_remap) { - ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SEG_REMAP_ON); - if (ret < 0) - return ret; - } + seg_remap = (SSD130X_SET_SEG_REMAP | + SSD130X_SET_SEG_REMAP_SET(ssd130x->seg_remap)); + ret = ssd130x_write_cmd(ssd130x, 1, seg_remap); + if (ret < 0) + return ret;
/* Set COM direction */ com_invdir = (SSD130X_SET_COM_SCAN_DIR |
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 47042e0ddd218f100292cebc5208cb1eff7473b6 ]
WARNING: unmet direct dependencies detected for DRM_GEM_SHMEM_HELPER Depends on [n]: HAS_IOMEM [=y] && DRM [=m] && MMU [=n] Selected by [m]: - DRM_SSD130X [=m] && HAS_IOMEM [=y] && DRM [=m]
DRM_GEM_SHMEM_HELPER depends on MMU, DRM_SSD130X should also depends on MMU.
Fixes: a61732e80867 ("drm: Add driver for Solomon SSD130x OLED displays") Signed-off-by: YueHaibing yuehaibing@huawei.com Acked-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220312063437.19160-1-yuehaib... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index 5861c3ab7c45..6230369505c9 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -1,6 +1,6 @@ config DRM_SSD130X tristate "DRM support for Solomon SSD130x OLED displays" - depends on DRM + depends on DRM && MMU select BACKLIGHT_CLASS_DEVICE select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 9b13a3fcd35fc24045d2fd0f0e13ddd8d7985b4b ]
There is no "reversed" handling in drm_fb_xrgb8888_to_mono_reversed(): the function just converts from color to grayscale, and reduces the number of grayscale levels from 256 to 2 (i.e. brightness 0-127 is mapped to 0, 128-255 to 1). All "reversed" handling is done in the repaper driver, where this function originated.
Hence make this clear by renaming drm_fb_xrgb8888_to_mono_reversed() to drm_fb_xrgb8888_to_mono(), and documenting the black/white pixel mapping.
Fixes: bcf8b616deb87941 ("drm/format-helper: Add drm_fb_xrgb8888_to_mono_reversed()") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Acked-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220317081830.1211400-2-geert... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_format_helper.c | 31 ++++++++++++++--------------- drivers/gpu/drm/solomon/ssd130x.c | 2 +- drivers/gpu/drm/tiny/repaper.c | 2 +- include/drm/drm_format_helper.h | 5 ++--- 4 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index bc0f49773868..5d9d0c695845 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -594,8 +594,8 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for } EXPORT_SYMBOL(drm_fb_blit_toio);
-static void drm_fb_gray8_to_mono_reversed_line(u8 *dst, const u8 *src, unsigned int pixels, - unsigned int start_offset, unsigned int end_len) +static void drm_fb_gray8_to_mono_line(u8 *dst, const u8 *src, unsigned int pixels, + unsigned int start_offset, unsigned int end_len) { unsigned int xb, i;
@@ -621,8 +621,8 @@ static void drm_fb_gray8_to_mono_reversed_line(u8 *dst, const u8 *src, unsigned }
/** - * drm_fb_xrgb8888_to_mono_reversed - Convert XRGB8888 to reversed monochrome - * @dst: reversed monochrome destination buffer + * drm_fb_xrgb8888_to_mono - Convert XRGB8888 to monochrome + * @dst: monochrome destination buffer (0=black, 1=white) * @dst_pitch: Number of bytes between two consecutive scanlines within dst * @src: XRGB8888 source buffer * @fb: DRM framebuffer @@ -633,10 +633,10 @@ static void drm_fb_gray8_to_mono_reversed_line(u8 *dst, const u8 *src, unsigned * and use this function to convert to the native format. * * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and - * then the result is converted from grayscale to reversed monohrome. + * then the result is converted from grayscale to monochrome. */ -void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const void *vaddr, - const struct drm_framebuffer *fb, const struct drm_rect *clip) +void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vaddr, + const struct drm_framebuffer *fb, const struct drm_rect *clip) { unsigned int linepixels = drm_rect_width(clip); unsigned int lines = clip->y2 - clip->y1; @@ -652,8 +652,8 @@ void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const v return;
/* - * The reversed mono destination buffer contains 1 bit per pixel - * and destination scanlines have to be in multiple of 8 pixels. + * The mono destination buffer contains 1 bit per pixel and + * destination scanlines have to be in multiple of 8 pixels. */ if (!dst_pitch) dst_pitch = DIV_ROUND_UP(linepixels, 8); @@ -664,9 +664,9 @@ void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const v * The cma memory is write-combined so reads are uncached. * Speed up by fetching one line at a time. * - * Also, format conversion from XR24 to reversed monochrome - * are done line-by-line but are converted to 8-bit grayscale - * as an intermediate step. + * Also, format conversion from XR24 to monochrome are done + * line-by-line but are converted to 8-bit grayscale as an + * intermediate step. * * Allocate a buffer to be used for both copying from the cma * memory and to store the intermediate grayscale line pixels. @@ -683,7 +683,7 @@ void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const v * are not aligned to multiple of 8. * * Calculate if the start and end pixels are not aligned and set the - * offsets for the reversed mono line conversion function to adjust. + * offsets for the mono line conversion function to adjust. */ start_offset = clip->x1 % 8; end_len = clip->x2 % 8; @@ -692,12 +692,11 @@ void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const v for (y = 0; y < lines; y++) { src32 = memcpy(src32, vaddr, len_src32); drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels); - drm_fb_gray8_to_mono_reversed_line(mono, gray8, dst_pitch, - start_offset, end_len); + drm_fb_gray8_to_mono_line(mono, gray8, dst_pitch, start_offset, end_len); vaddr += fb->pitches[0]; mono += dst_pitch; }
kfree(src32); } -EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono_reversed); +EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index d08d86ef07bc..caee851efd57 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -458,7 +458,7 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m if (!buf) return -ENOMEM;
- drm_fb_xrgb8888_to_mono_reversed(buf, 0, vmap, fb, rect); + drm_fb_xrgb8888_to_mono(buf, 0, vmap, fb, rect);
ssd130x_update_rect(ssd130x, buf, rect);
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 37b6bb90e46e..a096fb8b83e9 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -540,7 +540,7 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) if (ret) goto out_free;
- drm_fb_xrgb8888_to_mono_reversed(buf, 0, cma_obj->vaddr, fb, &clip); + drm_fb_xrgb8888_to_mono(buf, 0, cma_obj->vaddr, fb, &clip);
drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
diff --git a/include/drm/drm_format_helper.h b/include/drm/drm_format_helper.h index 0b0937c0b2f6..55145eca0782 100644 --- a/include/drm/drm_format_helper.h +++ b/include/drm/drm_format_helper.h @@ -43,8 +43,7 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for const void *vmap, const struct drm_framebuffer *fb, const struct drm_rect *rect);
-void drm_fb_xrgb8888_to_mono_reversed(void *dst, unsigned int dst_pitch, const void *src, - const struct drm_framebuffer *fb, - const struct drm_rect *clip); +void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *src, + const struct drm_framebuffer *fb, const struct drm_rect *clip);
#endif /* __LINUX_DRM_FORMAT_HELPER_H */
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 7392f2459eefcdab1d998af002d2b8b16fe4a2fd ]
The conversion functions drm_fb_xrgb8888_to_mono() and drm_fb_gray8_to_mono_line() do not behave correctly when the horizontal boundaries of the clip rectangle are not multiples of 8: a. When x1 % 8 != 0, the calculated pitch is not correct, b. When x2 % 8 != 0, the pixel data for the last byte is wrong.
Simplify the code and fix (a) by: 1. Removing start_offset, and always storing the first pixel in the first bit of the monochrome destination buffer. Drivers that require the first pixel in a byte to be located at an x-coordinate that is a multiple of 8 can always align the clip rectangle before calling drm_fb_xrgb8888_to_mono(). Note that: - The ssd130x driver does not need the alignment, as the monochrome buffer is a temporary format, - The repaper driver always updates the full screen, so the clip rectangle is always aligned. 2. Passing the number of pixels to drm_fb_gray8_to_mono_line(), instead of the number of bytes, and the number of pixels in the last byte.
Fix (b) by explicitly setting the target bit, instead of always setting bit 7 and shifting the value in each loop iteration.
Remove the bogus pitch check, which operates on bytes instead of pixels, and triggers when e.g. flashing the cursor on a text console with a font that is 8 pixels wide.
Drop the confusing comment about scanlines, as a pitch in bytes always contains a multiple of 8 pixels.
While at it, use the drm_rect_height() helper instead of open-coding the same operation.
Update the comments accordingly.
Fixes: bcf8b616deb87941 ("drm/format-helper: Add drm_fb_xrgb8888_to_mono_reversed()") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Acked-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220317081830.1211400-3-geert... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_format_helper.c | 55 ++++++++++------------------- 1 file changed, 18 insertions(+), 37 deletions(-)
diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 5d9d0c695845..e085f855a199 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -594,27 +594,16 @@ int drm_fb_blit_toio(void __iomem *dst, unsigned int dst_pitch, uint32_t dst_for } EXPORT_SYMBOL(drm_fb_blit_toio);
-static void drm_fb_gray8_to_mono_line(u8 *dst, const u8 *src, unsigned int pixels, - unsigned int start_offset, unsigned int end_len) -{ - unsigned int xb, i; - - for (xb = 0; xb < pixels; xb++) { - unsigned int start = 0, end = 8; - u8 byte = 0x00; - - if (xb == 0 && start_offset) - start = start_offset;
- if (xb == pixels - 1 && end_len) - end = end_len; - - for (i = start; i < end; i++) { - unsigned int x = xb * 8 + i; +static void drm_fb_gray8_to_mono_line(u8 *dst, const u8 *src, unsigned int pixels) +{ + while (pixels) { + unsigned int i, bits = min(pixels, 8U); + u8 byte = 0;
- byte >>= 1; - if (src[x] >> 7) - byte |= BIT(7); + for (i = 0; i < bits; i++, pixels--) { + if (*src++ >= 128) + byte |= BIT(i); } *dst++ = byte; } @@ -634,16 +623,22 @@ static void drm_fb_gray8_to_mono_line(u8 *dst, const u8 *src, unsigned int pixel * * This function uses drm_fb_xrgb8888_to_gray8() to convert to grayscale and * then the result is converted from grayscale to monochrome. + * + * The first pixel (upper left corner of the clip rectangle) will be converted + * and copied to the first bit (LSB) in the first byte of the monochrome + * destination buffer. + * If the caller requires that the first pixel in a byte must be located at an + * x-coordinate that is a multiple of 8, then the caller must take care itself + * of supplying a suitable clip rectangle. */ void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { unsigned int linepixels = drm_rect_width(clip); - unsigned int lines = clip->y2 - clip->y1; + unsigned int lines = drm_rect_height(clip); unsigned int cpp = fb->format->cpp[0]; unsigned int len_src32 = linepixels * cpp; struct drm_device *dev = fb->dev; - unsigned int start_offset, end_len; unsigned int y; u8 *mono = dst, *gray8; u32 *src32; @@ -652,14 +647,11 @@ void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vadd return;
/* - * The mono destination buffer contains 1 bit per pixel and - * destination scanlines have to be in multiple of 8 pixels. + * The mono destination buffer contains 1 bit per pixel */ if (!dst_pitch) dst_pitch = DIV_ROUND_UP(linepixels, 8);
- drm_WARN_ONCE(dev, dst_pitch % 8 != 0, "dst_pitch is not a multiple of 8\n"); - /* * The cma memory is write-combined so reads are uncached. * Speed up by fetching one line at a time. @@ -677,22 +669,11 @@ void drm_fb_xrgb8888_to_mono(void *dst, unsigned int dst_pitch, const void *vadd
gray8 = (u8 *)src32 + len_src32;
- /* - * For damage handling, it is possible that only parts of the source - * buffer is copied and this could lead to start and end pixels that - * are not aligned to multiple of 8. - * - * Calculate if the start and end pixels are not aligned and set the - * offsets for the mono line conversion function to adjust. - */ - start_offset = clip->x1 % 8; - end_len = clip->x2 % 8; - vaddr += clip_offset(clip, fb->pitches[0], cpp); for (y = 0; y < lines; y++) { src32 = memcpy(src32, vaddr, len_src32); drm_fb_xrgb8888_to_gray8_line(gray8, src32, linepixels); - drm_fb_gray8_to_mono_line(mono, gray8, dst_pitch, start_offset, end_len); + drm_fb_gray8_to_mono_line(mono, gray8, linepixels); vaddr += fb->pitches[0]; mono += dst_pitch; }
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit a97e753fd358e23155ae42c61292dfd57eb54c4a ]
The rectangle update functions ssd130x_fb_blit_rect() and ssd130x_update_rect() do not behave correctly when x1 != 0 or y1 != 0, or when y1 or y2 are not aligned to display page boundaries. E.g. when used as a text console, only the first line of text is shown on the display.
1. The buffer passed by ssd130x_fb_blit_rect() points to the first byte of monochrome bitmap data, and thus has its origin at (x1, y1), while ssd130x_update_rect() assumes it is at (0, 0). Fix ssd130x_update_rect() by changing the vertical and horizontal loop ranges, and adding the offsets only when needed.
2. In ssd130x_fb_blit_rect(), align y1 and y2 to the display page boundaries before doing the color conversion, so the full page is converted and updated. Remove the correction for an unaligned y1 from ssd130x_update_rect(), and add a check to make sure y1 is aligned.
Fixes: a61732e808672cfa ("drm: Add driver for Solomon SSD130x OLED displays") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Acked-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220317081830.1211400-4-geert... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/ssd130x.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index caee851efd57..7c99af4ce9dd 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -355,11 +355,14 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf, unsigned int width = drm_rect_width(rect); unsigned int height = drm_rect_height(rect); unsigned int line_length = DIV_ROUND_UP(width, 8); - unsigned int pages = DIV_ROUND_UP(y % 8 + height, 8); + unsigned int pages = DIV_ROUND_UP(height, 8); + struct drm_device *drm = &ssd130x->drm; u32 array_idx = 0; int ret, i, j, k; u8 *data_array = NULL;
+ drm_WARN_ONCE(drm, y % 8 != 0, "y must be aligned to screen page\n"); + data_array = kcalloc(width, pages, GFP_KERNEL); if (!data_array) return -ENOMEM; @@ -401,13 +404,13 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, u8 *buf, if (ret < 0) goto out_free;
- for (i = y / 8; i < y / 8 + pages; i++) { + for (i = 0; i < pages; i++) { int m = 8;
/* Last page may be partial */ - if (8 * (i + 1) > ssd130x->height) + if (8 * (y / 8 + i + 1) > ssd130x->height) m = ssd130x->height % 8; - for (j = x; j < x + width; j++) { + for (j = 0; j < width; j++) { u8 data = 0;
for (k = 0; k < m; k++) { @@ -454,6 +457,10 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m int ret = 0; u8 *buf = NULL;
+ /* Align y to display page boundaries */ + rect->y1 = round_down(rect->y1, 8); + rect->y2 = min_t(unsigned int, round_up(rect->y2, 8), ssd130x->height); + buf = kcalloc(fb->width, fb->height, GFP_KERNEL); if (!buf) return -ENOMEM;
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 4442ac1af10442d6e7e824fdc226f89ed94d5b53 ]
ssd130x_clear_screen() allocates a temporary buffer sized to hold one byte per pixel, while it only needs to hold one bit per pixel.
ssd130x_fb_blit_rect() allocates a temporary buffer sized to hold one byte per pixel for the whole frame buffer, while it only needs to hold one bit per pixel for the part that is to be updated. Pass dst_pitch to drm_fb_xrgb8888_to_mono(), as we have already calculated it anyway.
Fixes: a61732e808672cfa ("drm: Add driver for Solomon SSD130x OLED displays") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Acked-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220317081830.1211400-5-geert... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/solomon/ssd130x.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 7c99af4ce9dd..38b6c2c14f53 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -440,7 +440,8 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x) .y2 = ssd130x->height, };
- buf = kcalloc(ssd130x->width, ssd130x->height, GFP_KERNEL); + buf = kcalloc(DIV_ROUND_UP(ssd130x->width, 8), ssd130x->height, + GFP_KERNEL); if (!buf) return;
@@ -454,6 +455,7 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m { struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); void *vmap = map->vaddr; /* TODO: Use mapping abstraction properly */ + unsigned int dst_pitch; int ret = 0; u8 *buf = NULL;
@@ -461,11 +463,12 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_m rect->y1 = round_down(rect->y1, 8); rect->y2 = min_t(unsigned int, round_up(rect->y2, 8), ssd130x->height);
- buf = kcalloc(fb->width, fb->height, GFP_KERNEL); + dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); + buf = kcalloc(dst_pitch, drm_rect_height(rect), GFP_KERNEL); if (!buf) return -ENOMEM;
- drm_fb_xrgb8888_to_mono(buf, 0, vmap, fb, rect); + drm_fb_xrgb8888_to_mono(buf, dst_pitch, vmap, fb, rect);
ssd130x_update_rect(ssd130x, buf, rect);
From: Chuansheng Liu chuansheng.liu@intel.com
[ Upstream commit 856082f021a28221db2c32bd0531614a8382be67 ]
Easily hit the below list corruption: == list_add corruption. prev->next should be next (ffffffffc0ceb090), but was ffffec604507edc8. (prev=ffffec604507edc8). WARNING: CPU: 65 PID: 3959 at lib/list_debug.c:26 __list_add_valid+0x53/0x80 CPU: 65 PID: 3959 Comm: fbdev Tainted: G U RIP: 0010:__list_add_valid+0x53/0x80 Call Trace: <TASK> fb_deferred_io_mkwrite+0xea/0x150 do_page_mkwrite+0x57/0xc0 do_wp_page+0x278/0x2f0 __handle_mm_fault+0xdc2/0x1590 handle_mm_fault+0xdd/0x2c0 do_user_addr_fault+0x1d3/0x650 exc_page_fault+0x77/0x180 ? asm_exc_page_fault+0x8/0x30 asm_exc_page_fault+0x1e/0x30 RIP: 0033:0x7fd98fc8fad1 ==
Figure out the race happens when one process is adding &page->lru into the pagelist tail in fb_deferred_io_mkwrite(), another process is re-initializing the same &page->lru in fb_deferred_io_fault(), which is not protected by the lock.
This fix is to init all the page lists one time during initialization, it not only fixes the list corruption, but also avoids INIT_LIST_HEAD() redundantly.
V2: change "int i" to "unsigned int i" (Geert Uytterhoeven)
Signed-off-by: Chuansheng Liu chuansheng.liu@intel.com Fixes: 105a940416fc ("fbdev/defio: Early-out if page is already enlisted") Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Thomas Zimmermann tzimmermann@suse.de Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20220318005003.51810-1-chuansh... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/core/fb_defio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 842c66b3e33d..6aaf6d0abf39 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -59,7 +59,6 @@ static vm_fault_t fb_deferred_io_fault(struct vm_fault *vmf) printk(KERN_ERR "no mapping available\n");
BUG_ON(!page->mapping); - INIT_LIST_HEAD(&page->lru); page->index = vmf->pgoff;
vmf->page = page; @@ -213,6 +212,8 @@ static void fb_deferred_io_work(struct work_struct *work) void fb_deferred_io_init(struct fb_info *info) { struct fb_deferred_io *fbdefio = info->fbdefio; + struct page *page; + unsigned int i;
BUG_ON(!fbdefio); mutex_init(&fbdefio->lock); @@ -220,6 +221,12 @@ void fb_deferred_io_init(struct fb_info *info) INIT_LIST_HEAD(&fbdefio->pagelist); if (fbdefio->delay == 0) /* set a default of 1 s */ fbdefio->delay = HZ; + + /* initialize all the page lists one time */ + for (i = 0; i < info->fix.smem_len; i += PAGE_SIZE) { + page = fb_deferred_io_page(info, i); + INIT_LIST_HEAD(&page->lru); + } } EXPORT_SYMBOL_GPL(fb_deferred_io_init);
From: Zack Rusin zackr@vmware.com
[ Upstream commit 10a26e0d5fc3574f63ce8a6cf28381b126317f40 ]
vmw_move assumed that buffers to be moved would always be vmw_buffer_object's but after introduction of new placement for mob pages that's no longer the case. The resulting invalid read didn't have any practical consequences because the memory isn't used unless the object actually is a vmw_buffer_object. Fix it by moving the cast to the spot where the results are used.
Signed-off-by: Zack Rusin zackr@vmware.com Fixes: f6be23264bba ("drm/vmwgfx: Introduce a new placement for MOB page tables") Reported-by: Chuck Lever III chuck.lever@oracle.com Reviewed-by: Martin Krastev krastevm@vmware.com Tested-by: Chuck Lever chuck.lever@oracle.com Link: https://patchwork.freedesktop.org/patch/msgid/20220318174332.440068-2-zack@k... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 708899ba2102..6542f1498651 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c @@ -859,22 +859,21 @@ void vmw_query_move_notify(struct ttm_buffer_object *bo, struct ttm_device *bdev = bo->bdev; struct vmw_private *dev_priv;
- dev_priv = container_of(bdev, struct vmw_private, bdev);
mutex_lock(&dev_priv->binding_mutex);
- dx_query_mob = container_of(bo, struct vmw_buffer_object, base); - if (!dx_query_mob || !dx_query_mob->dx_query_ctx) { - mutex_unlock(&dev_priv->binding_mutex); - return; - } - /* If BO is being moved from MOB to system memory */ if (new_mem->mem_type == TTM_PL_SYSTEM && old_mem->mem_type == VMW_PL_MOB) { struct vmw_fence_obj *fence;
+ dx_query_mob = container_of(bo, struct vmw_buffer_object, base); + if (!dx_query_mob || !dx_query_mob->dx_query_ctx) { + mutex_unlock(&dev_priv->binding_mutex); + return; + } + (void) vmw_query_readback_all(dx_query_mob); mutex_unlock(&dev_priv->binding_mutex);
@@ -888,7 +887,6 @@ void vmw_query_move_notify(struct ttm_buffer_object *bo, (void) ttm_bo_wait(bo, false, false); } else mutex_unlock(&dev_priv->binding_mutex); - }
/**
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 2db80f93869d491be57cbc2b36f30d0d3a0e5bde ]
ath11k_peer_find_by_addr states via lockdep that ab->base_lock must be held when calling that function in order to protect the list. All callers except ath11k_mac_op_unassign_vif_chanctx have that lock acquired when calling ath11k_peer_find_by_addr. That lock is also not transitively held by a path towards ath11k_mac_op_unassign_vif_chanctx. The solution is to acquire the lock when calling ath11k_peer_find_by_addr inside ath11k_mac_op_unassign_vif_chanctx.
I am currently working on a static analyser to detect missing locks and this was a reported case. I manually verified the report by looking at the code, but I do not have real hardware so this is compile tested only.
Fixes: 701e48a43e15 ("ath11k: add packet log support for QCA6390") Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220314215253.92658-1-dossche.niels@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/mac.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 58ff761393db..2c8d5f2a0517 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7114,6 +7114,7 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ath11k *ar = hw->priv; struct ath11k_base *ab = ar->ab; struct ath11k_vif *arvif = (void *)vif->drv_priv; + struct ath11k_peer *peer; int ret;
mutex_lock(&ar->conf_mutex); @@ -7125,9 +7126,13 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, WARN_ON(!arvif->is_started);
if (ab->hw_params.vdev_start_delay && - arvif->vdev_type == WMI_VDEV_TYPE_MONITOR && - ath11k_peer_find_by_addr(ab, ar->mac_addr)) - ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr); + arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_addr(ab, ar->mac_addr); + spin_unlock_bh(&ab->base_lock); + if (peer) + ath11k_peer_delete(ar, arvif->vdev_id, ar->mac_addr); + }
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) { ret = ath11k_mac_monitor_stop(ar);
From: Nicolas Belin nbelin@baylibre.com
[ Upstream commit 003a1bd6a2a55c16cb2451153533dbedb12bebec ]
Set the register page length or window length to 0x100 according to the documentation.
Fixes: 988156dc2fc9 ("drm: bridge: add it66121 driver") Signed-off-by: Nicolas Belin nbelin@baylibre.com Acked-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://patchwork.freedesktop.org/patch/msgid/20220316135733.173950-3-nbelin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ite-it66121.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 69288cf894b9..e81c106e2c2b 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -227,7 +227,7 @@ static const struct regmap_range_cfg it66121_regmap_banks[] = { .selector_mask = 0x1, .selector_shift = 0, .window_start = 0x00, - .window_len = 0x130, + .window_len = 0x100, }, };
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 3dd4834a6efe4eb3c086526e1870bb768776d86a ]
If DRM_ITE_IT6505 is y but DRM_DP_HELPER is m, building failed:
drivers/gpu/drm/bridge/ite-it6505.o: In function `it6505_i2c_remove': ite-it6505.c:(.text+0x35c): undefined reference to `drm_dp_aux_unregister' drivers/gpu/drm/bridge/ite-it6505.o: In function `it6505_dpcd_read': ite-it6505.c:(.text+0x420): undefined reference to `drm_dp_dpcd_read' drivers/gpu/drm/bridge/ite-it6505.o: In function `it6505_get_dpcd': ite-it6505.c:(.text+0x4a4): undefined reference to `drm_dp_dpcd_read' drivers/gpu/drm/bridge/ite-it6505.o: In function `it6505_dpcd_write': ite-it6505.c:(.text+0x52c): undefined reference to `drm_dp_dpcd_write'
Select DRM_DP_HELPER for DRM_ITE_IT6505 to fix this.
Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Signed-off-by: YueHaibing yuehaibing@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/20220317094724.25972-1-yuehaib... 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 2145b08f9534..becd9867f3a0 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -77,6 +77,7 @@ config DRM_DISPLAY_CONNECTOR config DRM_ITE_IT6505 tristate "ITE IT6505 DisplayPort bridge" depends on OF + select DRM_DP_HELPER select DRM_KMS_HELPER select DRM_DP_HELPER select EXTCON
From: Wenli Looi wlooi@ucalgary.ca
[ Upstream commit 9aaff3864b603408c02c629957ae8d8ff5d5a4f2 ]
The current implementation is reading the wrong eeprom type.
Fixes: d8ec2e2a63e8 ("ath9k: Add an eeprom_ops callback for retrieving the eepmisc value") Signed-off-by: Wenli Looi wlooi@ucalgary.ca 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/20220320233010.123106-5-wlooi@ucalgary.ca Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index b0a4ca3559fd..abed1effd95c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -5615,7 +5615,7 @@ unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
static u8 ar9003_get_eepmisc(struct ath_hw *ah) { - return ah->eeprom.map4k.baseEepHeader.eepMisc; + return ah->eeprom.ar9300_eep.baseEepHeader.opCapFlags.eepMisc; }
const struct eeprom_ops eep_ar9300_ops = {
From: Jani Nikula jani.nikula@intel.com
[ Upstream commit 3aefc722ff52076407203b6af9713de567993adf ]
The invalid EDID block filtering uses the number of valid EDID extensions instead of all EDID extensions for looping the extensions in the copy. This is fine, by coincidence, if all the invalid blocks are at the end of the EDID. However, it's completely broken if there are invalid extensions in the middle; the invalid blocks are included and valid blocks are excluded.
Fix it by modifying the base block after, not before, the copy.
Fixes: 14544d0937bf ("drm/edid: Only print the bad edid when aborting") Reported-by: 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/20220330170426.349248-1-jani.n... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_edid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index cc7bd58369df..c5b86414873e 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2031,9 +2031,6 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
connector_bad_edid(connector, edid, edid[0x7e] + 1);
- edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions; - edid[0x7e] = valid_extensions; - new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL); if (!new) @@ -2050,6 +2047,9 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, base += EDID_LENGTH; }
+ new[EDID_LENGTH - 1] += new[0x7e] - valid_extensions; + new[0x7e] = valid_extensions; + kfree(edid); edid = new; }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 6f5efd118efafa22139e8670a4e4b506ba757dfd ]
Add the missing destroy_workqueue() before return from anx7625_i2c_probe() in the error handling case.
Fixes: adca62ec370c ("drm/bridge: anx7625: Support reading edid through aux channel") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Hsin-Yi Wang hsinyi@chromium.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220326073326.3389347-1-yangy... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 8e1851a57638..a23e13c29a1d 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -2657,7 +2657,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, if (ret) { if (ret != -EPROBE_DEFER) DRM_DEV_ERROR(dev, "fail to parse DT : %d\n", ret); - return ret; + goto free_wq; }
if (anx7625_register_i2c_dummy_clients(platform, client) != 0) { @@ -2672,7 +2672,7 @@ static int anx7625_i2c_probe(struct i2c_client *client, pm_suspend_ignore_children(dev, true); ret = devm_add_action_or_reset(dev, anx7625_runtime_disable, dev); if (ret) - return ret; + goto free_wq;
if (!platform->pdata.low_power_mode) { anx7625_disable_pd_protocol(platform);
From: Lucas Stach l.stach@pengutronix.de
[ Upstream commit 7ed2b0dabf7a22874cb30f8878df239ef638eb53 ]
When the probe routine fails we also need to clean up the CEC adapter registered in adv7511_cec_init().
Fixes: 3b1b975003e4 ("drm: adv7511/33: add HDMI CEC support") Signed-off-by: Lucas Stach l.stach@pengutronix.de Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220321104705.2804423-1-l.sta... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 005bf18682ff..668dcefbae17 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1313,6 +1313,7 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id) adv7511_audio_exit(adv7511); drm_bridge_remove(&adv7511->bridge); err_unregister_cec: + cec_unregister_adapter(adv7511->cec_adap); i2c_unregister_device(adv7511->i2c_cec); clk_disable_unprepare(adv7511->cec_clk); err_i2c_unregister_packet:
From: Marek Vasut marex@denx.de
[ Upstream commit 2dcec57b3734029cc1adc5cb872f61e21609eed4 ]
The chip register layout has nothing to do with MIPI DCS, the registers incorrectly marked as MIPI DCS in the driver are regular chip registers often with completely different function.
Fill in the actual register names and bits from [1] and [2] and add the entire register layout, since the documentation for this chip is hard to come by.
[1] https://github.com/rockchip-linux/kernel/blob/develop-4.19/drivers/gpu/drm/b... [2] https://github.com/tdjastrzebski/ICN6211-Configurator
Acked-by: Maxime Ripard maxime@cerno.tech Fixes: ce517f18944e3 ("drm: bridge: Add Chipone ICN6211 MIPI-DSI to RGB bridge") Signed-off-by: Marek Vasut marex@denx.de Cc: Jagan Teki jagan@amarulasolutions.com Cc: Maxime Ripard maxime@cerno.tech Cc: Robert Foss robert.foss@linaro.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Zimmermann tzimmermann@suse.de To: dri-devel@lists.freedesktop.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220331150509.9838-2-marex@de... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/chipone-icn6211.c | 134 ++++++++++++++++++++--- 1 file changed, 117 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index d9b7f48b99fb..376e0f80da5c 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -15,8 +15,19 @@ #include <linux/of_device.h> #include <linux/regulator/consumer.h>
-#include <video/mipi_display.h> - +#define VENDOR_ID 0x00 +#define DEVICE_ID_H 0x01 +#define DEVICE_ID_L 0x02 +#define VERSION_ID 0x03 +#define FIRMWARE_VERSION 0x08 +#define CONFIG_FINISH 0x09 +#define PD_CTRL(n) (0x0a + ((n) & 0x3)) /* 0..3 */ +#define RST_CTRL(n) (0x0e + ((n) & 0x1)) /* 0..1 */ +#define SYS_CTRL(n) (0x10 + ((n) & 0x7)) /* 0..4 */ +#define RGB_DRV(n) (0x18 + ((n) & 0x3)) /* 0..3 */ +#define RGB_DLY(n) (0x1c + ((n) & 0x1)) /* 0..1 */ +#define RGB_TEST_CTRL 0x1e +#define ATE_PLL_EN 0x1f #define HACTIVE_LI 0x20 #define VACTIVE_LI 0x21 #define VACTIVE_HACTIVE_HI 0x22 @@ -27,6 +38,95 @@ #define VFP 0x27 #define VSYNC 0x28 #define VBP 0x29 +#define BIST_POL 0x2a +#define BIST_POL_BIST_MODE(n) (((n) & 0xf) << 4) +#define BIST_POL_BIST_GEN BIT(3) +#define BIST_POL_HSYNC_POL BIT(2) +#define BIST_POL_VSYNC_POL BIT(1) +#define BIST_POL_DE_POL BIT(0) +#define BIST_RED 0x2b +#define BIST_GREEN 0x2c +#define BIST_BLUE 0x2d +#define BIST_CHESS_X 0x2e +#define BIST_CHESS_Y 0x2f +#define BIST_CHESS_XY_H 0x30 +#define BIST_FRAME_TIME_L 0x31 +#define BIST_FRAME_TIME_H 0x32 +#define FIFO_MAX_ADDR_LOW 0x33 +#define SYNC_EVENT_DLY 0x34 +#define HSW_MIN 0x35 +#define HFP_MIN 0x36 +#define LOGIC_RST_NUM 0x37 +#define OSC_CTRL(n) (0x48 + ((n) & 0x7)) /* 0..5 */ +#define BG_CTRL 0x4e +#define LDO_PLL 0x4f +#define PLL_CTRL(n) (0x50 + ((n) & 0xf)) /* 0..15 */ +#define PLL_CTRL_6_EXTERNAL 0x90 +#define PLL_CTRL_6_MIPI_CLK 0x92 +#define PLL_CTRL_6_INTERNAL 0x93 +#define PLL_REM(n) (0x60 + ((n) & 0x3)) /* 0..2 */ +#define PLL_DIV(n) (0x63 + ((n) & 0x3)) /* 0..2 */ +#define PLL_FRAC(n) (0x66 + ((n) & 0x3)) /* 0..2 */ +#define PLL_INT(n) (0x69 + ((n) & 0x1)) /* 0..1 */ +#define PLL_REF_DIV 0x6b +#define PLL_REF_DIV_P(n) ((n) & 0xf) +#define PLL_REF_DIV_Pe BIT(4) +#define PLL_REF_DIV_S(n) (((n) & 0x7) << 5) +#define PLL_SSC_P(n) (0x6c + ((n) & 0x3)) /* 0..2 */ +#define PLL_SSC_STEP(n) (0x6f + ((n) & 0x3)) /* 0..2 */ +#define PLL_SSC_OFFSET(n) (0x72 + ((n) & 0x3)) /* 0..3 */ +#define GPIO_OEN 0x79 +#define MIPI_CFG_PW 0x7a +#define MIPI_CFG_PW_CONFIG_DSI 0xc1 +#define MIPI_CFG_PW_CONFIG_I2C 0x3e +#define GPIO_SEL(n) (0x7b + ((n) & 0x1)) /* 0..1 */ +#define IRQ_SEL 0x7d +#define DBG_SEL 0x7e +#define DBG_SIGNAL 0x7f +#define MIPI_ERR_VECTOR_L 0x80 +#define MIPI_ERR_VECTOR_H 0x81 +#define MIPI_ERR_VECTOR_EN_L 0x82 +#define MIPI_ERR_VECTOR_EN_H 0x83 +#define MIPI_MAX_SIZE_L 0x84 +#define MIPI_MAX_SIZE_H 0x85 +#define DSI_CTRL 0x86 +#define DSI_CTRL_UNKNOWN 0x28 +#define DSI_CTRL_DSI_LANES(n) ((n) & 0x3) +#define MIPI_PN_SWAP 0x87 +#define MIPI_PN_SWAP_CLK BIT(4) +#define MIPI_PN_SWAP_D(n) BIT((n) & 0x3) +#define MIPI_SOT_SYNC_BIT_(n) (0x88 + ((n) & 0x1)) /* 0..1 */ +#define MIPI_ULPS_CTRL 0x8a +#define MIPI_CLK_CHK_VAR 0x8e +#define MIPI_CLK_CHK_INI 0x8f +#define MIPI_T_TERM_EN 0x90 +#define MIPI_T_HS_SETTLE 0x91 +#define MIPI_T_TA_SURE_PRE 0x92 +#define MIPI_T_LPX_SET 0x94 +#define MIPI_T_CLK_MISS 0x95 +#define MIPI_INIT_TIME_L 0x96 +#define MIPI_INIT_TIME_H 0x97 +#define MIPI_T_CLK_TERM_EN 0x99 +#define MIPI_T_CLK_SETTLE 0x9a +#define MIPI_TO_HS_RX_L 0x9e +#define MIPI_TO_HS_RX_H 0x9f +#define MIPI_PHY_(n) (0xa0 + ((n) & 0x7)) /* 0..5 */ +#define MIPI_PD_RX 0xb0 +#define MIPI_PD_TERM 0xb1 +#define MIPI_PD_HSRX 0xb2 +#define MIPI_PD_LPTX 0xb3 +#define MIPI_PD_LPRX 0xb4 +#define MIPI_PD_CK_LANE 0xb5 +#define MIPI_FORCE_0 0xb6 +#define MIPI_RST_CTRL 0xb7 +#define MIPI_RST_NUM 0xb8 +#define MIPI_DBG_SET_(n) (0xc0 + ((n) & 0xf)) /* 0..9 */ +#define MIPI_DBG_SEL 0xe0 +#define MIPI_DBG_DATA 0xe1 +#define MIPI_ATE_TEST_SEL 0xe2 +#define MIPI_ATE_STATUS_(n) (0xe3 + ((n) & 0x1)) /* 0..1 */ +#define MIPI_ATE_STATUS_1 0xe4 +#define ICN6211_MAX_REGISTER MIPI_ATE_STATUS(1)
struct chipone { struct device *dev; @@ -64,13 +164,13 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, struct chipone *icn = bridge_to_chipone(bridge); struct drm_display_mode *mode = &icn->mode;
- ICN6211_DSI(icn, 0x7a, 0xc1); + ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI);
ICN6211_DSI(icn, HACTIVE_LI, mode->hdisplay & 0xff);
ICN6211_DSI(icn, VACTIVE_LI, mode->vdisplay & 0xff);
- /** + /* * lsb nibble: 2nd nibble of hdisplay * msb nibble: 2nd nibble of vdisplay */ @@ -93,21 +193,21 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, ICN6211_DSI(icn, VBP, mode->vtotal - mode->vsync_end);
/* dsi specific sequence */ - ICN6211_DSI(icn, MIPI_DCS_SET_TEAR_OFF, 0x80); - ICN6211_DSI(icn, MIPI_DCS_SET_ADDRESS_MODE, 0x28); - ICN6211_DSI(icn, 0xb5, 0xa0); - ICN6211_DSI(icn, 0x5c, 0xff); - ICN6211_DSI(icn, MIPI_DCS_SET_COLUMN_ADDRESS, 0x01); - ICN6211_DSI(icn, MIPI_DCS_GET_POWER_SAVE, 0x92); - ICN6211_DSI(icn, 0x6b, 0x71); - ICN6211_DSI(icn, 0x69, 0x2b); - ICN6211_DSI(icn, MIPI_DCS_ENTER_SLEEP_MODE, 0x40); - ICN6211_DSI(icn, MIPI_DCS_EXIT_SLEEP_MODE, 0x98); + ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80); + ICN6211_DSI(icn, HFP_MIN, 0x28); + ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0); + ICN6211_DSI(icn, PLL_CTRL(12), 0xff); + ICN6211_DSI(icn, BIST_POL, BIST_POL_DE_POL); + ICN6211_DSI(icn, PLL_CTRL(6), PLL_CTRL_6_MIPI_CLK); + ICN6211_DSI(icn, PLL_REF_DIV, 0x71); + ICN6211_DSI(icn, PLL_INT(0), 0x2b); + ICN6211_DSI(icn, SYS_CTRL(0), 0x40); + ICN6211_DSI(icn, SYS_CTRL(1), 0x98);
/* icn6211 specific sequence */ - ICN6211_DSI(icn, 0xb6, 0x20); - ICN6211_DSI(icn, 0x51, 0x20); - ICN6211_DSI(icn, 0x09, 0x10); + ICN6211_DSI(icn, MIPI_FORCE_0, 0x20); + ICN6211_DSI(icn, PLL_CTRL(1), 0x20); + ICN6211_DSI(icn, CONFIG_FINISH, 0x10);
usleep_range(10000, 11000); }
From: Marek Vasut marex@denx.de
[ Upstream commit c0ff7a649d62105a9308cc3ac36e52a4669d9cb4 ]
The HFP_HSW_HBP_HI register must be programmed with 2 LSbits of each Horizontal Front Porch/Sync/Back Porch. Currently the driver programs this register to 0, which breaks displays with either value above 255.
The HFP_MIN register must be set to the same value as HFP_LI, otherwise there is visible image distortion, usually in the form of missing lines at the bottom of the panel.
Fix this by correctly programming the HFP_HSW_HBP_HI and HFP_MIN registers.
Acked-by: Maxime Ripard maxime@cerno.tech Fixes: ce517f18944e3 ("drm: bridge: Add Chipone ICN6211 MIPI-DSI to RGB bridge") Signed-off-by: Marek Vasut marex@denx.de Cc: Jagan Teki jagan@amarulasolutions.com Cc: Maxime Ripard maxime@cerno.tech Cc: Robert Foss robert.foss@linaro.org Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Zimmermann tzimmermann@suse.de To: dri-devel@lists.freedesktop.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220331150509.9838-3-marex@de... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/chipone-icn6211.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c b/drivers/gpu/drm/bridge/chipone-icn6211.c index 376e0f80da5c..c871a90c0b8f 100644 --- a/drivers/gpu/drm/bridge/chipone-icn6211.c +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c @@ -35,6 +35,9 @@ #define HSYNC_LI 0x24 #define HBP_LI 0x25 #define HFP_HSW_HBP_HI 0x26 +#define HFP_HSW_HBP_HI_HFP(n) (((n) & 0x300) >> 4) +#define HFP_HSW_HBP_HI_HS(n) (((n) & 0x300) >> 6) +#define HFP_HSW_HBP_HI_HBP(n) (((n) & 0x300) >> 8) #define VFP 0x27 #define VSYNC 0x28 #define VBP 0x29 @@ -163,6 +166,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, { struct chipone *icn = bridge_to_chipone(bridge); struct drm_display_mode *mode = &icn->mode; + u16 hfp, hbp, hsync;
ICN6211_DSI(icn, MIPI_CFG_PW, MIPI_CFG_PW_CONFIG_DSI);
@@ -178,13 +182,18 @@ static void chipone_atomic_enable(struct drm_bridge *bridge, ((mode->hdisplay >> 8) & 0xf) | (((mode->vdisplay >> 8) & 0xf) << 4));
- ICN6211_DSI(icn, HFP_LI, mode->hsync_start - mode->hdisplay); + hfp = mode->hsync_start - mode->hdisplay; + hsync = mode->hsync_end - mode->hsync_start; + hbp = mode->htotal - mode->hsync_end;
- ICN6211_DSI(icn, HSYNC_LI, mode->hsync_end - mode->hsync_start); - - ICN6211_DSI(icn, HBP_LI, mode->htotal - mode->hsync_end); - - ICN6211_DSI(icn, HFP_HSW_HBP_HI, 0x00); + ICN6211_DSI(icn, HFP_LI, hfp & 0xff); + ICN6211_DSI(icn, HSYNC_LI, hsync & 0xff); + ICN6211_DSI(icn, HBP_LI, hbp & 0xff); + /* Top two bits of Horizontal Front porch/Sync/Back porch */ + ICN6211_DSI(icn, HFP_HSW_HBP_HI, + HFP_HSW_HBP_HI_HFP(hfp) | + HFP_HSW_HBP_HI_HS(hsync) | + HFP_HSW_HBP_HI_HBP(hbp));
ICN6211_DSI(icn, VFP, mode->vsync_start - mode->vdisplay);
@@ -194,7 +203,7 @@ static void chipone_atomic_enable(struct drm_bridge *bridge,
/* dsi specific sequence */ ICN6211_DSI(icn, SYNC_EVENT_DLY, 0x80); - ICN6211_DSI(icn, HFP_MIN, 0x28); + ICN6211_DSI(icn, HFP_MIN, hfp & 0xff); ICN6211_DSI(icn, MIPI_PD_CK_LANE, 0xa0); ICN6211_DSI(icn, PLL_CTRL(12), 0xff); ICN6211_DSI(icn, BIST_POL, BIST_POL_DE_POL);
From: Chuanhong Guo gch981213@gmail.com
[ Upstream commit a4f9dd55c5e1bb951db6f1dee20e62e0103f3438 ]
Read From Cache Quad IO (EBH) uses 2 dummy bytes on this chip according to page 23 of the datasheet[0].
[0]: https://www.gigadevice.com/datasheet/gd5f1gq5xexxg/
Fixes: 469b99248985 ("mtd: spinand: gigadevice: Support GD5F1GQ5UExxG") Signed-off-by: Chuanhong Guo gch981213@gmail.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220320100001.247905-2-gch981213@gmail.co... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/spi/gigadevice.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index 1dd1c5898093..da77ab20296e 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -39,6 +39,14 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f, SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
+static SPINAND_OP_VARIANTS(read_cache_variants_1gq5, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + static SPINAND_OP_VARIANTS(write_cache_variants, SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), SPINAND_PROG_LOAD(true, 0, NULL, 0)); @@ -339,7 +347,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(4, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, &write_cache_variants, &update_cache_variants), SPINAND_HAS_QE_BIT,
From: Kuldeep Singh singh.kuldeep87k@gmail.com
[ Upstream commit e23d86c49a9c78e8dbe3abff20b30812b26ab427 ]
Add minItems constraint to interconnect-names as well. The schema currently tries to match 2 names and fail for DTs with single entry.
With the change applied, below interconnect-names values are possible: ['qspi-config'], ['qspi-config', 'qspi-memory']
Fixes: 8f9c291558ea ("dt-bindings: spi: Add interconnect binding for QSPI") Signed-off-by: Kuldeep Singh singh.kuldeep87k@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220328192006.18523-1-singh.kuldeep87k@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml | 1 + 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml index 5a60fba14bba..44d08aa3fd85 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qcom-qspi.yaml @@ -49,6 +49,7 @@ properties: maxItems: 2
interconnect-names: + minItems: 1 items: - const: qspi-config - const: qspi-memory
From: Srinivasa Rao Mandadapu quic_srivasam@quicinc.com
[ Upstream commit 1a8ee4cf84187bce17c76886eb6dd9389c3b99a8 ]
Update error handling in power domain init and exit handlers, as existing handling may cause issues in device remove function. Use appropriate pm core api for power domain get and sync to avoid redundant code.
Fixes: 9e3d83c52844 ("ASoC: codecs: Add power domains support in digital macro codecs")
Signed-off-by: Srinivasa Rao Mandadapu quic_srivasam@quicinc.com Co-developed-by: Venkata Prasad Potturu quic_potturu@quicinc.com Signed-off-by: Venkata Prasad Potturu quic_potturu@quicinc.com Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/1647965937-32203-1-git-send-email-quic_srivasam@qu... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/lpass-macro-common.c | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/sound/soc/codecs/lpass-macro-common.c b/sound/soc/codecs/lpass-macro-common.c index 6cede75ed3b5..3c661fd61173 100644 --- a/sound/soc/codecs/lpass-macro-common.c +++ b/sound/soc/codecs/lpass-macro-common.c @@ -24,42 +24,45 @@ struct lpass_macro *lpass_macro_pds_init(struct device *dev) return ERR_PTR(-ENOMEM);
l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro"); - if (IS_ERR_OR_NULL(l_pds->macro_pd)) - return NULL; - - ret = pm_runtime_get_sync(l_pds->macro_pd); - if (ret < 0) { - pm_runtime_put_noidle(l_pds->macro_pd); + if (IS_ERR_OR_NULL(l_pds->macro_pd)) { + ret = PTR_ERR(l_pds->macro_pd); goto macro_err; }
+ ret = pm_runtime_resume_and_get(l_pds->macro_pd); + if (ret < 0) + goto macro_sync_err; + l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec"); - if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) + if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) { + ret = PTR_ERR(l_pds->dcodec_pd); goto dcodec_err; + }
- ret = pm_runtime_get_sync(l_pds->dcodec_pd); - if (ret < 0) { - pm_runtime_put_noidle(l_pds->dcodec_pd); + ret = pm_runtime_resume_and_get(l_pds->dcodec_pd); + if (ret < 0) goto dcodec_sync_err; - } return l_pds;
dcodec_sync_err: dev_pm_domain_detach(l_pds->dcodec_pd, false); dcodec_err: pm_runtime_put(l_pds->macro_pd); -macro_err: +macro_sync_err: dev_pm_domain_detach(l_pds->macro_pd, false); +macro_err: return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(lpass_macro_pds_init);
void lpass_macro_pds_exit(struct lpass_macro *pds) { - pm_runtime_put(pds->macro_pd); - dev_pm_domain_detach(pds->macro_pd, false); - pm_runtime_put(pds->dcodec_pd); - dev_pm_domain_detach(pds->dcodec_pd, false); + if (pds) { + pm_runtime_put(pds->macro_pd); + dev_pm_domain_detach(pds->macro_pd, false); + pm_runtime_put(pds->dcodec_pd); + dev_pm_domain_detach(pds->dcodec_pd, false); + } } EXPORT_SYMBOL_GPL(lpass_macro_pds_exit);
From: Hui Wang hui.wang@canonical.com
[ Upstream commit 9f342904216f378e88008bb0ce1ae200a4b99fe8 ]
The CS35L41_NUM_OTP_ELEM is 100, but only 99 entries are defined in the array otp_map_1/2[CS35L41_NUM_OTP_ELEM], this will trigger UBSAN to report a shift-out-of-bounds warning in the cs35l41_otp_unpack() since the last entry in the array will result in GENMASK(-1, 0).
UBSAN reports this problem: UBSAN: shift-out-of-bounds in /home/hwang4/build/jammy/jammy/sound/soc/codecs/cs35l41-lib.c:836:8 shift exponent 64 is too large for 64-bit type 'long unsigned int' CPU: 10 PID: 595 Comm: systemd-udevd Not tainted 5.15.0-23-generic #23 Hardware name: LENOVO \x02MFG_IN_GO/\x02MFG_IN_GO, BIOS N3GET19W (1.00 ) 03/11/2022 Call Trace: <TASK> show_stack+0x52/0x58 dump_stack_lvl+0x4a/0x5f dump_stack+0x10/0x12 ubsan_epilogue+0x9/0x45 __ubsan_handle_shift_out_of_bounds.cold+0x61/0xef ? regmap_unlock_mutex+0xe/0x10 cs35l41_otp_unpack.cold+0x1c6/0x2b2 [snd_soc_cs35l41_lib] cs35l41_hda_probe+0x24f/0x33a [snd_hda_scodec_cs35l41] cs35l41_hda_i2c_probe+0x65/0x90 [snd_hda_scodec_cs35l41_i2c] ? cs35l41_hda_i2c_remove+0x20/0x20 [snd_hda_scodec_cs35l41_i2c] i2c_device_probe+0x252/0x2b0
Fixes: 6450ef559056 ("ASoC: cs35l41: CS35L41 Boosted Smart Amplifier") Reviewed-by: Lucas Tanure tanureal@opensource.cirrus.com Acked-by: Charles Keepax ckeepax@opensource.cirrus.com Signed-off-by: Hui Wang hui.wang@canonical.com Link: https://lore.kernel.org/r/20220328123535.50000-2-hui.wang@canonical.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/sound/cs35l41.h | 1 - sound/soc/codecs/cs35l41-lib.c | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index bf7f9a9aeba0..9341130257ea 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -536,7 +536,6 @@
#define CS35L41_MAX_CACHE_REG 36 #define CS35L41_OTP_SIZE_WORDS 32 -#define CS35L41_NUM_OTP_ELEM 100
#define CS35L41_VALID_PDATA 0x80000000 #define CS35L41_NUM_SUPPLIES 2 diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index aa6823fbd1a4..17cf782f39af 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -422,7 +422,7 @@ static bool cs35l41_volatile_reg(struct device *dev, unsigned int reg) } }
-static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] = { +static const struct cs35l41_otp_packed_element_t otp_map_1[] = { /* addr shift size */ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ @@ -525,7 +525,7 @@ static const struct cs35l41_otp_packed_element_t otp_map_1[CS35L41_NUM_OTP_ELEM] { 0x00017044, 0, 24 }, /*LOT_NUMBER*/ };
-static const struct cs35l41_otp_packed_element_t otp_map_2[CS35L41_NUM_OTP_ELEM] = { +static const struct cs35l41_otp_packed_element_t otp_map_2[] = { /* addr shift size */ { 0x00002030, 0, 4 }, /*TRIM_OSC_FREQ_TRIM*/ { 0x00002030, 7, 1 }, /*TRIM_OSC_TRIM_DONE*/ @@ -671,35 +671,35 @@ static const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[] = { { .id = 0x01, .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_1), .bit_offset = 16, .word_offset = 2, }, { .id = 0x02, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x03, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x06, .map = otp_map_2, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_2), .bit_offset = 16, .word_offset = 2, }, { .id = 0x08, .map = otp_map_1, - .num_elements = CS35L41_NUM_OTP_ELEM, + .num_elements = ARRAY_SIZE(otp_map_1), .bit_offset = 16, .word_offset = 2, },
From: Peter Ujfalusi peter.ujfalusi@linux.intel.com
[ Upstream commit a403993ce98fb401f696da7c4f374739a7609cff ]
Since the scontrol->priv is freed up during load operation it should be set to NULL to be safe against double freeing attempt.
Fixes: b5cee8feb1d48 ("ASoC: SOF: topology: Make control parsing IPC agnostic") Signed-off-by: Peter Ujfalusi peter.ujfalusi@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/20220331114757.32551-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 af1bbd34213c..cdff48c4195f 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1605,6 +1605,7 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_ if (scontrol->priv_size > 0) { memcpy(cdata->data, scontrol->priv, scontrol->priv_size); kfree(scontrol->priv); + scontrol->priv = NULL;
if (cdata->data->magic != SOF_ABI_MAGIC) { dev_err(sdev->dev, "Wrong ABI magic 0x%08x.\n", cdata->data->magic);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 4f4e0454e226de3bf4efd7e7924d1edc571c52d5 ]
Call of_node_put(platform_node) to avoid refcount leak in the error path.
Fixes: 94319ba10eca ("ASoC: mediatek: Use platform_of_node for machine drivers") Fixes: 493433785df0 ("ASoC: mediatek: mt8173: fix device_node leak") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20220404092903.26725-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-max98090.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c index 4cb90da89262..58778cd2e61b 100644 --- a/sound/soc/mediatek/mt8173/mt8173-max98090.c +++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c @@ -167,7 +167,8 @@ static int mt8173_max98090_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) @@ -179,6 +180,8 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, card);
of_node_put(codec_node); + +put_platform_node: of_node_put(platform_node); return ret; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 05654431a18fe24e5e46a375d98904134628a102 ]
This node pointer is returned by of_parse_phandle() with refcount incremented in this function. Calling of_node_put() to avoid the refcount leak.
Fixes: 8625c1dbd876 ("ASoC: mediatek: Add mt2701-wm8960 machine driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220404093526.30004-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/mediatek/mt2701/mt2701-wm8960.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/mediatek/mt2701/mt2701-wm8960.c b/sound/soc/mediatek/mt2701/mt2701-wm8960.c index f56de1b918bf..0cdf2ae36243 100644 --- a/sound/soc/mediatek/mt2701/mt2701-wm8960.c +++ b/sound/soc/mediatek/mt2701/mt2701-wm8960.c @@ -129,7 +129,8 @@ static int mt2701_wm8960_machine_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) @@ -140,7 +141,7 @@ static int mt2701_wm8960_machine_probe(struct platform_device *pdev) ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); if (ret) { dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret); - return ret; + goto put_codec_node; }
ret = devm_snd_soc_register_card(&pdev->dev, card); @@ -148,6 +149,10 @@ static int mt2701_wm8960_machine_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", __func__, ret);
+put_codec_node: + of_node_put(codec_node); +put_platform_node: + of_node_put(platform_node); return ret; }
From: Akira Yokosawa akiyks@gmail.com
[ Upstream commit 2c2de6f2e2bc444eed65eaa949b4fdadab93f6b3 ]
Using a substitution pattern of "|copy|" without including isonum.txt causes a doc build warning.
Using the symbol "©" itself is a better choice for those who read .rst sources.
Reported by: Randy Dunlap rdunlap@infradead.org
Fixes: 16c02447f3e1 ("Documentation: thermal: DPTF Documentation") Suggested-by: Jonathan Corbet corbet@lwn.net Signed-off-by: Akira Yokosawa akiyks@gmail.com Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Cc: linux-pm@vger.kernel.org Cc: linux-doc@vger.kernel.org Acked-by: Randy Dunlap rdunlap@infradead.org Tested-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Jonathan Corbet corbet@lwn.net Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/driver-api/thermal/intel_dptf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst index 96668dca753a..372bdb4d04c6 100644 --- a/Documentation/driver-api/thermal/intel_dptf.rst +++ b/Documentation/driver-api/thermal/intel_dptf.rst @@ -4,7 +4,7 @@ Intel(R) Dynamic Platform and Thermal Framework Sysfs Interface ===============================================================
-:Copyright: |copy| 2022 Intel Corporation +:Copyright: © 2022 Intel Corporation
:Author: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com
From: Ammar Faizi ammarfaizi2@gnuweeb.org
[ Upstream commit b86eb74098a92afd789da02699b4b0dd3f73b889 ]
The asm constraint does not reflect the fact that the asm statement can modify the value of the local variable loops. Which it does.
Specifying the wrong constraint may lead to undefined behavior, it may clobber random stuff (e.g. local variable, important temporary value in regs, etc.). This is especially dangerous when the compiler decides to inline the function and since it doesn't know that the value gets modified, it might decide to use it from a register directly without reloading it.
Change the constraint to "+a" to denote that the first argument is an input and an output argument.
[ bp: Fix typo, massage commit message. ]
Fixes: e01b70ef3eb3 ("x86: fix bug in arch/i386/lib/delay.c file, delay_loop function") Signed-off-by: Ammar Faizi ammarfaizi2@gnuweeb.org Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/20220329104705.65256-2-ammarfaizi2@gnuweeb.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/lib/delay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index 65d15df6212d..0e65d00e2339 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c @@ -54,8 +54,8 @@ static void delay_loop(u64 __loops) " jnz 2b \n" "3: dec %0 \n"
- : /* we don't need output */ - :"a" (loops) + : "+a" (loops) + : ); }
From: Rex-BC Chen rex-bc.chen@mediatek.com
[ Upstream commit b74d921b900b6ce38c6247c0a1c86be9f3746493 ]
We encountered a kernel panic issue that callback data will be NULL when it's using in ovl irq handler. There is a timing issue between mtk_disp_ovl_irq_handler() and mtk_ovl_disable_vblank().
To resolve this issue, we use the flow to register/unregister vblank cb: - Register callback function and callback data when crtc creates. - Unregister callback function and callback data when crtc destroies.
With this solution, we can assure callback data will not be NULL when vblank is disable.
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220321072320.150... Fixes: 9b0704988b15 ("drm/mediatek: Register vblank callback function") Signed-off-by: Rex-BC Chen rex-bc.chen@mediatek.com Reviewed-by: jason-jh.lin jason-jh.lin@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_disp_drv.h | 16 +++++++----- drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 22 ++++++++++++---- drivers/gpu/drm/mediatek/mtk_disp_rdma.c | 20 +++++++++----- drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 14 +++++++++- drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 4 +++ drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 29 ++++++++++++++++----- 6 files changed, 80 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h index 86c3068894b1..974462831133 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -76,9 +76,11 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx, void mtk_ovl_start(struct device *dev); void mtk_ovl_stop(struct device *dev); unsigned int mtk_ovl_supported_rotations(struct device *dev); -void mtk_ovl_enable_vblank(struct device *dev, - void (*vblank_cb)(void *), - void *vblank_cb_data); +void mtk_ovl_register_vblank_cb(struct device *dev, + void (*vblank_cb)(void *), + void *vblank_cb_data); +void mtk_ovl_unregister_vblank_cb(struct device *dev); +void mtk_ovl_enable_vblank(struct device *dev); void mtk_ovl_disable_vblank(struct device *dev);
void mtk_rdma_bypass_shadow(struct device *dev); @@ -93,9 +95,11 @@ void mtk_rdma_layer_config(struct device *dev, unsigned int idx, struct cmdq_pkt *cmdq_pkt); void mtk_rdma_start(struct device *dev); void mtk_rdma_stop(struct device *dev); -void mtk_rdma_enable_vblank(struct device *dev, - void (*vblank_cb)(void *), - void *vblank_cb_data); +void mtk_rdma_register_vblank_cb(struct device *dev, + void (*vblank_cb)(void *), + void *vblank_cb_data); +void mtk_rdma_unregister_vblank_cb(struct device *dev); +void mtk_rdma_enable_vblank(struct device *dev); void mtk_rdma_disable_vblank(struct device *dev);
#endif diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c index 17cd9b932298..70ab22964f3b 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c @@ -97,14 +97,28 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; }
-void mtk_ovl_enable_vblank(struct device *dev, - void (*vblank_cb)(void *), - void *vblank_cb_data) +void mtk_ovl_register_vblank_cb(struct device *dev, + void (*vblank_cb)(void *), + void *vblank_cb_data) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
ovl->vblank_cb = vblank_cb; ovl->vblank_cb_data = vblank_cb_data; +} + +void mtk_ovl_unregister_vblank_cb(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + + ovl->vblank_cb = NULL; + ovl->vblank_cb_data = NULL; +} + +void mtk_ovl_enable_vblank(struct device *dev) +{ + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); + writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA); writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN); } @@ -113,8 +127,6 @@ void mtk_ovl_disable_vblank(struct device *dev) { struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
- ovl->vblank_cb = NULL; - ovl->vblank_cb_data = NULL; writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); }
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c index 662e91d9d45f..1be4caf9ff96 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c @@ -95,24 +95,32 @@ static void rdma_update_bits(struct device *dev, unsigned int reg, writel(tmp, rdma->regs + reg); }
-void mtk_rdma_enable_vblank(struct device *dev, - void (*vblank_cb)(void *), - void *vblank_cb_data) +void mtk_rdma_register_vblank_cb(struct device *dev, + void (*vblank_cb)(void *), + void *vblank_cb_data) { struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
rdma->vblank_cb = vblank_cb; rdma->vblank_cb_data = vblank_cb_data; - rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, - RDMA_FRAME_END_INT); }
-void mtk_rdma_disable_vblank(struct device *dev) +void mtk_rdma_unregister_vblank_cb(struct device *dev) { struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
rdma->vblank_cb = NULL; rdma->vblank_cb_data = NULL; +} + +void mtk_rdma_enable_vblank(struct device *dev) +{ + rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, + RDMA_FRAME_END_INT); +} + +void mtk_rdma_disable_vblank(struct device *dev) +{ rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0); }
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index ede435d2c1ef..f24b21eb03cd 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -152,6 +152,7 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt) static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) { struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); + int i;
mtk_mutex_put(mtk_crtc->mutex); #if IS_REACHABLE(CONFIG_MTK_CMDQ) @@ -162,6 +163,14 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc) mtk_crtc->cmdq_client.chan = NULL; } #endif + + for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { + struct mtk_ddp_comp *comp; + + comp = mtk_crtc->ddp_comp[i]; + mtk_ddp_comp_unregister_vblank_cb(comp); + } + drm_crtc_cleanup(crtc); }
@@ -617,7 +626,7 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc) struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
- mtk_ddp_comp_enable_vblank(comp, mtk_crtc_ddp_irq, &mtk_crtc->base); + mtk_ddp_comp_enable_vblank(comp);
return 0; } @@ -926,6 +935,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, if (comp->funcs->ctm_set) has_ctm = true; } + + mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq, + &mtk_crtc->base); }
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 2e99aee13dfe..5d7504a72b11 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -297,6 +297,8 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = { .config = mtk_ovl_config, .start = mtk_ovl_start, .stop = mtk_ovl_stop, + .register_vblank_cb = mtk_ovl_register_vblank_cb, + .unregister_vblank_cb = mtk_ovl_unregister_vblank_cb, .enable_vblank = mtk_ovl_enable_vblank, .disable_vblank = mtk_ovl_disable_vblank, .supported_rotations = mtk_ovl_supported_rotations, @@ -321,6 +323,8 @@ static const struct mtk_ddp_comp_funcs ddp_rdma = { .config = mtk_rdma_config, .start = mtk_rdma_start, .stop = mtk_rdma_stop, + .register_vblank_cb = mtk_rdma_register_vblank_cb, + .unregister_vblank_cb = mtk_rdma_unregister_vblank_cb, .enable_vblank = mtk_rdma_enable_vblank, .disable_vblank = mtk_rdma_disable_vblank, .layer_nr = mtk_rdma_layer_nr, diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index ad267bb8fc9b..1cbc6332282d 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -48,9 +48,11 @@ struct mtk_ddp_comp_funcs { unsigned int bpc, struct cmdq_pkt *cmdq_pkt); void (*start)(struct device *dev); void (*stop)(struct device *dev); - void (*enable_vblank)(struct device *dev, - void (*vblank_cb)(void *), - void *vblank_cb_data); + void (*register_vblank_cb)(struct device *dev, + void (*vblank_cb)(void *), + void *vblank_cb_data); + void (*unregister_vblank_cb)(struct device *dev); + void (*enable_vblank)(struct device *dev); void (*disable_vblank)(struct device *dev); unsigned int (*supported_rotations)(struct device *dev); unsigned int (*layer_nr)(struct device *dev); @@ -110,12 +112,25 @@ static inline void mtk_ddp_comp_stop(struct mtk_ddp_comp *comp) comp->funcs->stop(comp->dev); }
-static inline void mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp *comp, - void (*vblank_cb)(void *), - void *vblank_cb_data) +static inline void mtk_ddp_comp_register_vblank_cb(struct mtk_ddp_comp *comp, + void (*vblank_cb)(void *), + void *vblank_cb_data) +{ + if (comp->funcs && comp->funcs->register_vblank_cb) + comp->funcs->register_vblank_cb(comp->dev, vblank_cb, + vblank_cb_data); +} + +static inline void mtk_ddp_comp_unregister_vblank_cb(struct mtk_ddp_comp *comp) +{ + if (comp->funcs && comp->funcs->unregister_vblank_cb) + comp->funcs->unregister_vblank_cb(comp->dev); +} + +static inline void mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp *comp) { if (comp->funcs && comp->funcs->enable_vblank) - comp->funcs->enable_vblank(comp->dev, vblank_cb, vblank_cb_data); + comp->funcs->enable_vblank(comp->dev); }
static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit cfab37ff31afcd0f99f3cccbff1f8ffa11e44c00 ]
When support for MT8192 was added, the DPI device was not added to the list of components to look for. This causes the secondary display pipeline to not be able to fully bind, and the DRM driver subsequently defers probing.
Add the DPI device compatible to list of DPI components to fix this.
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220225032754.140... Fixes: 01365f549c88 ("drm/mediatek: Add support for Mediatek SoC MT8192") Signed-off-by: Chen-Yu Tsai wenst@chromium.org Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 247c6ff277ef..b0e4e5d68927 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -509,6 +509,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = { .data = (void *)MTK_DPI }, { .compatible = "mediatek,mt8183-dpi", .data = (void *)MTK_DPI }, + { .compatible = "mediatek,mt8192-dpi", + .data = (void *)MTK_DPI }, { .compatible = "mediatek,mt2701-dsi", .data = (void *)MTK_DSI }, { .compatible = "mediatek,mt8173-dsi",
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 748acfc98adab21a93ae7a1b5bed0f048463e873 ]
During a commit, the core clock, which feeds the HVS, needs to run at a minimum of 500MHz.
While doing that commit, we can also change the mode to one that requires a higher core clock, so we take the core clock rate associated to that new state into account for that boost.
However, the old state also needs to be taken into account if it requires a core clock higher that the new one and our 500MHz limit, since it's still live in hardware at the beginning of our commit.
Fixes: 16e101051f32 ("drm/vc4: Increase the core clock based on HVS load") Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: https://lore.kernel.org/r/20220331143744.777652-2-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_kms.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 24de29bc1cda..992d6a240002 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -385,9 +385,10 @@ static void vc4_atomic_commit_tail(struct drm_atomic_state *state) }
if (vc4->hvs->hvs5) { + unsigned long state_rate = max(old_hvs_state->core_clock_rate, + new_hvs_state->core_clock_rate); unsigned long core_rate = max_t(unsigned long, - 500000000, - new_hvs_state->core_clock_rate); + 500000000, state_rate);
clk_set_min_rate(hvs->core_clk, core_rate); }
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit b51cd7ad143d2eb31a6df81c2183128920e47c2b ]
In order to get the field currently being output, the driver has been using the display FIFO frame count in the HVS, reading a 6-bit field at the offset 12 in the DISPSTATx register.
While that field is indeed at that location for the FIFO 1 and 2, the one for the FIFO0 is actually in the DISPSTAT1 register, at the offset 18.
Fixes: e538092cb15c ("drm/vc4: Enable precise vblank timestamping for interlaced modes.") Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: https://lore.kernel.org/r/20220331143744.777652-3-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_crtc.c | 2 +- drivers/gpu/drm/vc4/vc4_drv.h | 1 + drivers/gpu/drm/vc4/vc4_hvs.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/vc4/vc4_regs.h | 12 ++++++++++-- 4 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 783890e8d43a..477b3c5ad089 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -123,7 +123,7 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc *crtc, *vpos /= 2;
/* Use hpos to correct for field offset in interlaced mode. */ - if (VC4_GET_FIELD(val, SCALER_DISPSTATX_FRAME_COUNT) % 2) + if (vc4_hvs_get_fifo_frame_count(dev, vc4_crtc_state->assigned_channel) % 2) *hpos += mode->crtc_htotal / 2; }
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 4329e09d357c..801da3e8ebdb 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -935,6 +935,7 @@ void vc4_irq_reset(struct drm_device *dev); extern struct platform_driver vc4_hvs_driver; void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output); int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output); +u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo); int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state); void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state); void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state); diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 604933e20e6a..c8cae10500b9 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -197,6 +197,29 @@ static void vc4_hvs_update_gamma_lut(struct drm_crtc *crtc) vc4_hvs_lut_load(crtc); }
+u8 vc4_hvs_get_fifo_frame_count(struct drm_device *dev, unsigned int fifo) +{ + struct vc4_dev *vc4 = to_vc4_dev(dev); + u8 field = 0; + + switch (fifo) { + case 0: + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT1), + SCALER_DISPSTAT1_FRCNT0); + break; + case 1: + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT1), + SCALER_DISPSTAT1_FRCNT1); + break; + case 2: + field = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTAT2), + SCALER_DISPSTAT2_FRCNT2); + break; + } + + return field; +} + int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output) { struct vc4_dev *vc4 = to_vc4_dev(dev); diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index 33410718089e..bae8c9cd6f7c 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h @@ -379,8 +379,6 @@ # define SCALER_DISPSTATX_MODE_EOF 3 # define SCALER_DISPSTATX_FULL BIT(29) # define SCALER_DISPSTATX_EMPTY BIT(28) -# define SCALER_DISPSTATX_FRAME_COUNT_MASK VC4_MASK(17, 12) -# define SCALER_DISPSTATX_FRAME_COUNT_SHIFT 12 # define SCALER_DISPSTATX_LINE_MASK VC4_MASK(11, 0) # define SCALER_DISPSTATX_LINE_SHIFT 0
@@ -403,9 +401,15 @@ (x) * (SCALER_DISPBKGND1 - \ SCALER_DISPBKGND0)) #define SCALER_DISPSTAT1 0x00000058 +# define SCALER_DISPSTAT1_FRCNT0_MASK VC4_MASK(23, 18) +# define SCALER_DISPSTAT1_FRCNT0_SHIFT 18 +# define SCALER_DISPSTAT1_FRCNT1_MASK VC4_MASK(17, 12) +# define SCALER_DISPSTAT1_FRCNT1_SHIFT 12 + #define SCALER_DISPSTATX(x) (SCALER_DISPSTAT0 + \ (x) * (SCALER_DISPSTAT1 - \ SCALER_DISPSTAT0)) + #define SCALER_DISPBASE1 0x0000005c #define SCALER_DISPBASEX(x) (SCALER_DISPBASE0 + \ (x) * (SCALER_DISPBASE1 - \ @@ -415,7 +419,11 @@ (x) * (SCALER_DISPCTRL1 - \ SCALER_DISPCTRL0)) #define SCALER_DISPBKGND2 0x00000064 + #define SCALER_DISPSTAT2 0x00000068 +# define SCALER_DISPSTAT2_FRCNT2_MASK VC4_MASK(17, 12) +# define SCALER_DISPSTAT2_FRCNT2_SHIFT 12 + #define SCALER_DISPBASE2 0x0000006c #define SCALER_DISPALPHA2 0x00000070 #define SCALER_GAMADDR 0x00000078
From: Miles Chen miles.chen@mediatek.com
[ Upstream commit 2c5d69b0a141e1e98febe3111e6f4fd8420493a5 ]
In current implementation, mtk_cec_mask() writes val into target register and ignores the mask. After talking to our hdmi experts, mtk_cec_mask() should read a register, clean only mask bits, and update (val | mask) bits to the register.
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220315232301.243... Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support") Signed-off-by: Miles Chen miles.chen@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Cc: Zhiqiang Lin zhiqiang.lin@mediatek.com Cc: CK Hu ck.hu@mediatek.com Cc: Matthias Brugger matthias.bgg@gmail.com Cc: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Chun-Kuang Hu chunkuang.hu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/mediatek/mtk_cec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c index e9cef5c0c8f7..cdfa648910b2 100644 --- a/drivers/gpu/drm/mediatek/mtk_cec.c +++ b/drivers/gpu/drm/mediatek/mtk_cec.c @@ -85,7 +85,7 @@ static void mtk_cec_mask(struct mtk_cec *cec, unsigned int offset, u32 tmp = readl(cec->regs + offset) & ~mask;
tmp |= val & mask; - writel(val, cec->regs + offset); + writel(tmp, cec->regs + offset); }
void mtk_cec_set_hpd_event(struct device *dev,
From: Yongqiang Sun yongqiang.sun@amd.com
[ Upstream commit 49aa98ca30cd186ab33fc5802066e2024d3bfa39 ]
driver loading failed on VEGA10 SRIOV VF with linux host due to a wide range of stolen reserved vram. Since VEGA10 SRIOV VF need to reserve vram for firmware with windows Hyper_V host specifically, check hypervisor type to only reserve memory for it, and the range of the reserved vram can be limited to between 5M-7M area.
Fixes: faad5ccac1eaae ("drm/amdgpu: Add stolen reserved memory for MI25 SRIOV.") Signed-off-by: Yongqiang Sun yongqiang.sun@amd.com Acked-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/amdgpu_gmc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index a66a0881a934..3e9582c245bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -25,6 +25,7 @@ */
#include <linux/io-64-nonatomic-lo-hi.h> +#include <asm/hypervisor.h>
#include "amdgpu.h" #include "amdgpu_gmc.h" @@ -647,11 +648,11 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev) case CHIP_VEGA10: adev->mman.keep_stolen_vga_memory = true; /* - * VEGA10 SRIOV VF needs some firmware reserved area. + * VEGA10 SRIOV VF with MS_HYPERV host needs some firmware reserved area. */ - if (amdgpu_sriov_vf(adev)) { - adev->mman.stolen_reserved_offset = 0x100000; - adev->mman.stolen_reserved_size = 0x600000; + if (amdgpu_sriov_vf(adev) && hypervisor_is_type(X86_HYPER_MS_HYPERV)) { + adev->mman.stolen_reserved_offset = 0x500000; + adev->mman.stolen_reserved_size = 0x200000; } break; case CHIP_RAVEN:
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 8514e6b1f40319e31ac4aa3fbf606796786366c9 ]
By default, the HVS driver will force the HVS output 3 to be muxed to the HVS channel 2. However, the Transposer can only be assigned to the HVS channel 2, so whenever we try to use the writeback connector, we'll mux its associated output (Output 2) to the channel 2.
This leads to both the output 2 and 3 feeding from the same channel, which is explicitly discouraged in the documentation.
In order to avoid this, let's reset all the output muxes to their reset value.
Fixes: 87ebcd42fb7b ("drm/vc4: crtc: Assign output to channel automatically") Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: https://lore.kernel.org/r/20220328153659.2382206-2-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_hvs.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index c8cae10500b9..9d88bfb50c9b 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -605,6 +605,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) struct vc4_hvs *hvs = NULL; int ret; u32 dispctrl; + u32 reg;
hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL); if (!hvs) @@ -676,6 +677,26 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
vc4->hvs = hvs;
+ reg = HVS_READ(SCALER_DISPECTRL); + reg &= ~SCALER_DISPECTRL_DSP2_MUX_MASK; + HVS_WRITE(SCALER_DISPECTRL, + reg | VC4_SET_FIELD(0, SCALER_DISPECTRL_DSP2_MUX)); + + reg = HVS_READ(SCALER_DISPCTRL); + reg &= ~SCALER_DISPCTRL_DSP3_MUX_MASK; + HVS_WRITE(SCALER_DISPCTRL, + reg | VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX)); + + reg = HVS_READ(SCALER_DISPEOLN); + reg &= ~SCALER_DISPEOLN_DSP4_MUX_MASK; + HVS_WRITE(SCALER_DISPEOLN, + reg | VC4_SET_FIELD(3, SCALER_DISPEOLN_DSP4_MUX)); + + reg = HVS_READ(SCALER_DISPDITHER); + reg &= ~SCALER_DISPDITHER_DSP5_MUX_MASK; + HVS_WRITE(SCALER_DISPDITHER, + reg | VC4_SET_FIELD(3, SCALER_DISPDITHER_DSP5_MUX)); + dispctrl = HVS_READ(SCALER_DISPCTRL);
dispctrl |= SCALER_DISPCTRL_ENABLE; @@ -683,10 +704,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) SCALER_DISPCTRL_DISPEIRQ(1) | SCALER_DISPCTRL_DISPEIRQ(2);
- /* Set DSP3 (PV1) to use HVS channel 2, which would otherwise - * be unused. - */ - dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK; dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ | SCALER_DISPCTRL_SLVWREIRQ | SCALER_DISPCTRL_SLVRDEIRQ | @@ -700,7 +717,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) SCALER_DISPCTRL_DSPEISLUR(1) | SCALER_DISPCTRL_DSPEISLUR(2) | SCALER_DISPCTRL_SCLEIRQ); - dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
HVS_WRITE(SCALER_DISPCTRL, dispctrl);
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 234998df929f14d00cbf2f1e81a7facb69fd9266 ]
The TXP_VSTART_AT_EOF will generate a second VSTART signal to the HVS. However, the HVS waits for VSTART to enable the FIFO and will thus start filling the FIFO before the start of the frame.
This leads to corruption at the beginning of the first frame, and content from the previous frame at the beginning of the next frames.
Since one VSTART is enough, let's get rid of it.
Fixes: 008095e065a8 ("drm/vc4: Add support for the transposer block") Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: https://lore.kernel.org/r/20220328153659.2382206-3-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_txp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index 9809ca3e2945..ace2d03649ba 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -298,7 +298,7 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn, if (WARN_ON(i == ARRAY_SIZE(drm_fmts))) return;
- ctrl = TXP_GO | TXP_VSTART_AT_EOF | TXP_EI | + ctrl = TXP_GO | TXP_EI | VC4_SET_FIELD(0xf, TXP_BYTE_ENABLE) | VC4_SET_FIELD(txp_fmts[i], TXP_FORMAT);
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 5453343a88ede8b12812fced81ecd24cb888ccc3 ]
If we use a format that has padding instead of the alpha component (such as XRGB8888), it appears that the Transposer will fill the padding to 0, disregarding what was stored in the input buffer padding.
This leads to issues with IGT, since it will set the padding to 0xff, but will then compare the CRC of the two frames which will thus fail. Another nice side effect is that it is now possible to just use the buffer as ARGB.
Fixes: 008095e065a8 ("drm/vc4: Add support for the transposer block") Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Thomas Zimmermann tzimmermann@suse.de Link: https://lore.kernel.org/r/20220328153659.2382206-4-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/vc4/vc4_txp.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index ace2d03649ba..82beb8c159f2 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -304,6 +304,12 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
if (fb->format->has_alpha) ctrl |= TXP_ALPHA_ENABLE; + else + /* + * If TXP_ALPHA_ENABLE isn't set and TXP_ALPHA_INVERT is, the + * hardware will force the output padding to be 0xff. + */ + ctrl |= TXP_ALPHA_INVERT;
gem = drm_fb_cma_get_gem_obj(fb, 0); TXP_WRITE(TXP_DST_PTR, gem->paddr + fb->offsets[0]);
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit e89d57d938c8fa80c457982154ed6110804814fe ]
During BPF static linking, all the ELF relocations and .BTF.ext information (including CO-RE relocations) are preserved for __weak subprograms that were logically overriden by either previous weak subprogram instance or by corresponding "strong" (non-weak) subprogram. This is just how native user-space linkers work, nothing new.
But libbpf is over-zealous when processing CO-RE relocation to error out when CO-RE relocation belonging to such eliminated weak subprogram is encountered. Instead of erroring out on this expected situation, log debug-level message and skip the relocation.
Fixes: db2b8b06423c ("libbpf: Support CO-RE relocations for multi-prog sections") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220408181425.2287230-2-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index dabf9a1451c3..7af6805a863d 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -5665,10 +5665,17 @@ bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path) insn_idx = rec->insn_off / BPF_INSN_SZ; prog = find_prog_by_sec_insn(obj, sec_idx, insn_idx); if (!prog) { - pr_warn("sec '%s': failed to find program at insn #%d for CO-RE offset relocation #%d\n", - sec_name, insn_idx, i); - err = -EINVAL; - goto out; + /* When __weak subprog is "overridden" by another instance + * of the subprog from a different object file, linker still + * appends all the .BTF.ext info that used to belong to that + * eliminated subprogram. + * This is similar to what x86-64 linker does for relocations. + * So just ignore such relocations just like we ignore + * subprog instructions when discovering subprograms. + */ + pr_debug("sec '%s': skipping CO-RE relocation #%d for insn #%d belonging to eliminated weak subprogram\n", + sec_name, i, insn_idx); + continue; } /* no need to apply CO-RE relocation if the program is * not going to be loaded
From: Maciej W. Rozycki macro@orcam.me.uk
[ Upstream commit 4969e223b109754c2340a26bba9b1cf44f0cba9b ]
Fix an issue with commit 1ce849c75534 ("x86/PCI: Add support for the ALi M1487 (IBC) PIRQ router") and correct ALi M1487 (IBC) PIRQ router link value (`pirq' cookie) interpretation according to findings in the BIOS.
Credit to Nikolai Zhubr for the detective work as to the bit layout.
Fixes: 1ce849c75534 ("x86/PCI: Add support for the ALi M1487 (IBC) PIRQ router") Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Signed-off-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203310013270.44113@angie.orcam.me... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/pci/irq.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 97b63e35e152..21c4bc41741f 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -253,6 +253,15 @@ static void write_pc_conf_nybble(u8 base, u8 index, u8 val) pc_conf_set(reg, x); }
+/* + * FinALi pirq rules are as follows: + * + * - bit 0 selects between INTx Routing Table Mapping Registers, + * + * - bit 3 selects the nibble within the INTx Routing Table Mapping Register, + * + * - bits 7:4 map to bits 3:0 of the PCI INTx Sensitivity Register. + */ static int pirq_finali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { @@ -260,11 +269,13 @@ static int pirq_finali_get(struct pci_dev *router, struct pci_dev *dev, 0, 9, 3, 10, 4, 5, 7, 6, 0, 11, 0, 12, 0, 14, 0, 15 }; unsigned long flags; + u8 index; u8 x;
+ index = (pirq & 1) << 1 | (pirq & 8) >> 3; raw_spin_lock_irqsave(&pc_conf_lock, flags); pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY); - x = irqmap[read_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, pirq - 1)]; + x = irqmap[read_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, index)]; pc_conf_set(PC_CONF_FINALI_LOCK, 0); raw_spin_unlock_irqrestore(&pc_conf_lock, flags); return x; @@ -278,13 +289,15 @@ static int pirq_finali_set(struct pci_dev *router, struct pci_dev *dev, }; u8 val = irqmap[irq]; unsigned long flags; + u8 index;
if (!val) return 0;
+ index = (pirq & 1) << 1 | (pirq & 8) >> 3; raw_spin_lock_irqsave(&pc_conf_lock, flags); pc_conf_set(PC_CONF_FINALI_LOCK, PC_CONF_FINALI_LOCK_KEY); - write_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, pirq - 1, val); + write_pc_conf_nybble(PC_CONF_FINALI_PCI_INTX_RT1, index, val); pc_conf_set(PC_CONF_FINALI_LOCK, 0); raw_spin_unlock_irqrestore(&pc_conf_lock, flags); return 1; @@ -293,7 +306,7 @@ static int pirq_finali_set(struct pci_dev *router, struct pci_dev *dev, static int pirq_finali_lvl(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - u8 mask = ~(1u << (pirq - 1)); + u8 mask = ~((pirq & 0xf0u) >> 4); unsigned long flags; u8 trig;
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 65a569b03ca832ebc93ce45a7466137e2bb62254 ]
The mptcp release callback checks several flags in atomic context, but only MPTCP_CLEAN_UNA can be up frequently.
Reorganize the code to avoid multiple conditionals in the most common scenarios.
Additional clarify a related comment.
Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Mat Martineau mathew.j.martineau@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/protocol.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 0cbea3b6d0a4..2a9335ce5df1 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3092,15 +3092,17 @@ static void mptcp_release_cb(struct sock *sk) spin_lock_bh(&sk->sk_lock.slock); }
- /* be sure to set the current sk state before tacking actions - * depending on sk_state - */ - if (__test_and_clear_bit(MPTCP_CONNECTED, &msk->cb_flags)) - __mptcp_set_connected(sk); if (__test_and_clear_bit(MPTCP_CLEAN_UNA, &msk->cb_flags)) __mptcp_clean_una_wakeup(sk); - if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) - __mptcp_error_report(sk); + if (unlikely(&msk->cb_flags)) { + /* be sure to set the current sk state before tacking actions + * depending on sk_state, that is processing MPTCP_ERROR_REPORT + */ + if (__test_and_clear_bit(MPTCP_CONNECTED, &msk->cb_flags)) + __mptcp_set_connected(sk); + if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) + __mptcp_error_report(sk); + }
__mptcp_update_rmem(sk); }
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 43f5b111d1ff16161ce60e19aeddb999cb6f0b01 ]
When an incoming MP_PRIO option changes the backup status of any subflow, we need to reset the packet scheduler status, or the next send could keep using the previously selected subflow, without taking in account the new priorities.
Reported-by: Davide Caratti dcaratti@redhat.com Fixes: 40453a5c61f4 ("mptcp: add the incoming MP_PRIO support") Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Mat Martineau mathew.j.martineau@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/pm.c | 19 +++++++++++++++---- net/mptcp/protocol.c | 2 ++ net/mptcp/protocol.h | 1 + 3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index aa51b100e033..4d6a61acc487 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -261,14 +261,25 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, spin_unlock_bh(&pm->lock); }
-void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup) +void mptcp_pm_mp_prio_received(struct sock *ssk, u8 bkup) { - struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); + struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + struct sock *sk = subflow->conn; + struct mptcp_sock *msk;
pr_debug("subflow->backup=%d, bkup=%d\n", subflow->backup, bkup); - subflow->backup = bkup; + msk = mptcp_sk(sk); + if (subflow->backup != bkup) { + subflow->backup = bkup; + mptcp_data_lock(sk); + if (!sock_owned_by_user(sk)) + msk->last_snd = NULL; + else + __set_bit(MPTCP_RESET_SCHEDULER, &msk->cb_flags); + mptcp_data_unlock(sk); + }
- mptcp_event(MPTCP_EVENT_SUB_PRIORITY, mptcp_sk(subflow->conn), sk, GFP_ATOMIC); + mptcp_event(MPTCP_EVENT_SUB_PRIORITY, msk, ssk, GFP_ATOMIC); }
void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 2a9335ce5df1..8f54293c1d88 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -3102,6 +3102,8 @@ static void mptcp_release_cb(struct sock *sk) __mptcp_set_connected(sk); if (__test_and_clear_bit(MPTCP_ERROR_REPORT, &msk->cb_flags)) __mptcp_error_report(sk); + if (__test_and_clear_bit(MPTCP_RESET_SCHEDULER, &msk->cb_flags)) + msk->last_snd = NULL; }
__mptcp_update_rmem(sk); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 5655a63aa6a8..9ac63fa4866e 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -124,6 +124,7 @@ #define MPTCP_RETRANSMIT 4 #define MPTCP_FLUSH_JOIN_LIST 5 #define MPTCP_CONNECTED 6 +#define MPTCP_RESET_SCHEDULER 7
static inline bool before64(__u64 seq1, __u64 seq2) {
From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 0e203c324752e13d22624ab7ffafe934fa06ab50 ]
Similar to the previous patch, for priority changes requested by the local PM.
Reported-and-suggested-by: Davide Caratti dcaratti@redhat.com Fixes: 067065422fcd ("mptcp: add the outgoing MP_PRIO support") Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Mat Martineau mathew.j.martineau@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/pm_netlink.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index b5e8de6f7507..e3dcc5501579 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -727,6 +727,8 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, if (!addresses_equal(&local, addr, addr->port)) continue;
+ if (subflow->backup != bkup) + msk->last_snd = NULL; subflow->backup = bkup; subflow->send_mp_prio = 1; subflow->request_bkup = bkup;
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit a75971bc2b8453630e9f85e0beaa4da8db8277a3 ]
There's no real reason not to send the SSID to userspace when it requests information about P2P_GO, it is, in that respect, exactly the same as AP interfaces. Fix that.
Fixes: 44905265bc15 ("nl80211: don't expose wdev->ssid for most interfaces") Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20220318134656.14354ae223f0.Ia25e85a512281b92e1645... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/nl80211.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1a3551b6d18b..02a29052e41d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3719,6 +3719,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag wdev_lock(wdev); 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)) goto nla_put_failure_locked;
From: Zhou Qingyang zhou1615@umn.edu
[ Upstream commit f5e284bb74ab296f98122673c7ecd22028b2c200 ]
In komeda_plane_add(), komeda_get_layer_fourcc_list() is assigned to formats and used in drm_universal_plane_init(). drm_universal_plane_init() passes formats to __drm_universal_plane_init(). __drm_universal_plane_init() further passes formats to memcpy() as src parameter, which could lead to an undefined behavior bug on failure of komeda_get_layer_fourcc_list().
Fix this bug by adding a check of formats.
This bug was found by a static analyzer. The analysis employs differential checking to identify inconsistent security operations (e.g., checks or kfrees) between two code paths and confirms that the inconsistent operations are not recovered in the current function or the callers, so they constitute bugs.
Note that, as a bug found by static analysis, it can be a false positive or hard to trigger. Multiple researchers have cross-reviewed the bug.
Builds with CONFIG_DRM_KOMEDA=m show no new warnings, and our static analyzer no longer warns about this code.
Fixes: 61f1c4a8ab75 ("drm/komeda: Attach komeda_dev to DRM-KMS") Signed-off-by: Zhou Qingyang zhou1615@umn.edu Signed-off-by: Liviu Dudau liviu.dudau@arm.com Link: https://lore.kernel.org/dri-devel/20211201033704.32054-1-zhou1615@umn.edu Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/display/komeda/komeda_plane.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index d646e3ae1a23..517b94c3bcaf 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -265,6 +265,10 @@ static int komeda_plane_add(struct komeda_kms_dev *kms,
formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, layer->layer_type, &n_formats); + if (!formats) { + kfree(kplane); + return -ENOMEM; + }
err = drm_universal_plane_init(&kms->base, plane, get_possible_crtcs(kms, c->pipeline),
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit 73c3ed7495c67b8fbdc31cf58e6ca8757df31a33 ]
The return value of kzalloc() needs to be checked. To avoid use of null pointer '&state->base' in case of the failure of alloc.
Fixes: 99665d072183 ("drm: mali-dp: add malidp_crtc_state struct") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Reviewed-by: Brian Starkey brian.starkey@arm.com Signed-off-by: Liviu Dudau liviu.dudau@arm.com Link: https://patchwork.freedesktop.org/patch/msgid/20211214100837.46912-1-jiashen... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/arm/malidp_crtc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index 494075ddbef6..b5928b52e279 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -487,7 +487,10 @@ static void malidp_crtc_reset(struct drm_crtc *crtc) if (crtc->state) malidp_crtc_destroy_state(crtc, crtc->state);
- __drm_atomic_helper_crtc_reset(crtc, &state->base); + if (state) + __drm_atomic_helper_crtc_reset(crtc, &state->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); }
static int malidp_crtc_enable_vblank(struct drm_crtc *crtc)
From: Yongqiang Sun yongqiang.sun@amd.com
[ Upstream commit d9e50239a9611b9a1759e007e9a810c8d178da28 ]
Add CONFIG_X86 check to fix the build error.
Fixes: 49aa98ca30cd18 ("drm/amd/amdgpu: Only reserve vram for firmware with vega9 MS_HYPERV host.") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Yongqiang Sun yongqiang.sun@amd.com Acked-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/amdgpu_gmc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 3e9582c245bb..88b852b3a2cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -25,7 +25,9 @@ */
#include <linux/io-64-nonatomic-lo-hi.h> +#ifdef CONFIG_X86 #include <asm/hypervisor.h> +#endif
#include "amdgpu.h" #include "amdgpu_gmc.h" @@ -650,10 +652,12 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev) /* * VEGA10 SRIOV VF with MS_HYPERV host needs some firmware reserved area. */ +#ifdef CONFIG_X86 if (amdgpu_sriov_vf(adev) && hypervisor_is_type(X86_HYPER_MS_HYPERV)) { adev->mman.stolen_reserved_offset = 0x500000; adev->mman.stolen_reserved_size = 0x200000; } +#endif break; case CHIP_RAVEN: case CHIP_RENOIR:
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 8b1ea69a63eb62f97cef63e6d816b64ed84e8760 ]
wait_for_completion_timeout() returns unsigned long not int. It returns 0 if timed out, and positive if completed. The check for <= 0 is ambiguous and should be == 0 here indicating timeout which is the only error case.
Fixes: 5720ec0a6d26 ("spi: spi-ti-qspi: Add DMA support for QSPI mmap read") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220411111034.24447-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-ti-qspi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index e06aafe169e0..081da1fd3fd7 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c @@ -448,6 +448,7 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst, enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; struct dma_async_tx_descriptor *tx; int ret; + unsigned long time_left;
tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags); if (!tx) { @@ -467,9 +468,9 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst, }
dma_async_issue_pending(chan); - ret = wait_for_completion_timeout(&qspi->transfer_complete, + time_left = wait_for_completion_timeout(&qspi->transfer_complete, msecs_to_jiffies(len)); - if (ret <= 0) { + if (time_left == 0) { dmaengine_terminate_sync(chan); dev_err(qspi->dev, "DMA wait_for_completion_timeout\n"); return -ETIMEDOUT;
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit 8106bddbab5f0ba180e6d693c7c1fc6926d57caa ]
The scftorture test module's scf_handler() function is supposed to provide three different distributions of short delays (including "no delay") and one distribution of long delays, if specified by the scftorture.longwait module parameter. However, the second of the two non-zero-wait short delays is disabled due to the first such delay's "goto out" not being enclosed in the "then" clause with the "udelay()".
This commit therefore adjusts the code to provide the intended set of delays.
Fixes: e9d338a0b179 ("scftorture: Add smp_call_function() torture test") Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/scftorture.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/scftorture.c b/kernel/scftorture.c index dcb0410950e4..5d113aa59e77 100644 --- a/kernel/scftorture.c +++ b/kernel/scftorture.c @@ -267,9 +267,10 @@ static void scf_handler(void *scfc_in) } this_cpu_inc(scf_invoked_count); if (longwait <= 0) { - if (!(r & 0xffc0)) + if (!(r & 0xffc0)) { udelay(r & 0x3f); - goto out; + goto out; + } } if (r & 0xfff) goto out;
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit bfa323c659b1016c8e896920ba08cd6914cc3b0c ]
If PHYLINK is n, build fails:
drivers/net/ethernet/ti/am65-cpsw-ethtool.o: In function `am65_cpsw_set_link_ksettings': am65-cpsw-ethtool.c:(.text+0x118): undefined reference to `phylink_ethtool_ksettings_set' drivers/net/ethernet/ti/am65-cpsw-ethtool.o: In function `am65_cpsw_get_link_ksettings': am65-cpsw-ethtool.c:(.text+0x138): undefined reference to `phylink_ethtool_ksettings_get' drivers/net/ethernet/ti/am65-cpsw-ethtool.o: In function `am65_cpsw_set_eee': am65-cpsw-ethtool.c:(.text+0x158): undefined reference to `phylink_ethtool_set_eee'
Select PHYLINK for TI_K3_AM65_CPSW_NUSS to fix this.
Fixes: e8609e69470f ("net: ethernet: ti: am65-cpsw: Convert to PHYLINK") Signed-off-by: YueHaibing yuehaibing@huawei.com Reviewed-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://lore.kernel.org/r/20220409105931.9080-1-yuehaibing@huawei.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ti/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index affcf92cd3aa..fb30bc5d56cb 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig @@ -94,6 +94,7 @@ config TI_K3_AM65_CPSW_NUSS depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER select NET_DEVLINK select TI_DAVINCI_MDIO + select PHYLINK imply PHY_TI_GMII_SEL depends on TI_K3_AM65_CPTS || !TI_K3_AM65_CPTS help
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
[ Upstream commit 66f862563ed68717dfd84e808ca12705ed275ced ]
When using an external PHY connected using RGMII to mt7531 port 5, the PHY can be used to used support 1000BASE-X connections. Moreover, if 1000BASE-T is supported, then we should allow 1000BASE-X as well, since which are supported is a property of the PHY.
Therefore, it makes no sense to exclude this from the linkmodes when 1000BASE-T is supported.
Fixes: c288575f7810 ("net: dsa: mt7530: Add the support of MT7531 switch") Tested-by: Marek Behún kabel@kernel.org Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mt7530.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index fe3cb26f4287..831ccbecb0c2 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -2540,13 +2540,7 @@ static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port, /* Port5 supports ethier RGMII or SGMII. * Port6 supports SGMII only. */ - switch (port) { - case 5: - if (mt7531_is_rgmii_port(priv, port)) - break; - fallthrough; - case 6: - phylink_set(supported, 1000baseX_Full); + if (port == 6) { phylink_set(supported, 2500baseX_Full); phylink_set(supported, 2500baseT_Full); } @@ -2914,8 +2908,6 @@ static void mt7530_mac_port_validate(struct dsa_switch *ds, int port, unsigned long *supported) { - if (port == 5) - phylink_set(supported, 1000baseX_Full); }
static void mt7531_mac_port_validate(struct dsa_switch *ds, int port, @@ -2952,8 +2944,10 @@ mt753x_phylink_validate(struct dsa_switch *ds, int port, }
/* This switch only supports 1G full-duplex. */ - if (state->interface != PHY_INTERFACE_MODE_MII) + if (state->interface != PHY_INTERFACE_MODE_MII) { phylink_set(mask, 1000baseT_Full); + phylink_set(mask, 1000baseX_Full); + }
priv->info->mac_port_validate(ds, port, mask);
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit f45ba67eb74ab4b775616af731bdf8944afce3f1 ]
platform_get_irq() return negative value on failure, so null check of return value is incorrect. Fix it by comparing whether it is less than zero.
Fixes: 9055a2f59162 ("ixp4xx_eth: make ptp support a platform driver") Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20220412085126.2532924-1-lv.ruyi@zte.com.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/xscale/ptp_ixp46x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c index 1f382777aa5a..9abbdb71e629 100644 --- a/drivers/net/ethernet/xscale/ptp_ixp46x.c +++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c @@ -271,7 +271,7 @@ static int ptp_ixp_probe(struct platform_device *pdev) ixp_clock.master_irq = platform_get_irq(pdev, 0); ixp_clock.slave_irq = platform_get_irq(pdev, 1); if (IS_ERR(ixp_clock.regs) || - !ixp_clock.master_irq || !ixp_clock.slave_irq) + ixp_clock.master_irq < 0 || ixp_clock.slave_irq < 0) return -ENXIO;
ixp_clock.caps = ptp_ixp_caps;
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 1b0e81416a24d6e9b8c2341e22e8bf48f8b8bfc9 ]
Commit 3e3b5dfcd16a ("NFC: reorder the logic in nfc_{un,}register_device") assumes the device_is_registered() in function nfc_dev_up() will help to check when the rfkill is unregistered. However, this check only take effect when device_del(&dev->dev) is done in nfc_unregister_device(). Hence, the rfkill object is still possible be dereferenced.
The crash trace in latest kernel (5.18-rc2):
[ 68.760105] ================================================================== [ 68.760330] BUG: KASAN: use-after-free in __lock_acquire+0x3ec1/0x6750 [ 68.760756] Read of size 8 at addr ffff888009c93018 by task fuzz/313 [ 68.760756] [ 68.760756] CPU: 0 PID: 313 Comm: fuzz Not tainted 5.18.0-rc2 #4 [ 68.760756] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 [ 68.760756] Call Trace: [ 68.760756] <TASK> [ 68.760756] dump_stack_lvl+0x57/0x7d [ 68.760756] print_report.cold+0x5e/0x5db [ 68.760756] ? __lock_acquire+0x3ec1/0x6750 [ 68.760756] kasan_report+0xbe/0x1c0 [ 68.760756] ? __lock_acquire+0x3ec1/0x6750 [ 68.760756] __lock_acquire+0x3ec1/0x6750 [ 68.760756] ? lockdep_hardirqs_on_prepare+0x410/0x410 [ 68.760756] ? register_lock_class+0x18d0/0x18d0 [ 68.760756] lock_acquire+0x1ac/0x4f0 [ 68.760756] ? rfkill_blocked+0xe/0x60 [ 68.760756] ? lockdep_hardirqs_on_prepare+0x410/0x410 [ 68.760756] ? mutex_lock_io_nested+0x12c0/0x12c0 [ 68.760756] ? nla_get_range_signed+0x540/0x540 [ 68.760756] ? _raw_spin_lock_irqsave+0x4e/0x50 [ 68.760756] _raw_spin_lock_irqsave+0x39/0x50 [ 68.760756] ? rfkill_blocked+0xe/0x60 [ 68.760756] rfkill_blocked+0xe/0x60 [ 68.760756] nfc_dev_up+0x84/0x260 [ 68.760756] nfc_genl_dev_up+0x90/0xe0 [ 68.760756] genl_family_rcv_msg_doit+0x1f4/0x2f0 [ 68.760756] ? genl_family_rcv_msg_attrs_parse.constprop.0+0x230/0x230 [ 68.760756] ? security_capable+0x51/0x90 [ 68.760756] genl_rcv_msg+0x280/0x500 [ 68.760756] ? genl_get_cmd+0x3c0/0x3c0 [ 68.760756] ? lock_acquire+0x1ac/0x4f0 [ 68.760756] ? nfc_genl_dev_down+0xe0/0xe0 [ 68.760756] ? lockdep_hardirqs_on_prepare+0x410/0x410 [ 68.760756] netlink_rcv_skb+0x11b/0x340 [ 68.760756] ? genl_get_cmd+0x3c0/0x3c0 [ 68.760756] ? netlink_ack+0x9c0/0x9c0 [ 68.760756] ? netlink_deliver_tap+0x136/0xb00 [ 68.760756] genl_rcv+0x1f/0x30 [ 68.760756] netlink_unicast+0x430/0x710 [ 68.760756] ? memset+0x20/0x40 [ 68.760756] ? netlink_attachskb+0x740/0x740 [ 68.760756] ? __build_skb_around+0x1f4/0x2a0 [ 68.760756] netlink_sendmsg+0x75d/0xc00 [ 68.760756] ? netlink_unicast+0x710/0x710 [ 68.760756] ? netlink_unicast+0x710/0x710 [ 68.760756] sock_sendmsg+0xdf/0x110 [ 68.760756] __sys_sendto+0x19e/0x270 [ 68.760756] ? __ia32_sys_getpeername+0xa0/0xa0 [ 68.760756] ? fd_install+0x178/0x4c0 [ 68.760756] ? fd_install+0x195/0x4c0 [ 68.760756] ? kernel_fpu_begin_mask+0x1c0/0x1c0 [ 68.760756] __x64_sys_sendto+0xd8/0x1b0 [ 68.760756] ? lockdep_hardirqs_on+0xbf/0x130 [ 68.760756] ? syscall_enter_from_user_mode+0x1d/0x50 [ 68.760756] do_syscall_64+0x3b/0x90 [ 68.760756] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 68.760756] RIP: 0033:0x7f67fb50e6b3 ... [ 68.760756] RSP: 002b:00007f67fa91fe90 EFLAGS: 00000293 ORIG_RAX: 000000000000002c [ 68.760756] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f67fb50e6b3 [ 68.760756] RDX: 000000000000001c RSI: 0000559354603090 RDI: 0000000000000003 [ 68.760756] RBP: 00007f67fa91ff00 R08: 00007f67fa91fedc R09: 000000000000000c [ 68.760756] R10: 0000000000000000 R11: 0000000000000293 R12: 00007ffe824d496e [ 68.760756] R13: 00007ffe824d496f R14: 00007f67fa120000 R15: 0000000000000003
[ 68.760756] </TASK> [ 68.760756] [ 68.760756] Allocated by task 279: [ 68.760756] kasan_save_stack+0x1e/0x40 [ 68.760756] __kasan_kmalloc+0x81/0xa0 [ 68.760756] rfkill_alloc+0x7f/0x280 [ 68.760756] nfc_register_device+0xa3/0x1a0 [ 68.760756] nci_register_device+0x77a/0xad0 [ 68.760756] nfcmrvl_nci_register_dev+0x20b/0x2c0 [ 68.760756] nfcmrvl_nci_uart_open+0xf2/0x1dd [ 68.760756] nci_uart_tty_ioctl+0x2c3/0x4a0 [ 68.760756] tty_ioctl+0x764/0x1310 [ 68.760756] __x64_sys_ioctl+0x122/0x190 [ 68.760756] do_syscall_64+0x3b/0x90 [ 68.760756] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 68.760756] [ 68.760756] Freed by task 314: [ 68.760756] kasan_save_stack+0x1e/0x40 [ 68.760756] kasan_set_track+0x21/0x30 [ 68.760756] kasan_set_free_info+0x20/0x30 [ 68.760756] __kasan_slab_free+0x108/0x170 [ 68.760756] kfree+0xb0/0x330 [ 68.760756] device_release+0x96/0x200 [ 68.760756] kobject_put+0xf9/0x1d0 [ 68.760756] nfc_unregister_device+0x77/0x190 [ 68.760756] nfcmrvl_nci_unregister_dev+0x88/0xd0 [ 68.760756] nci_uart_tty_close+0xdf/0x180 [ 68.760756] tty_ldisc_kill+0x73/0x110 [ 68.760756] tty_ldisc_hangup+0x281/0x5b0 [ 68.760756] __tty_hangup.part.0+0x431/0x890 [ 68.760756] tty_release+0x3a8/0xc80 [ 68.760756] __fput+0x1f0/0x8c0 [ 68.760756] task_work_run+0xc9/0x170 [ 68.760756] exit_to_user_mode_prepare+0x194/0x1a0 [ 68.760756] syscall_exit_to_user_mode+0x19/0x50 [ 68.760756] do_syscall_64+0x48/0x90 [ 68.760756] entry_SYSCALL_64_after_hwframe+0x44/0xae
This patch just add the null out of dev->rfkill to make sure such dereference cannot happen. This is safe since the device_lock() already protect the check/write from data race.
Fixes: 3e3b5dfcd16a ("NFC: reorder the logic in nfc_{un,}register_device") Signed-off-by: Lin Ma linma@zju.edu.cn Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/net/nfc/core.c b/net/nfc/core.c index 5b286e1e0a6f..6ff3e10ff8e3 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -1166,6 +1166,7 @@ void nfc_unregister_device(struct nfc_dev *dev) if (dev->rfkill) { rfkill_unregister(dev->rfkill); rfkill_destroy(dev->rfkill); + dev->rfkill = NULL; } dev->shutting_down = true; device_unlock(&dev->dev);
From: Kevin Hao haokexin@gmail.com
[ Upstream commit a85ee6401a47ae3fc64ba506cacb3e7873823c65 ]
The struct dbs_data embeds a struct gov_attr_set and the struct gov_attr_set embeds a kobject. Since every kobject must have a release() method and we can't use kfree() to free it directly, so introduce cpufreq_dbs_data_release() to release the dbs_data via the kobject::release() method. This fixes the calltrace like below:
ODEBUG: free active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x34 WARNING: CPU: 12 PID: 810 at lib/debugobjects.c:505 debug_print_object+0xb8/0x100 Modules linked in: CPU: 12 PID: 810 Comm: sh Not tainted 5.16.0-next-20220120-yocto-standard+ #536 Hardware name: Marvell OcteonTX CN96XX board (DT) pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : debug_print_object+0xb8/0x100 lr : debug_print_object+0xb8/0x100 sp : ffff80001dfcf9a0 x29: ffff80001dfcf9a0 x28: 0000000000000001 x27: ffff0001464f0000 x26: 0000000000000000 x25: ffff8000090e3f00 x24: ffff80000af60210 x23: ffff8000094dfb78 x22: ffff8000090e3f00 x21: ffff0001080b7118 x20: ffff80000aeb2430 x19: ffff800009e8f5e0 x18: 0000000000000000 x17: 0000000000000002 x16: 00004d62e58be040 x15: 013590470523aff8 x14: ffff8000090e1828 x13: 0000000001359047 x12: 00000000f5257d14 x11: 0000000000040591 x10: 0000000066c1ffea x9 : ffff8000080d15e0 x8 : ffff80000a1765a8 x7 : 0000000000000000 x6 : 0000000000000001 x5 : ffff800009e8c000 x4 : ffff800009e8c760 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0001474ed040 Call trace: debug_print_object+0xb8/0x100 __debug_check_no_obj_freed+0x1d0/0x25c debug_check_no_obj_freed+0x24/0xa0 kfree+0x11c/0x440 cpufreq_dbs_governor_exit+0xa8/0xac cpufreq_exit_governor+0x44/0x90 cpufreq_set_policy+0x29c/0x570 store_scaling_governor+0x110/0x154 store+0xb0/0xe0 sysfs_kf_write+0x58/0x84 kernfs_fop_write_iter+0x12c/0x1c0 new_sync_write+0xf0/0x18c vfs_write+0x1cc/0x220 ksys_write+0x74/0x100 __arm64_sys_write+0x28/0x3c invoke_syscall.constprop.0+0x58/0xf0 do_el0_svc+0x70/0x170 el0_svc+0x54/0x190 el0t_64_sync_handler+0xa4/0x130 el0t_64_sync+0x1a0/0x1a4 irq event stamp: 189006 hardirqs last enabled at (189005): [<ffff8000080849d0>] finish_task_switch.isra.0+0xe0/0x2c0 hardirqs last disabled at (189006): [<ffff8000090667a4>] el1_dbg+0x24/0xa0 softirqs last enabled at (188966): [<ffff8000080106d0>] __do_softirq+0x4b0/0x6a0 softirqs last disabled at (188957): [<ffff80000804a618>] __irq_exit_rcu+0x108/0x1a4
[ rjw: Because can be freed by the gov_attr_set_put() in cpufreq_dbs_governor_exit() now, it is also necessary to put the invocation of the governor ->exit() callback into the new cpufreq_dbs_data_release() function. ]
Fixes: c4435630361d ("cpufreq: governor: New sysfs show/store callbacks for governor tunables") Signed-off-by: Kevin Hao haokexin@gmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/cpufreq_governor.c | 20 +++++++++++++------- drivers/cpufreq/cpufreq_governor.h | 1 + 2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 0d42cf8b88d8..85da677c43d6 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -388,6 +388,15 @@ static void free_policy_dbs_info(struct policy_dbs_info *policy_dbs, gov->free(policy_dbs); }
+static void cpufreq_dbs_data_release(struct kobject *kobj) +{ + struct dbs_data *dbs_data = to_dbs_data(to_gov_attr_set(kobj)); + struct dbs_governor *gov = dbs_data->gov; + + gov->exit(dbs_data); + kfree(dbs_data); +} + int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) { struct dbs_governor *gov = dbs_governor_of(policy); @@ -425,6 +434,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) goto free_policy_dbs_info; }
+ dbs_data->gov = gov; gov_attr_set_init(&dbs_data->attr_set, &policy_dbs->list);
ret = gov->init(dbs_data); @@ -447,6 +457,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) policy->governor_data = policy_dbs;
gov->kobj_type.sysfs_ops = &governor_sysfs_ops; + gov->kobj_type.release = cpufreq_dbs_data_release; ret = kobject_init_and_add(&dbs_data->attr_set.kobj, &gov->kobj_type, get_governor_parent_kobj(policy), "%s", gov->gov.name); @@ -488,13 +499,8 @@ void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy)
policy->governor_data = NULL;
- if (!count) { - if (!have_governor_per_policy()) - gov->gdbs_data = NULL; - - gov->exit(dbs_data); - kfree(dbs_data); - } + if (!count && !have_governor_per_policy()) + gov->gdbs_data = NULL;
free_policy_dbs_info(policy_dbs, gov);
diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index a5a0bc3cc23e..168c23fd7fca 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -37,6 +37,7 @@ enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE}; /* Governor demand based switching data (per-policy or global). */ struct dbs_data { struct gov_attr_set attr_set; + struct dbs_governor *gov; void *tuners; unsigned int ignore_nice_load; unsigned int sampling_rate;
From: Javier Martinez Canillas javierm@redhat.com
[ Upstream commit a031651ff2144a3d81d4916856c093bc1ea0a413 ]
Commit d9f283ae71af ("efi: Disable runtime services on RT") disabled EFI runtime services by default when the CONFIG_PREEMPT_RT option is enabled.
The rationale for that commit is that some EFI calls could take too much time, leading to large latencies which is an issue for Real-Time kernels.
But a side effect of that change was that now is not possible anymore to enable the EFI runtime services by default when CONFIG_PREEMPT_RT is set, without passing an efi=runtime command line parameter to the kernel.
Instead, let's add a new EFI_DISABLE_RUNTIME boolean Kconfig option, that would be set to n by default but to y if CONFIG_PREEMPT_RT is enabled.
That way, the current behaviour is preserved but gives users a mechanism to enable the EFI runtimes services in their kernels if that is required. For example, if the firmware could guarantee bounded time for EFI calls.
Also, having a separate boolean config could allow users to disable the EFI runtime services by default even when CONFIG_PREEMPT_RT is not set.
Reported-by: Alexander Larsson alexl@redhat.com Fixes: d9f283ae71af ("efi: Disable runtime services on RT") Signed-off-by: Javier Martinez Canillas javierm@redhat.com Link: https://lore.kernel.org/r/20220331151654.184433-1-javierm@redhat.com Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/efi/Kconfig | 15 +++++++++++++++ drivers/firmware/efi/efi.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 2c3dac5ecb36..243882f5e5f9 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -284,3 +284,18 @@ config EFI_CUSTOM_SSDT_OVERLAYS
See Documentation/admin-guide/acpi/ssdt-overlays.rst for more information. + +config EFI_DISABLE_RUNTIME + bool "Disable EFI runtime services support by default" + default y if PREEMPT_RT + help + Allow to disable the EFI runtime services support by default. This can + already be achieved by using the efi=noruntime option, but it could be + useful to have this default without any kernel command line parameter. + + The EFI runtime services are disabled by default when PREEMPT_RT is + enabled, because measurements have shown that some EFI functions calls + might take too much time to complete, causing large latencies which is + an issue for Real-Time kernels. + + This default can be overridden by using the efi=runtime option. diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 5502e176d51b..ff57db8f8d05 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -66,7 +66,7 @@ struct mm_struct efi_mm = {
struct workqueue_struct *efi_rts_wq;
-static bool disable_runtime = IS_ENABLED(CONFIG_PREEMPT_RT); +static bool disable_runtime = IS_ENABLED(CONFIG_EFI_DISABLE_RUNTIME); static int __init setup_noefi(char *arg) { disable_runtime = true;
From: Jan Kiszka jan.kiszka@siemens.com
[ Upstream commit aa480379d8bdb33920d68acfd90f823c8af32578 ]
Fixes "no previous declaration for 'efi_capsule_setup_info'" warnings under W=1.
Fixes: 2959c95d510c ("efi/capsule: Add support for Quark security header") Signed-off-by: Jan Kiszka jan.kiszka@siemens.com Link: https://lore.kernel.org/r/c28d3f86-dd72-27d1-e2c2-40971b8da6bd@siemens.com Signed-off-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/efi.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/linux/efi.h b/include/linux/efi.h index ccd4d3f91c98..cc6d2be2ffd5 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -213,6 +213,8 @@ struct capsule_info { size_t page_bytes_remain; };
+int efi_capsule_setup_info(struct capsule_info *cap_info, void *kbuff, + size_t hdr_bytes); int __efi_capsule_setup_info(struct capsule_info *cap_info);
/*
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 002752af7b89b74c64fe6bec8c5fde3d3a7810d8 ]
Some of the fwnode APIs might return an error pointer instead of NULL or valid fwnode handle. The result of such API call may be considered optional and hence the test for it is usually done in a form of
fwnode = fwnode_find_reference(...); if (IS_ERR(fwnode)) ...error handling...
Nevertheless the resulting fwnode may have bumped the reference count and hence caller of the above API is obliged to call fwnode_handle_put(). Since fwnode may be not valid either as NULL or error pointer the check has to be performed there. This approach uglifies the code and adds a point of making a mistake, i.e. forgetting about error point case.
To prevent this, allow an error pointer to be passed to the fwnode APIs.
Fixes: 83b34afb6b79 ("device property: Introduce fwnode_find_reference()") Reported-by: Nuno Sá nuno.sa@analog.com Tested-by: Nuno Sá nuno.sa@analog.com Acked-by: Nuno Sá nuno.sa@analog.com Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Tested-by: Michael Walle michael@walle.cc Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/property.c | 89 +++++++++++++++++++++++------------------ include/linux/fwnode.h | 10 ++--- 2 files changed, 56 insertions(+), 43 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c index c0e94cce9c29..2f6843c9612b 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -47,12 +47,14 @@ bool fwnode_property_present(const struct fwnode_handle *fwnode, { bool ret;
+ if (IS_ERR_OR_NULL(fwnode)) + return false; + ret = fwnode_call_bool_op(fwnode, property_present, propname); - if (ret == false && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) - ret = fwnode_call_bool_op(fwnode->secondary, property_present, - propname); - return ret; + if (ret) + return ret; + + return fwnode_call_bool_op(fwnode->secondary, property_present, propname); } EXPORT_SYMBOL_GPL(fwnode_property_present);
@@ -232,15 +234,16 @@ static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode, { int ret;
+ if (IS_ERR_OR_NULL(fwnode)) + return -EINVAL; + ret = fwnode_call_int_op(fwnode, property_read_int_array, propname, elem_size, val, nval); - if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) - ret = fwnode_call_int_op( - fwnode->secondary, property_read_int_array, propname, - elem_size, val, nval); + if (ret != -EINVAL) + return ret;
- return ret; + return fwnode_call_int_op(fwnode->secondary, property_read_int_array, propname, + elem_size, val, nval); }
/** @@ -371,14 +374,16 @@ int fwnode_property_read_string_array(const struct fwnode_handle *fwnode, { int ret;
+ if (IS_ERR_OR_NULL(fwnode)) + return -EINVAL; + ret = fwnode_call_int_op(fwnode, property_read_string_array, propname, val, nval); - if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) - ret = fwnode_call_int_op(fwnode->secondary, - property_read_string_array, propname, - val, nval); - return ret; + if (ret != -EINVAL) + return ret; + + return fwnode_call_int_op(fwnode->secondary, property_read_string_array, propname, + val, nval); } EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
@@ -480,15 +485,19 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, { int ret;
+ if (IS_ERR_OR_NULL(fwnode)) + return -ENOENT; + ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop, nargs, index, args); + if (ret == 0) + return ret;
- if (ret < 0 && !IS_ERR_OR_NULL(fwnode) && - !IS_ERR_OR_NULL(fwnode->secondary)) - ret = fwnode_call_int_op(fwnode->secondary, get_reference_args, - prop, nargs_prop, nargs, index, args); + if (IS_ERR_OR_NULL(fwnode->secondary)) + return ret;
- return ret; + return fwnode_call_int_op(fwnode->secondary, get_reference_args, prop, nargs_prop, + nargs, index, args); } EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
@@ -635,12 +644,13 @@ EXPORT_SYMBOL_GPL(fwnode_count_parents); struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode, unsigned int depth) { - unsigned int i; - fwnode_handle_get(fwnode);
- for (i = 0; i < depth && fwnode; i++) + do { + if (depth-- == 0) + break; fwnode = fwnode_get_next_parent(fwnode); + } while (fwnode);
return fwnode; } @@ -659,17 +669,17 @@ EXPORT_SYMBOL_GPL(fwnode_get_nth_parent); bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor, struct fwnode_handle *test_child) { - if (!test_ancestor) + if (IS_ERR_OR_NULL(test_ancestor)) return false;
fwnode_handle_get(test_child); - while (test_child) { + do { if (test_child == test_ancestor) { fwnode_handle_put(test_child); return true; } test_child = fwnode_get_next_parent(test_child); - } + } while (test_child); return false; }
@@ -698,7 +708,7 @@ fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode, { struct fwnode_handle *next_child = child;
- if (!fwnode) + if (IS_ERR_OR_NULL(fwnode)) return NULL;
do { @@ -722,16 +732,16 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev, const struct fwnode_handle *fwnode = dev_fwnode(dev); struct fwnode_handle *next;
+ if (IS_ERR_OR_NULL(fwnode)) + return NULL; + /* Try to find a child in primary fwnode */ next = fwnode_get_next_child_node(fwnode, child); if (next) return next;
/* When no more children in primary, continue with secondary */ - if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary)) - next = fwnode_get_next_child_node(fwnode->secondary, child); - - return next; + return fwnode_get_next_child_node(fwnode->secondary, child); } EXPORT_SYMBOL_GPL(device_get_next_child_node);
@@ -798,6 +808,9 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put); */ bool fwnode_device_is_available(const struct fwnode_handle *fwnode) { + if (IS_ERR_OR_NULL(fwnode)) + return false; + if (!fwnode_has_op(fwnode, device_is_available)) return true;
@@ -988,14 +1001,14 @@ fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, parent = fwnode_graph_get_port_parent(prev); else parent = fwnode; + if (IS_ERR_OR_NULL(parent)) + return NULL;
ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); + if (ep) + return ep;
- if (IS_ERR_OR_NULL(ep) && - !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary)) - ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL); - - return ep; + return fwnode_graph_get_next_endpoint(parent->secondary, NULL); } EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h index 3a532ba66f6c..7defac04f9a3 100644 --- a/include/linux/fwnode.h +++ b/include/linux/fwnode.h @@ -148,12 +148,12 @@ struct fwnode_operations { int (*add_links)(struct fwnode_handle *fwnode); };
-#define fwnode_has_op(fwnode, op) \ - ((fwnode) && (fwnode)->ops && (fwnode)->ops->op) +#define fwnode_has_op(fwnode, op) \ + (!IS_ERR_OR_NULL(fwnode) && (fwnode)->ops && (fwnode)->ops->op) + #define fwnode_call_int_op(fwnode, op, ...) \ - (fwnode ? (fwnode_has_op(fwnode, op) ? \ - (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \ - -EINVAL) + (fwnode_has_op(fwnode, op) ? \ + (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : (IS_ERR_OR_NULL(fwnode) ? -EINVAL : -ENXIO))
#define fwnode_call_bool_op(fwnode, op, ...) \ (fwnode_has_op(fwnode, op) ? \
From: Gavin Wan Gavin.Wan@amd.com
[ Upstream commit d68cf992ded575928cf4ddf7c64faff0d8dcce14 ]
[why] These static variables save the RLC Scratch registers address. When we install multiple GPUs (for example: XGMI setting) and multiple GPUs call the function at same time. The RLC Scratch registers address are changed each other. Then it caused reading/writing from/to wrong GPU.
[how] Removed the static from the variables. The variables are on the stack.
Fixes: 5d447e29670148 ("drm/amdgpu: add helper for rlcg indirect reg access") Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Gavin Wan Gavin.Wan@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_virt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index 5e3756643da3..1d55b2bae37e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -864,11 +864,11 @@ static u32 amdgpu_virt_rlcg_reg_rw(struct amdgpu_device *adev, u32 offset, u32 v uint32_t timeout = 50000; uint32_t i, tmp; uint32_t ret = 0; - static void *scratch_reg0; - static void *scratch_reg1; - static void *scratch_reg2; - static void *scratch_reg3; - static void *spare_int; + void *scratch_reg0; + void *scratch_reg1; + void *scratch_reg2; + void *scratch_reg3; + void *spare_int;
if (!adev->gfx.rlc.rlcg_reg_access_supported) { dev_err(adev->dev,
From: Ansuel Smith ansuelsmth@gmail.com
[ Upstream commit 6cfc03b602200c5cbbd8d906fd905547814e83df ]
Restore original way to handle mdio read error by returning 0xffff. This was wrongly changed when the internal_mdio_read was introduced, now that both legacy and internal use the same function, make sure that they behave the same way.
Fixes: ce062a0adbfe ("net: dsa: qca8k: fix kernel panic with legacy mdio mapping") Signed-off-by: Ansuel Smith ansuelsmth@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/qca8k.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c index d3ed0a7f8077..22b328bd7cd5 100644 --- a/drivers/net/dsa/qca8k.c +++ b/drivers/net/dsa/qca8k.c @@ -1287,7 +1287,12 @@ qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum) if (ret >= 0) return ret;
- return qca8k_mdio_read(priv, phy, regnum); + ret = qca8k_mdio_read(priv, phy, regnum); + + if (ret < 0) + return 0xffff; + + return ret; }
static int
From: Christoph Hellwig hch@lst.de
[ Upstream commit 179d8609d8424529e95021df939ed7b0b82b37f1 ]
For block devices, the SCSI target drivers implements UNMAP as calls to blkdev_issue_discard, which does not guarantee zeroing just because Write Zeroes is supported.
Note that this does not affect the file backed path which uses fallocate to punch holes.
Fixes: 2237498f0b5c ("target/iblock: Convert WRITE_SAME to blkdev_issue_zeroout") Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Martin K. Petersen martin.petersen@oracle.com Reviewed-by: Chaitanya Kulkarni kch@nvidia.com Link: https://lore.kernel.org/r/20220415045258.199825-2-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_device.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 44bb380e7390..fa866acef5bb 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -850,7 +850,6 @@ bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib, attrib->unmap_granularity = q->limits.discard_granularity / block_size; attrib->unmap_granularity_alignment = q->limits.discard_alignment / block_size; - attrib->unmap_zeroes_data = !!(q->limits.max_write_zeroes_sectors); return true; } EXPORT_SYMBOL(target_configure_unmap_from_queue);
From: Christoph Hellwig hch@lst.de
[ Upstream commit 40349d0e16cedd0de561f59752c3249780fb749b ]
Fold each branch into its only caller.
Signed-off-by: Christoph Hellwig hch@lst.de Acked-by: Christoph Böhmwalder christoph.boehmwalder@linbit.com Link: https://lore.kernel.org/r/20220415045258.199825-5-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_main.c | 47 +++++++++++++++------------------- 1 file changed, 20 insertions(+), 27 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 4b0b25cc916e..367715205c86 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -903,31 +903,6 @@ void drbd_gen_and_send_sync_uuid(struct drbd_peer_device *peer_device) } }
-/* communicated if (agreed_features & DRBD_FF_WSAME) */ -static void -assign_p_sizes_qlim(struct drbd_device *device, struct p_sizes *p, - struct request_queue *q) -{ - if (q) { - p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q)); - p->qlim->logical_block_size = cpu_to_be32(queue_logical_block_size(q)); - p->qlim->alignment_offset = cpu_to_be32(queue_alignment_offset(q)); - p->qlim->io_min = cpu_to_be32(queue_io_min(q)); - p->qlim->io_opt = cpu_to_be32(queue_io_opt(q)); - p->qlim->discard_enabled = blk_queue_discard(q); - p->qlim->write_same_capable = 0; - } else { - q = device->rq_queue; - p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q)); - p->qlim->logical_block_size = cpu_to_be32(queue_logical_block_size(q)); - p->qlim->alignment_offset = 0; - p->qlim->io_min = cpu_to_be32(queue_io_min(q)); - p->qlim->io_opt = cpu_to_be32(queue_io_opt(q)); - p->qlim->discard_enabled = 0; - p->qlim->write_same_capable = 0; - } -} - int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enum dds_flags flags) { struct drbd_device *device = peer_device->device; @@ -957,14 +932,32 @@ int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enu q_order_type = drbd_queue_order_type(device); max_bio_size = queue_max_hw_sectors(q) << 9; max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE); - assign_p_sizes_qlim(device, p, q); + p->qlim->physical_block_size = + cpu_to_be32(queue_physical_block_size(q)); + p->qlim->logical_block_size = + cpu_to_be32(queue_logical_block_size(q)); + p->qlim->alignment_offset = + cpu_to_be32(queue_alignment_offset(q)); + p->qlim->io_min = cpu_to_be32(queue_io_min(q)); + p->qlim->io_opt = cpu_to_be32(queue_io_opt(q)); + p->qlim->discard_enabled = blk_queue_discard(q); put_ldev(device); } else { + struct request_queue *q = device->rq_queue; + + p->qlim->physical_block_size = + cpu_to_be32(queue_physical_block_size(q)); + p->qlim->logical_block_size = + cpu_to_be32(queue_logical_block_size(q)); + p->qlim->alignment_offset = 0; + p->qlim->io_min = cpu_to_be32(queue_io_min(q)); + p->qlim->io_opt = cpu_to_be32(queue_io_opt(q)); + p->qlim->discard_enabled = 0; + d_size = 0; u_size = 0; q_order_type = QUEUE_ORDERED_NONE; max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */ - assign_p_sizes_qlim(device, p, NULL); }
if (peer_device->connection->agreed_pro_version <= 94)
From: Christoph Hellwig hch@lst.de
[ Upstream commit 7a38acce229685968b770d1d9e64e01396b93643 ]
Use the bdev based limits helpers where they exist.
Signed-off-by: Christoph Hellwig hch@lst.de Acked-by: Christoph Böhmwalder christoph.boehmwalder@linbit.com Link: https://lore.kernel.org/r/20220415045258.199825-6-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_main.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 367715205c86..c39b04bda261 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -924,7 +924,9 @@ int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enu
memset(p, 0, packet_size); if (get_ldev_if_state(device, D_NEGOTIATING)) { - struct request_queue *q = bdev_get_queue(device->ldev->backing_bdev); + struct block_device *bdev = device->ldev->backing_bdev; + struct request_queue *q = bdev_get_queue(bdev); + d_size = drbd_get_max_capacity(device->ldev); rcu_read_lock(); u_size = rcu_dereference(device->ldev->disk_conf)->disk_size; @@ -933,13 +935,13 @@ int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enu max_bio_size = queue_max_hw_sectors(q) << 9; max_bio_size = min(max_bio_size, DRBD_MAX_BIO_SIZE); p->qlim->physical_block_size = - cpu_to_be32(queue_physical_block_size(q)); + cpu_to_be32(bdev_physical_block_size(bdev)); p->qlim->logical_block_size = - cpu_to_be32(queue_logical_block_size(q)); + cpu_to_be32(bdev_logical_block_size(bdev)); p->qlim->alignment_offset = cpu_to_be32(queue_alignment_offset(q)); - p->qlim->io_min = cpu_to_be32(queue_io_min(q)); - p->qlim->io_opt = cpu_to_be32(queue_io_opt(q)); + p->qlim->io_min = cpu_to_be32(bdev_io_min(bdev)); + p->qlim->io_opt = cpu_to_be32(bdev_io_opt(bdev)); p->qlim->discard_enabled = blk_queue_discard(q); put_ldev(device); } else {
From: Christoph Hellwig hch@lst.de
[ Upstream commit c6f23b1a05441a26f765e59dd95e8ba7354f9388 ]
The bdev version does the right thing for partitions, so use that.
Fixes: 9104d31a759f ("drbd: introduce WRITE_SAME support") Signed-off-by: Christoph Hellwig hch@lst.de Acked-by: Christoph Böhmwalder christoph.boehmwalder@linbit.com Link: https://lore.kernel.org/r/20220415045258.199825-7-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index c39b04bda261..7b501c8d5992 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -939,7 +939,7 @@ int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enu p->qlim->logical_block_size = cpu_to_be32(bdev_logical_block_size(bdev)); p->qlim->alignment_offset = - cpu_to_be32(queue_alignment_offset(q)); + cpu_to_be32(bdev_alignment_offset(bdev)); p->qlim->io_min = cpu_to_be32(bdev_io_min(bdev)); p->qlim->io_opt = cpu_to_be32(bdev_io_opt(bdev)); p->qlim->discard_enabled = blk_queue_discard(q);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 33cb0917bbe241dd17a2b87ead63514c1b7e5615 ]
There are two initializers for P_RETRY_WRITE:
drivers/block/drbd/drbd_main.c:3676:22: warning: initialized field overwritten [-Woverride-init]
Remove the first one since it was already ignored by the compiler and reorder the list to match the enum definition. As P_ZEROES had no entry, add that one instead.
Fixes: 036b17eaab93 ("drbd: Receiving part for the PROTOCOL_UPDATE packet") Fixes: f31e583aa2c2 ("drbd: introduce P_ZEROES (REQ_OP_WRITE_ZEROES on the "wire")") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Christoph Böhmwalder christoph.boehmwalder@linbit.com Link: https://lore.kernel.org/r/20220406190715.1938174-2-christoph.boehmwalder@lin... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/drbd/drbd_main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 7b501c8d5992..57b23e49ee91 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3581,9 +3581,8 @@ const char *cmdname(enum drbd_packet cmd) * when we want to support more than * one PRO_VERSION */ static const char *cmdnames[] = { + [P_DATA] = "Data", - [P_WSAME] = "WriteSame", - [P_TRIM] = "Trim", [P_DATA_REPLY] = "DataReply", [P_RS_DATA_REPLY] = "RSDataReply", [P_BARRIER] = "Barrier", @@ -3594,7 +3593,6 @@ const char *cmdname(enum drbd_packet cmd) [P_DATA_REQUEST] = "DataRequest", [P_RS_DATA_REQUEST] = "RSDataRequest", [P_SYNC_PARAM] = "SyncParam", - [P_SYNC_PARAM89] = "SyncParam89", [P_PROTOCOL] = "ReportProtocol", [P_UUIDS] = "ReportUUIDs", [P_SIZES] = "ReportSizes", @@ -3602,6 +3600,7 @@ const char *cmdname(enum drbd_packet cmd) [P_SYNC_UUID] = "ReportSyncUUID", [P_AUTH_CHALLENGE] = "AuthChallenge", [P_AUTH_RESPONSE] = "AuthResponse", + [P_STATE_CHG_REQ] = "StateChgRequest", [P_PING] = "Ping", [P_PING_ACK] = "PingAck", [P_RECV_ACK] = "RecvAck", @@ -3612,23 +3611,25 @@ const char *cmdname(enum drbd_packet cmd) [P_NEG_DREPLY] = "NegDReply", [P_NEG_RS_DREPLY] = "NegRSDReply", [P_BARRIER_ACK] = "BarrierAck", - [P_STATE_CHG_REQ] = "StateChgRequest", [P_STATE_CHG_REPLY] = "StateChgReply", [P_OV_REQUEST] = "OVRequest", [P_OV_REPLY] = "OVReply", [P_OV_RESULT] = "OVResult", [P_CSUM_RS_REQUEST] = "CsumRSRequest", [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", + [P_SYNC_PARAM89] = "SyncParam89", [P_COMPRESSED_BITMAP] = "CBitmap", [P_DELAY_PROBE] = "DelayProbe", [P_OUT_OF_SYNC] = "OutOfSync", - [P_RETRY_WRITE] = "RetryWrite", [P_RS_CANCEL] = "RSCancel", [P_CONN_ST_CHG_REQ] = "conn_st_chg_req", [P_CONN_ST_CHG_REPLY] = "conn_st_chg_reply", [P_PROTOCOL_UPDATE] = "protocol_update", + [P_TRIM] = "Trim", [P_RS_THIN_REQ] = "rs_thin_req", [P_RS_DEALLOCATED] = "rs_deallocated", + [P_WSAME] = "WriteSame", + [P_ZEROES] = "Zeroes",
/* enum drbd_packet, but not commands - obsoleted flags: * P_MAY_IGNORE
From: Tyler Hicks tyhicks@linux.microsoft.com
[ Upstream commit ad2df24732e8956a45a00894d2163c4ee8fb0e1f ]
The dmc520 driver requires that at least one interrupt line, out of the ten possible, is configured. The driver prints an error and returns -EINVAL from its .probe function if there are no interrupt lines configured.
Don't print a KERN_ERR level message for each interrupt line that's unconfigured as that can confuse users into thinking that there is an error condition.
Before this change, the following KERN_ERR level messages would be reported if only dram_ecc_errc and dram_ecc_errd were configured in the device tree:
dmc520 68000000.dmc: IRQ ram_ecc_errc not found dmc520 68000000.dmc: IRQ ram_ecc_errd not found dmc520 68000000.dmc: IRQ failed_access not found dmc520 68000000.dmc: IRQ failed_prog not found dmc520 68000000.dmc: IRQ link_err not dmc520 68000000.dmc: IRQ temperature_event not found dmc520 68000000.dmc: IRQ arch_fsm not found dmc520 68000000.dmc: IRQ phy_request not found
Fixes: 1088750d7839 ("EDAC: Add EDAC driver for DMC520") Reported-by: Sinan Kaya okaya@kernel.org Signed-off-by: Tyler Hicks tyhicks@linux.microsoft.com Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/20220111163800.22362-1-tyhicks@linux.microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/edac/dmc520_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/edac/dmc520_edac.c b/drivers/edac/dmc520_edac.c index b8a7d9594afd..1fa5ca57e9ec 100644 --- a/drivers/edac/dmc520_edac.c +++ b/drivers/edac/dmc520_edac.c @@ -489,7 +489,7 @@ static int dmc520_edac_probe(struct platform_device *pdev) dev = &pdev->dev;
for (idx = 0; idx < NUMBER_OF_IRQS; idx++) { - irq = platform_get_irq_byname(pdev, dmc520_irq_configs[idx].name); + irq = platform_get_irq_byname_optional(pdev, dmc520_irq_configs[idx].name); irqs[idx] = irq; masks[idx] = dmc520_irq_configs[idx].mask; if (irq >= 0) {
From: Stanislav Fomichev sdf@google.com
[ Upstream commit 055eb95533273bc334794dbc598400d10800528f ]
Commit 7d08c2c91171 ("bpf: Refactor BPF_PROG_RUN_ARRAY family of macros into functions") switched a bunch of BPF_PROG_RUN macros to inline routines. This changed the semantic a bit. Due to arguments expansion of macros, it used to be:
rcu_read_lock(); array = rcu_dereference(cgrp->bpf.effective[atype]); ...
Now, with with inline routines, we have: array_rcu = rcu_dereference(cgrp->bpf.effective[atype]); /* array_rcu can be kfree'd here */ rcu_read_lock(); array = rcu_dereference(array_rcu);
I'm assuming in practice rcu subsystem isn't fast enough to trigger this but let's use rcu API properly.
Also, rename to lower caps to not confuse with macros. Additionally, drop and expand BPF_PROG_CGROUP_INET_EGRESS_RUN_ARRAY.
See [1] for more context.
[1] https://lore.kernel.org/bpf/CAKH8qBs60fOinFdxiiQikK_q0EcVxGvNTQoWvHLEUGbgcj1...
v2 - keep rcu locks inside by passing cgroup_bpf
Fixes: 7d08c2c91171 ("bpf: Refactor BPF_PROG_RUN_ARRAY family of macros into functions") Signed-off-by: Stanislav Fomichev sdf@google.com Signed-off-by: Alexei Starovoitov ast@kernel.org Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/bpf/20220414161233.170780-1-sdf@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/bpf-lirc.c | 8 ++- include/linux/bpf.h | 115 ++------------------------------- kernel/bpf/cgroup.c | 124 +++++++++++++++++++++++++++++++----- kernel/trace/bpf_trace.c | 5 +- 4 files changed, 124 insertions(+), 128 deletions(-)
diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c index 3eff08d7b8e5..fe17c7f98e81 100644 --- a/drivers/media/rc/bpf-lirc.c +++ b/drivers/media/rc/bpf-lirc.c @@ -216,8 +216,12 @@ void lirc_bpf_run(struct rc_dev *rcdev, u32 sample)
raw->bpf_sample = sample;
- if (raw->progs) - BPF_PROG_RUN_ARRAY(raw->progs, &raw->bpf_sample, bpf_prog_run); + if (raw->progs) { + rcu_read_lock(); + bpf_prog_run_array(rcu_dereference(raw->progs), + &raw->bpf_sample, bpf_prog_run); + rcu_read_unlock(); + } }
/* diff --git a/include/linux/bpf.h b/include/linux/bpf.h index f084b251fce7..67efaa38c33f 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1221,7 +1221,7 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, /* an array of programs to be executed under rcu_lock. * * Typical usage: - * ret = BPF_PROG_RUN_ARRAY(&bpf_prog_array, ctx, bpf_prog_run); + * ret = bpf_prog_run_array(rcu_dereference(&bpf_prog_array), ctx, bpf_prog_run); * * the structure returned by bpf_prog_array_alloc() should be populated * with program pointers and the last pointer must be NULL. @@ -1315,83 +1315,22 @@ static inline void bpf_reset_run_ctx(struct bpf_run_ctx *old_ctx)
typedef u32 (*bpf_prog_run_fn)(const struct bpf_prog *prog, const void *ctx);
-static __always_inline int -BPF_PROG_RUN_ARRAY_CG_FLAGS(const struct bpf_prog_array __rcu *array_rcu, - const void *ctx, bpf_prog_run_fn run_prog, - int retval, u32 *ret_flags) -{ - const struct bpf_prog_array_item *item; - const struct bpf_prog *prog; - const struct bpf_prog_array *array; - struct bpf_run_ctx *old_run_ctx; - struct bpf_cg_run_ctx run_ctx; - u32 func_ret; - - run_ctx.retval = retval; - migrate_disable(); - rcu_read_lock(); - array = rcu_dereference(array_rcu); - item = &array->items[0]; - old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); - while ((prog = READ_ONCE(item->prog))) { - run_ctx.prog_item = item; - func_ret = run_prog(prog, ctx); - if (!(func_ret & 1) && !IS_ERR_VALUE((long)run_ctx.retval)) - run_ctx.retval = -EPERM; - *(ret_flags) |= (func_ret >> 1); - item++; - } - bpf_reset_run_ctx(old_run_ctx); - rcu_read_unlock(); - migrate_enable(); - return run_ctx.retval; -} - -static __always_inline int -BPF_PROG_RUN_ARRAY_CG(const struct bpf_prog_array __rcu *array_rcu, - const void *ctx, bpf_prog_run_fn run_prog, - int retval) -{ - const struct bpf_prog_array_item *item; - const struct bpf_prog *prog; - const struct bpf_prog_array *array; - struct bpf_run_ctx *old_run_ctx; - struct bpf_cg_run_ctx run_ctx; - - run_ctx.retval = retval; - migrate_disable(); - rcu_read_lock(); - array = rcu_dereference(array_rcu); - item = &array->items[0]; - old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); - while ((prog = READ_ONCE(item->prog))) { - run_ctx.prog_item = item; - if (!run_prog(prog, ctx) && !IS_ERR_VALUE((long)run_ctx.retval)) - run_ctx.retval = -EPERM; - item++; - } - bpf_reset_run_ctx(old_run_ctx); - rcu_read_unlock(); - migrate_enable(); - return run_ctx.retval; -} - static __always_inline u32 -BPF_PROG_RUN_ARRAY(const struct bpf_prog_array __rcu *array_rcu, +bpf_prog_run_array(const struct bpf_prog_array *array, const void *ctx, bpf_prog_run_fn run_prog) { const struct bpf_prog_array_item *item; const struct bpf_prog *prog; - const struct bpf_prog_array *array; struct bpf_run_ctx *old_run_ctx; struct bpf_trace_run_ctx run_ctx; u32 ret = 1;
- migrate_disable(); - rcu_read_lock(); - array = rcu_dereference(array_rcu); + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), "no rcu lock held"); + if (unlikely(!array)) - goto out; + return ret; + + migrate_disable(); old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); item = &array->items[0]; while ((prog = READ_ONCE(item->prog))) { @@ -1400,50 +1339,10 @@ BPF_PROG_RUN_ARRAY(const struct bpf_prog_array __rcu *array_rcu, item++; } bpf_reset_run_ctx(old_run_ctx); -out: - rcu_read_unlock(); migrate_enable(); return ret; }
-/* To be used by __cgroup_bpf_run_filter_skb for EGRESS BPF progs - * so BPF programs can request cwr for TCP packets. - * - * Current cgroup skb programs can only return 0 or 1 (0 to drop the - * packet. This macro changes the behavior so the low order bit - * indicates whether the packet should be dropped (0) or not (1) - * and the next bit is a congestion notification bit. This could be - * used by TCP to call tcp_enter_cwr() - * - * Hence, new allowed return values of CGROUP EGRESS BPF programs are: - * 0: drop packet - * 1: keep packet - * 2: drop packet and cn - * 3: keep packet and cn - * - * This macro then converts it to one of the NET_XMIT or an error - * code that is then interpreted as drop packet (and no cn): - * 0: NET_XMIT_SUCCESS skb should be transmitted - * 1: NET_XMIT_DROP skb should be dropped and cn - * 2: NET_XMIT_CN skb should be transmitted and cn - * 3: -err skb should be dropped - */ -#define BPF_PROG_CGROUP_INET_EGRESS_RUN_ARRAY(array, ctx, func) \ - ({ \ - u32 _flags = 0; \ - bool _cn; \ - u32 _ret; \ - _ret = BPF_PROG_RUN_ARRAY_CG_FLAGS(array, ctx, func, 0, &_flags); \ - _cn = _flags & BPF_RET_SET_CN; \ - if (_ret && !IS_ERR_VALUE((long)_ret)) \ - _ret = -EFAULT; \ - if (!_ret) \ - _ret = (_cn ? NET_XMIT_CN : NET_XMIT_SUCCESS); \ - else \ - _ret = (_cn ? NET_XMIT_DROP : _ret); \ - _ret; \ - }) - #ifdef CONFIG_BPF_SYSCALL DECLARE_PER_CPU(int, bpf_prog_active); extern struct mutex bpf_stats_enabled_mutex; diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 128028efda64..0cb6211fcb58 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -22,6 +22,72 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(cgroup_bpf_enabled_key, MAX_CGROUP_BPF_ATTACH_TYPE); EXPORT_SYMBOL(cgroup_bpf_enabled_key);
+/* __always_inline is necessary to prevent indirect call through run_prog + * function pointer. + */ +static __always_inline int +bpf_prog_run_array_cg_flags(const struct cgroup_bpf *cgrp, + enum cgroup_bpf_attach_type atype, + const void *ctx, bpf_prog_run_fn run_prog, + int retval, u32 *ret_flags) +{ + const struct bpf_prog_array_item *item; + const struct bpf_prog *prog; + const struct bpf_prog_array *array; + struct bpf_run_ctx *old_run_ctx; + struct bpf_cg_run_ctx run_ctx; + u32 func_ret; + + run_ctx.retval = retval; + migrate_disable(); + rcu_read_lock(); + array = rcu_dereference(cgrp->effective[atype]); + item = &array->items[0]; + old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); + while ((prog = READ_ONCE(item->prog))) { + run_ctx.prog_item = item; + func_ret = run_prog(prog, ctx); + if (!(func_ret & 1) && !IS_ERR_VALUE((long)run_ctx.retval)) + run_ctx.retval = -EPERM; + *(ret_flags) |= (func_ret >> 1); + item++; + } + bpf_reset_run_ctx(old_run_ctx); + rcu_read_unlock(); + migrate_enable(); + return run_ctx.retval; +} + +static __always_inline int +bpf_prog_run_array_cg(const struct cgroup_bpf *cgrp, + enum cgroup_bpf_attach_type atype, + const void *ctx, bpf_prog_run_fn run_prog, + int retval) +{ + const struct bpf_prog_array_item *item; + const struct bpf_prog *prog; + const struct bpf_prog_array *array; + struct bpf_run_ctx *old_run_ctx; + struct bpf_cg_run_ctx run_ctx; + + run_ctx.retval = retval; + migrate_disable(); + rcu_read_lock(); + array = rcu_dereference(cgrp->effective[atype]); + item = &array->items[0]; + old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); + while ((prog = READ_ONCE(item->prog))) { + run_ctx.prog_item = item; + if (!run_prog(prog, ctx) && !IS_ERR_VALUE((long)run_ctx.retval)) + run_ctx.retval = -EPERM; + item++; + } + bpf_reset_run_ctx(old_run_ctx); + rcu_read_unlock(); + migrate_enable(); + return run_ctx.retval; +} + void cgroup_bpf_offline(struct cgroup *cgrp) { cgroup_get(cgrp); @@ -1075,11 +1141,38 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk, bpf_compute_and_save_data_end(skb, &saved_data_end);
if (atype == CGROUP_INET_EGRESS) { - ret = BPF_PROG_CGROUP_INET_EGRESS_RUN_ARRAY( - cgrp->bpf.effective[atype], skb, __bpf_prog_run_save_cb); + u32 flags = 0; + bool cn; + + ret = bpf_prog_run_array_cg_flags( + &cgrp->bpf, atype, + skb, __bpf_prog_run_save_cb, 0, &flags); + + /* Return values of CGROUP EGRESS BPF programs are: + * 0: drop packet + * 1: keep packet + * 2: drop packet and cn + * 3: keep packet and cn + * + * The returned value is then converted to one of the NET_XMIT + * or an error code that is then interpreted as drop packet + * (and no cn): + * 0: NET_XMIT_SUCCESS skb should be transmitted + * 1: NET_XMIT_DROP skb should be dropped and cn + * 2: NET_XMIT_CN skb should be transmitted and cn + * 3: -err skb should be dropped + */ + + cn = flags & BPF_RET_SET_CN; + if (ret && !IS_ERR_VALUE((long)ret)) + ret = -EFAULT; + if (!ret) + ret = (cn ? NET_XMIT_CN : NET_XMIT_SUCCESS); + else + ret = (cn ? NET_XMIT_DROP : ret); } else { - ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], skb, - __bpf_prog_run_save_cb, 0); + ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, + skb, __bpf_prog_run_save_cb, 0); if (ret && !IS_ERR_VALUE((long)ret)) ret = -EFAULT; } @@ -1109,8 +1202,7 @@ int __cgroup_bpf_run_filter_sk(struct sock *sk, { struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
- return BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], sk, - bpf_prog_run, 0); + return bpf_prog_run_array_cg(&cgrp->bpf, atype, sk, bpf_prog_run, 0); } EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);
@@ -1155,8 +1247,8 @@ int __cgroup_bpf_run_filter_sock_addr(struct sock *sk, }
cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); - return BPF_PROG_RUN_ARRAY_CG_FLAGS(cgrp->bpf.effective[atype], &ctx, - bpf_prog_run, 0, flags); + return bpf_prog_run_array_cg_flags(&cgrp->bpf, atype, + &ctx, bpf_prog_run, 0, flags); } EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_addr);
@@ -1182,8 +1274,8 @@ int __cgroup_bpf_run_filter_sock_ops(struct sock *sk, { struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
- return BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], sock_ops, - bpf_prog_run, 0); + return bpf_prog_run_array_cg(&cgrp->bpf, atype, sock_ops, bpf_prog_run, + 0); } EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_ops);
@@ -1200,8 +1292,7 @@ int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
rcu_read_lock(); cgrp = task_dfl_cgroup(current); - ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], &ctx, - bpf_prog_run, 0); + ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run, 0); rcu_read_unlock();
return ret; @@ -1366,8 +1457,7 @@ int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
rcu_read_lock(); cgrp = task_dfl_cgroup(current); - ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[atype], &ctx, - bpf_prog_run, 0); + ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run, 0); rcu_read_unlock();
kfree(ctx.cur_val); @@ -1459,7 +1549,7 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level, }
lock_sock(sk); - ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[CGROUP_SETSOCKOPT], + ret = bpf_prog_run_array_cg(&cgrp->bpf, CGROUP_SETSOCKOPT, &ctx, bpf_prog_run, 0); release_sock(sk);
@@ -1559,7 +1649,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level, }
lock_sock(sk); - ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[CGROUP_GETSOCKOPT], + ret = bpf_prog_run_array_cg(&cgrp->bpf, CGROUP_GETSOCKOPT, &ctx, bpf_prog_run, retval); release_sock(sk);
@@ -1608,7 +1698,7 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level, * be called if that data shouldn't be "exported". */
- ret = BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[CGROUP_GETSOCKOPT], + ret = bpf_prog_run_array_cg(&cgrp->bpf, CGROUP_GETSOCKOPT, &ctx, bpf_prog_run, retval); if (ret < 0) return ret; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index d8553f46caa2..6b58fc6813df 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -129,7 +129,10 @@ unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx) * out of events when it was updated in between this and the * rcu_dereference() which is accepted risk. */ - ret = BPF_PROG_RUN_ARRAY(call->prog_array, ctx, bpf_prog_run); + rcu_read_lock(); + ret = bpf_prog_run_array(rcu_dereference(call->prog_array), + ctx, bpf_prog_run); + rcu_read_unlock();
out: __this_cpu_dec(bpf_prog_active);
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit fb8da7f3111ab500606960bef1bb32450c664750 ]
As defined in the anx7625 dt-binding, the analogix,lane0-swing and analogix,lane1-swing properties are uint8 arrays. Yet, the driver was reading the array as if it were of uint32 and masking to 8-bit before writing to the registers. This means that a devicetree written in accordance to the dt-binding would have its values incorrectly parsed.
Fix the issue by reading the array as uint8 and storing them as uint8 internally, so that we can also drop the masking when writing the registers.
Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature") 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/20220408013034.673418-1-nfrapr... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 12 ++++++------ drivers/gpu/drm/bridge/analogix/anx7625.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index a23e13c29a1d..060849f8ad8b 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1478,12 +1478,12 @@ static void anx7625_dp_adjust_swing(struct anx7625_data *ctx) for (i = 0; i < ctx->pdata.dp_lane0_swing_reg_cnt; i++) anx7625_reg_write(ctx, ctx->i2c.tx_p1_client, DP_TX_LANE0_SWING_REG0 + i, - ctx->pdata.lane0_reg_data[i] & 0xFF); + ctx->pdata.lane0_reg_data[i]);
for (i = 0; i < ctx->pdata.dp_lane1_swing_reg_cnt; i++) anx7625_reg_write(ctx, ctx->i2c.tx_p1_client, DP_TX_LANE1_SWING_REG0 + i, - ctx->pdata.lane1_reg_data[i] & 0xFF); + ctx->pdata.lane1_reg_data[i]); }
static void dp_hpd_change_handler(struct anx7625_data *ctx, bool on) @@ -1590,8 +1590,8 @@ static int anx7625_get_swing_setting(struct device *dev, num_regs = DP_TX_SWING_REG_CNT;
pdata->dp_lane0_swing_reg_cnt = num_regs; - of_property_read_u32_array(dev->of_node, "analogix,lane0-swing", - pdata->lane0_reg_data, num_regs); + of_property_read_u8_array(dev->of_node, "analogix,lane0-swing", + pdata->lane0_reg_data, num_regs); }
if (of_get_property(dev->of_node, @@ -1600,8 +1600,8 @@ static int anx7625_get_swing_setting(struct device *dev, num_regs = DP_TX_SWING_REG_CNT;
pdata->dp_lane1_swing_reg_cnt = num_regs; - of_property_read_u32_array(dev->of_node, "analogix,lane1-swing", - pdata->lane1_reg_data, num_regs); + of_property_read_u8_array(dev->of_node, "analogix,lane1-swing", + pdata->lane1_reg_data, num_regs); }
return 0; diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.h b/drivers/gpu/drm/bridge/analogix/anx7625.h index edbbfe410a56..e257a84db962 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.h +++ b/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -426,9 +426,9 @@ struct anx7625_platform_data { int mipi_lanes; int audio_en; int dp_lane0_swing_reg_cnt; - int lane0_reg_data[DP_TX_SWING_REG_CNT]; + u8 lane0_reg_data[DP_TX_SWING_REG_CNT]; int dp_lane1_swing_reg_cnt; - int lane1_reg_data[DP_TX_SWING_REG_CNT]; + u8 lane1_reg_data[DP_TX_SWING_REG_CNT]; u32 low_power_mode; struct device_node *mipi_host_node; };
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 3a745b51cddafade99aaea1b93aad31e9614e230 ]
All of the resources used by this driver has managed interfaces, so use them. Otherwise we will get the following splat:
[ 4.472703] denali-nand-pci 0000:00:05.0: timeout while waiting for irq 0x1000 [ 4.474071] denali-nand-pci: probe of 0000:00:05.0 failed with error -5 [ 4.473538] nand: No NAND device found [ 4.474068] BUG: unable to handle page fault for address: ffffc90005000410 [ 4.475169] #PF: supervisor write access in kernel mode [ 4.475579] #PF: error_code(0x0002) - not-present page [ 4.478362] RIP: 0010:iowrite32+0x9/0x50 [ 4.486068] Call Trace: [ 4.486269] <IRQ> [ 4.486443] denali_isr+0x15b/0x300 [denali] [ 4.486788] ? denali_direct_write+0x50/0x50 [denali] [ 4.487189] __handle_irq_event_percpu+0x161/0x3b0 [ 4.487571] handle_irq_event+0x7d/0x1b0 [ 4.487884] handle_fasteoi_irq+0x2b0/0x770 [ 4.488219] __common_interrupt+0xc8/0x1b0 [ 4.488549] common_interrupt+0x9a/0xc0
Fixes: 93db446a424c ("mtd: nand: move raw NAND related code to the raw/ subdir") Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220411125808.958276-1-zheyuma97@gmail.co... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/raw/denali_pci.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/mtd/nand/raw/denali_pci.c b/drivers/mtd/nand/raw/denali_pci.c index 20c085a30adc..de7e722d3826 100644 --- a/drivers/mtd/nand/raw/denali_pci.c +++ b/drivers/mtd/nand/raw/denali_pci.c @@ -74,22 +74,21 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return ret; }
- denali->reg = ioremap(csr_base, csr_len); + denali->reg = devm_ioremap(denali->dev, csr_base, csr_len); if (!denali->reg) { dev_err(&dev->dev, "Spectra: Unable to remap memory region\n"); return -ENOMEM; }
- denali->host = ioremap(mem_base, mem_len); + denali->host = devm_ioremap(denali->dev, mem_base, mem_len); if (!denali->host) { dev_err(&dev->dev, "Spectra: ioremap failed!"); - ret = -ENOMEM; - goto out_unmap_reg; + return -ENOMEM; }
ret = denali_init(denali); if (ret) - goto out_unmap_host; + return ret;
nsels = denali->nbanks;
@@ -117,10 +116,6 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
out_remove_denali: denali_remove(denali); -out_unmap_host: - iounmap(denali->host); -out_unmap_reg: - iounmap(denali->reg); return ret; }
@@ -129,8 +124,6 @@ static void denali_pci_remove(struct pci_dev *dev) struct denali_controller *denali = pci_get_drvdata(dev);
denali_remove(denali); - iounmap(denali->reg); - iounmap(denali->host); }
static struct pci_driver denali_pci_driver = {
From: Jonathan Teh jonathan.teh@outlook.com
[ Upstream commit 116c3f4a78ebe478d5ad5a038baf931e93e7d748 ]
Increase maximum brightness for Dream Cheeky to 63. Emperically determined based on testing in kernel 4.4 on this device:
Bus 003 Device 002: ID 1d34:0004 Dream Cheeky Webmail Notifier
Fixes: 6c7ad07e9e05 ("HID: migrate USB LED driver from usb misc to hid") Signed-off-by: Jonathan Teh jonathan.teh@outlook.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-led.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/hid-led.c b/drivers/hid/hid-led.c index c2c66ceca132..7d82f8d426bb 100644 --- a/drivers/hid/hid-led.c +++ b/drivers/hid/hid-led.c @@ -366,7 +366,7 @@ static const struct hidled_config hidled_configs[] = { .type = DREAM_CHEEKY, .name = "Dream Cheeky Webmail Notifier", .short_name = "dream_cheeky", - .max_brightness = 31, + .max_brightness = 63, .num_leds = 1, .report_size = 9, .report_type = RAW_REQUEST,
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 1af20714fedad238362571620be0bd690ded05b6 ]
'input' is a managed resource allocated with devm_input_allocate_device(), so there is no need to call input_free_device() explicitly or there will be a double free.
According to the doc of devm_input_allocate_device(): * Managed input devices do not need to be explicitly unregistered or * freed as it will be done automatically when owner device unbinds from * its driver (or binding fails).
Fixes: b7429ea53d6c ("HID: elan: Fix memleak in elan_input_configured") Fixes: 9a6a4193d65b ("HID: Add driver for USB ELAN Touchpad") Signed-off-by: Miaoqian Lin linmq006@gmail.com Acked-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-elan.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/hid/hid-elan.c b/drivers/hid/hid-elan.c index 3091355d48df..8e4a5528e25d 100644 --- a/drivers/hid/hid-elan.c +++ b/drivers/hid/hid-elan.c @@ -188,7 +188,6 @@ static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi) ret = input_mt_init_slots(input, ELAN_MAX_FINGERS, INPUT_MT_POINTER); if (ret) { hid_err(hdev, "Failed to init elan MT slots: %d\n", ret); - input_free_device(input); return ret; }
@@ -200,7 +199,6 @@ static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi) hid_err(hdev, "Failed to register elan input device: %d\n", ret); input_mt_destroy_slots(input); - input_free_device(input); return ret; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 9f15930bb2ef9f031d62ffc49629cbae89137733 ]
In the error handling path, the clk_prepare_enable() function call should be balanced by a corresponding 'clk_disable_unprepare()' call, as already done in the remove function.
Fixes: 3424e3a4f844 ("drm: bridge: analogix/dp: split exynos dp driver to bridge directory") Signed-off-by: Miaoqian Lin linmq006@gmail.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/20220420011644.25730-1-linmq00... Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/bridge/analogix/analogix_dp_core.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index eb590fb8e8d0..474ef88015ae 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1698,8 +1698,10 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dp->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(dp->reg_base)) - return ERR_CAST(dp->reg_base); + if (IS_ERR(dp->reg_base)) { + ret = PTR_ERR(dp->reg_base); + goto err_disable_clk; + }
dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd");
@@ -1711,7 +1713,8 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) if (IS_ERR(dp->hpd_gpiod)) { dev_err(dev, "error getting HDP GPIO: %ld\n", PTR_ERR(dp->hpd_gpiod)); - return ERR_CAST(dp->hpd_gpiod); + ret = PTR_ERR(dp->hpd_gpiod); + goto err_disable_clk; }
if (dp->hpd_gpiod) { @@ -1731,7 +1734,8 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data)
if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); - return ERR_PTR(-ENODEV); + ret = -ENODEV; + goto err_disable_clk; }
ret = devm_request_threaded_irq(&pdev->dev, dp->irq, @@ -1740,11 +1744,15 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) irq_flags, "analogix-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); - return ERR_PTR(ret); + goto err_disable_clk; } disable_irq(dp->irq);
return dp; + +err_disable_clk: + clk_disable_unprepare(dp->clock); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(analogix_dp_probe);
From: Wei Yongjun weiyongjun1@huawei.com
[ Upstream commit bab76514aca36bc513224525d5598da676938218 ]
KASAN report slab-out-of-bounds in __regmap_init as follows:
BUG: KASAN: slab-out-of-bounds in __regmap_init drivers/base/regmap/regmap.c:841 Read of size 1 at addr ffff88803678cdf1 by task xrun/9137
CPU: 0 PID: 9137 Comm: xrun Tainted: G W 5.18.0-rc2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0xe8/0x15a lib/dump_stack.c:88 print_report.cold+0xcd/0x69b mm/kasan/report.c:313 kasan_report+0x8e/0xc0 mm/kasan/report.c:491 __regmap_init+0x4540/0x4ba0 drivers/base/regmap/regmap.c:841 __devm_regmap_init+0x7a/0x100 drivers/base/regmap/regmap.c:1266 __devm_regmap_init_i2c+0x65/0x80 drivers/base/regmap/regmap-i2c.c:394 da9121_i2c_probe+0x386/0x6d1 drivers/regulator/da9121-regulator.c:1039 i2c_device_probe+0x959/0xac0 drivers/i2c/i2c-core-base.c:563
This happend when da9121 device is probe by da9121_i2c_id, but with invalid dts. Thus, chip->subvariant_id is set to -EINVAL, and later da9121_assign_chip_model() will access 'regmap' without init it.
Fix it by return -EINVAL from da9121_assign_chip_model() if 'chip->subvariant_id' is invalid.
Fixes: f3fbd5566f6a ("regulator: da9121: Add device variants") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wei Yongjun weiyongjun1@huawei.com Reviewed-by: Adam Ward Adam.Ward.Opensource@diasemi.com Link: https://lore.kernel.org/r/20220421090335.1876149-1-weiyongjun1@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/da9121-regulator.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index eb9df485bd8a..76e0e23bf598 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -1030,6 +1030,8 @@ static int da9121_assign_chip_model(struct i2c_client *i2c, chip->variant_id = DA9121_TYPE_DA9142; regmap = &da9121_2ch_regmap_config; break; + default: + return -EINVAL; }
/* Set these up for of_regulator_match call which may want .of_map_modes */
From: Nícolas F. R. A. Prado nfraprado@collabora.com
[ Upstream commit 7112e0b0a58be8575547eba6596c42710922674f ]
The configuration for mt8192 was incorrectly using the output formats from mt8173. Since the output formats for mt8192 are instead the same ones as for mt8183, which require two bus samples per pixel, the pixelclock and DDR edge setting were misconfigured. This made external displays unable to show the image.
Fix the issue by correcting the output format for mt8192 to be the same as for mt8183, fixing the usage of external displays for mt8192.
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220408013950.674... Fixes: be63f6e8601f ("drm/mediatek: dpi: Add output bus formats to driver data") Signed-off-by: Nícolas F. R. A. Prado nfraprado@collabora.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_dpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c b/drivers/gpu/drm/mediatek/mtk_dpi.c index 4554e2de1430..e61cd67b978f 100644 --- a/drivers/gpu/drm/mediatek/mtk_dpi.c +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -819,8 +819,8 @@ static const struct mtk_dpi_conf mt8192_conf = { .cal_factor = mt8183_calculate_factor, .reg_h_fre_con = 0xe0, .max_clock_khz = 150000, - .output_fmts = mt8173_output_fmts, - .num_output_fmts = ARRAY_SIZE(mt8173_output_fmts), + .output_fmts = mt8183_output_fmts, + .num_output_fmts = ARRAY_SIZE(mt8183_output_fmts), };
static int mtk_dpi_probe(struct platform_device *pdev)
From: Marco Elver elver@google.com
[ Upstream commit 78ed93d72ded679e3caf0758357209887bda885f ]
With SIGTRAP on perf events, we have encountered termination of processes due to user space attempting to block delivery of SIGTRAP. Consider this case:
<set up SIGTRAP on a perf event> ... sigset_t s; sigemptyset(&s); sigaddset(&s, SIGTRAP | <and others>); sigprocmask(SIG_BLOCK, &s, ...); ... <perf event triggers>
When the perf event triggers, while SIGTRAP is blocked, force_sig_perf() will force the signal, but revert back to the default handler, thus terminating the task.
This makes sense for error conditions, but not so much for explicitly requested monitoring. However, the expectation is still that signals generated by perf events are synchronous, which will no longer be the case if the signal is blocked and delivered later.
To give user space the ability to clearly distinguish synchronous from asynchronous signals, introduce siginfo_t::si_perf_flags and TRAP_PERF_FLAG_ASYNC (opted for flags in case more binary information is required in future).
The resolution to the problem is then to (a) no longer force the signal (avoiding the terminations), but (b) tell user space via si_perf_flags if the signal was synchronous or not, so that such signals can be handled differently (e.g. let user space decide to ignore or consider the data imprecise).
The alternative of making the kernel ignore SIGTRAP on perf events if the signal is blocked may work for some usecases, but likely causes issues in others that then have to revert back to interception of sigprocmask() (which we want to avoid). [ A concrete example: when using breakpoint perf events to track data-flow, in a region of code where signals are blocked, data-flow can no longer be tracked accurately. When a relevant asynchronous signal is received after unblocking the signal, the data-flow tracking logic needs to know its state is imprecise. ]
Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events") Reported-by: Dmitry Vyukov dvyukov@google.com Signed-off-by: Marco Elver elver@google.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Geert Uytterhoeven geert@linux-m68k.org Tested-by: Dmitry Vyukov dvyukov@google.com Link: https://lore.kernel.org/r/20220404111204.935357-1-elver@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/kernel/signal.c | 1 + arch/arm64/kernel/signal.c | 1 + arch/arm64/kernel/signal32.c | 1 + arch/m68k/kernel/signal.c | 1 + arch/sparc/kernel/signal32.c | 1 + arch/sparc/kernel/signal_64.c | 1 + arch/x86/kernel/signal_compat.c | 2 ++ include/linux/compat.h | 1 + include/linux/sched/signal.h | 2 +- include/uapi/asm-generic/siginfo.h | 7 +++++++ kernel/events/core.c | 4 ++-- kernel/signal.c | 18 ++++++++++++++++-- 12 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 459abc5d1819..ea128e32e8ca 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -708,6 +708,7 @@ static_assert(offsetof(siginfo_t, si_upper) == 0x18); static_assert(offsetof(siginfo_t, si_pkey) == 0x14); static_assert(offsetof(siginfo_t, si_perf_data) == 0x10); static_assert(offsetof(siginfo_t, si_perf_type) == 0x14); +static_assert(offsetof(siginfo_t, si_perf_flags) == 0x18); static_assert(offsetof(siginfo_t, si_band) == 0x0c); static_assert(offsetof(siginfo_t, si_fd) == 0x10); static_assert(offsetof(siginfo_t, si_call_addr) == 0x0c); diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 4a4122ef6f39..41b5d9d3672a 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -1011,6 +1011,7 @@ static_assert(offsetof(siginfo_t, si_upper) == 0x28); static_assert(offsetof(siginfo_t, si_pkey) == 0x20); static_assert(offsetof(siginfo_t, si_perf_data) == 0x18); static_assert(offsetof(siginfo_t, si_perf_type) == 0x20); +static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24); static_assert(offsetof(siginfo_t, si_band) == 0x10); static_assert(offsetof(siginfo_t, si_fd) == 0x18); static_assert(offsetof(siginfo_t, si_call_addr) == 0x10); diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c index d984282b979f..4700f8522d27 100644 --- a/arch/arm64/kernel/signal32.c +++ b/arch/arm64/kernel/signal32.c @@ -487,6 +487,7 @@ static_assert(offsetof(compat_siginfo_t, si_upper) == 0x18); static_assert(offsetof(compat_siginfo_t, si_pkey) == 0x14); static_assert(offsetof(compat_siginfo_t, si_perf_data) == 0x10); static_assert(offsetof(compat_siginfo_t, si_perf_type) == 0x14); +static_assert(offsetof(compat_siginfo_t, si_perf_flags) == 0x18); static_assert(offsetof(compat_siginfo_t, si_band) == 0x0c); static_assert(offsetof(compat_siginfo_t, si_fd) == 0x10); static_assert(offsetof(compat_siginfo_t, si_call_addr) == 0x0c); diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index 49533f65958a..b9f6908a31bc 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -625,6 +625,7 @@ static inline void siginfo_build_tests(void) /* _sigfault._perf */ BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x10); BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x14); + BUILD_BUG_ON(offsetof(siginfo_t, si_perf_flags) != 0x18);
/* _sigpoll */ BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c); diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index f9fe502b81c6..dad38960d1a8 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -779,5 +779,6 @@ static_assert(offsetof(compat_siginfo_t, si_upper) == 0x18); static_assert(offsetof(compat_siginfo_t, si_pkey) == 0x14); static_assert(offsetof(compat_siginfo_t, si_perf_data) == 0x10); static_assert(offsetof(compat_siginfo_t, si_perf_type) == 0x14); +static_assert(offsetof(compat_siginfo_t, si_perf_flags) == 0x18); static_assert(offsetof(compat_siginfo_t, si_band) == 0x0c); static_assert(offsetof(compat_siginfo_t, si_fd) == 0x10); diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 8b9fc76cd3e0..570e43e6fda5 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -590,5 +590,6 @@ static_assert(offsetof(siginfo_t, si_upper) == 0x28); static_assert(offsetof(siginfo_t, si_pkey) == 0x20); static_assert(offsetof(siginfo_t, si_perf_data) == 0x18); static_assert(offsetof(siginfo_t, si_perf_type) == 0x20); +static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24); static_assert(offsetof(siginfo_t, si_band) == 0x10); static_assert(offsetof(siginfo_t, si_fd) == 0x14); diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c index b52407c56000..879ef8c72f5c 100644 --- a/arch/x86/kernel/signal_compat.c +++ b/arch/x86/kernel/signal_compat.c @@ -149,8 +149,10 @@ static inline void signal_compat_build_tests(void)
BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18); BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20); + BUILD_BUG_ON(offsetof(siginfo_t, si_perf_flags) != 0x24); BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10); BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14); + BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_flags) != 0x18);
CHECK_CSI_OFFSET(_sigpoll); CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int)); diff --git a/include/linux/compat.h b/include/linux/compat.h index 1c758b0e0359..01fddf72a81f 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -235,6 +235,7 @@ typedef struct compat_siginfo { struct { compat_ulong_t _data; u32 _type; + u32 _flags; } _perf; }; } _sigfault; diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 3c8b34876744..bab7cc56b13a 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -320,7 +320,7 @@ int send_sig_mceerr(int code, void __user *, short, struct task_struct *);
int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper); int force_sig_pkuerr(void __user *addr, u32 pkey); -int force_sig_perf(void __user *addr, u32 type, u64 sig_data); +int send_sig_perf(void __user *addr, u32 type, u64 sig_data);
int force_sig_ptrace_errno_trap(int errno, void __user *addr); int force_sig_fault_trapno(int sig, int code, void __user *addr, int trapno); diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h index 3ba180f550d7..ffbe4cec9f32 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -99,6 +99,7 @@ union __sifields { struct { unsigned long _data; __u32 _type; + __u32 _flags; } _perf; }; } _sigfault; @@ -164,6 +165,7 @@ typedef struct siginfo { #define si_pkey _sifields._sigfault._addr_pkey._pkey #define si_perf_data _sifields._sigfault._perf._data #define si_perf_type _sifields._sigfault._perf._type +#define si_perf_flags _sifields._sigfault._perf._flags #define si_band _sifields._sigpoll._band #define si_fd _sifields._sigpoll._fd #define si_call_addr _sifields._sigsys._call_addr @@ -270,6 +272,11 @@ typedef struct siginfo { * that are of the form: ((PTRACE_EVENT_XXX << 8) | SIGTRAP) */
+/* + * Flags for si_perf_flags if SIGTRAP si_code is TRAP_PERF. + */ +#define TRAP_PERF_FLAG_ASYNC (1u << 0) + /* * SIGCHLD si_codes */ diff --git a/kernel/events/core.c b/kernel/events/core.c index 7f1e4c5897e7..950b25c3f210 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6428,8 +6428,8 @@ static void perf_sigtrap(struct perf_event *event) if (current->flags & PF_EXITING) return;
- force_sig_perf((void __user *)event->pending_addr, - event->attr.type, event->attr.sig_data); + send_sig_perf((void __user *)event->pending_addr, + event->attr.type, event->attr.sig_data); }
static void perf_pending_event_disable(struct perf_event *event) diff --git a/kernel/signal.c b/kernel/signal.c index 30cd1ca43bcd..e43bc2a692f5 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1805,7 +1805,7 @@ int force_sig_pkuerr(void __user *addr, u32 pkey) } #endif
-int force_sig_perf(void __user *addr, u32 type, u64 sig_data) +int send_sig_perf(void __user *addr, u32 type, u64 sig_data) { struct kernel_siginfo info;
@@ -1817,7 +1817,18 @@ int force_sig_perf(void __user *addr, u32 type, u64 sig_data) info.si_perf_data = sig_data; info.si_perf_type = type;
- return force_sig_info(&info); + /* + * Signals generated by perf events should not terminate the whole + * process if SIGTRAP is blocked, however, delivering the signal + * asynchronously is better than not delivering at all. But tell user + * space if the signal was asynchronous, so it can clearly be + * distinguished from normal synchronous ones. + */ + info.si_perf_flags = sigismember(¤t->blocked, info.si_signo) ? + TRAP_PERF_FLAG_ASYNC : + 0; + + return send_sig_info(info.si_signo, &info, current); }
/** @@ -3432,6 +3443,7 @@ void copy_siginfo_to_external32(struct compat_siginfo *to, to->si_addr = ptr_to_compat(from->si_addr); to->si_perf_data = from->si_perf_data; to->si_perf_type = from->si_perf_type; + to->si_perf_flags = from->si_perf_flags; break; case SIL_CHLD: to->si_pid = from->si_pid; @@ -3509,6 +3521,7 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to, to->si_addr = compat_ptr(from->si_addr); to->si_perf_data = from->si_perf_data; to->si_perf_type = from->si_perf_type; + to->si_perf_flags = from->si_perf_flags; break; case SIL_CHLD: to->si_pid = from->si_pid; @@ -4722,6 +4735,7 @@ static inline void siginfo_buildtime_checks(void) CHECK_OFFSET(si_pkey); CHECK_OFFSET(si_perf_data); CHECK_OFFSET(si_perf_type); + CHECK_OFFSET(si_perf_flags);
/* sigpoll */ CHECK_OFFSET(si_band);
From: Chengming Zhou zhouchengming@bytedance.com
[ Upstream commit 64eaf50731ac0a8c76ce2fedd50ef6652aabc5ff ]
Since commit 23127296889f ("sched/fair: Update scale invariance of PELT") change to use rq_clock_pelt() instead of rq_clock_task(), we should also use rq_clock_pelt() for throttled_clock_task_time and throttled_clock_task accounting to get correct cfs_rq_clock_pelt() of throttled cfs_rq. And rename throttled_clock_task(_time) to be clock_pelt rather than clock_task.
Fixes: 23127296889f ("sched/fair: Update scale invariance of PELT") Signed-off-by: Chengming Zhou zhouchengming@bytedance.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Ben Segall bsegall@google.com Reviewed-by: Vincent Guittot vincent.guittot@linaro.org Link: https://lore.kernel.org/r/20220408115309.81603-1-zhouchengming@bytedance.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 8 ++++---- kernel/sched/pelt.h | 4 ++-- kernel/sched/sched.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a68482d66535..cc8daa3dcc8b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4846,8 +4846,8 @@ static int tg_unthrottle_up(struct task_group *tg, void *data)
cfs_rq->throttle_count--; if (!cfs_rq->throttle_count) { - cfs_rq->throttled_clock_task_time += rq_clock_task(rq) - - cfs_rq->throttled_clock_task; + cfs_rq->throttled_clock_pelt_time += rq_clock_pelt(rq) - + cfs_rq->throttled_clock_pelt;
/* Add cfs_rq with load or one or more already running entities to the list */ if (!cfs_rq_is_decayed(cfs_rq) || cfs_rq->nr_running) @@ -4864,7 +4864,7 @@ static int tg_throttle_down(struct task_group *tg, void *data)
/* group is entering throttled state, stop time */ if (!cfs_rq->throttle_count) { - cfs_rq->throttled_clock_task = rq_clock_task(rq); + cfs_rq->throttled_clock_pelt = rq_clock_pelt(rq); list_del_leaf_cfs_rq(cfs_rq); } cfs_rq->throttle_count++; @@ -5308,7 +5308,7 @@ static void sync_throttle(struct task_group *tg, int cpu) pcfs_rq = tg->parent->cfs_rq[cpu];
cfs_rq->throttle_count = pcfs_rq->throttle_count; - cfs_rq->throttled_clock_task = rq_clock_task(cpu_rq(cpu)); + cfs_rq->throttled_clock_pelt = rq_clock_pelt(cpu_rq(cpu)); }
/* conditionally throttle active cfs_rq's from put_prev_entity() */ diff --git a/kernel/sched/pelt.h b/kernel/sched/pelt.h index c336f5f481bc..4ff2ed4f8fa1 100644 --- a/kernel/sched/pelt.h +++ b/kernel/sched/pelt.h @@ -145,9 +145,9 @@ static inline u64 rq_clock_pelt(struct rq *rq) static inline u64 cfs_rq_clock_pelt(struct cfs_rq *cfs_rq) { if (unlikely(cfs_rq->throttle_count)) - return cfs_rq->throttled_clock_task - cfs_rq->throttled_clock_task_time; + return cfs_rq->throttled_clock_pelt - cfs_rq->throttled_clock_pelt_time;
- return rq_clock_pelt(rq_of(cfs_rq)) - cfs_rq->throttled_clock_task_time; + return rq_clock_pelt(rq_of(cfs_rq)) - cfs_rq->throttled_clock_pelt_time; } #else static inline u64 cfs_rq_clock_pelt(struct cfs_rq *cfs_rq) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 2133aea22086..0d2b6b758f32 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -603,8 +603,8 @@ struct cfs_rq { s64 runtime_remaining;
u64 throttled_clock; - u64 throttled_clock_task; - u64 throttled_clock_task_time; + u64 throttled_clock_pelt; + u64 throttled_clock_pelt_time; int throttled; int throttle_count; struct list_head throttled_list;
From: Chengming Zhou zhouchengming@bytedance.com
[ Upstream commit 890d550d7dbac7a31ecaa78732aa22be282bb6b8 ]
Martin find it confusing when look at the /proc/pressure/cpu output, and found no hint about that CPU "full" line in psi Documentation.
% cat /proc/pressure/cpu some avg10=0.92 avg60=0.91 avg300=0.73 total=933490489 full avg10=0.22 avg60=0.23 avg300=0.16 total=358783277
The PSI_CPU_FULL state is introduced by commit e7fcd7622823 ("psi: Add PSI_CPU_FULL state"), which mainly for cgroup level, but also counted at the system level as a side effect.
Naturally, the FULL state doesn't exist for the CPU resource at the system level. These "full" numbers can come from CPU idle schedule latency. For example, t1 is the time when task wakeup on an idle CPU, t2 is the time when CPU pick and switch to it. The delta of (t2 - t1) will be in CPU_FULL state.
Another case all processes can be stalled is when all cgroups have been throttled at the same time, which unlikely to happen.
Anyway, CPU_FULL metric is meaningless and confusing at the system level. So this patch will report zeroes for CPU full at the system level, and update psi Documentation accordingly.
Fixes: e7fcd7622823 ("psi: Add PSI_CPU_FULL state") Reported-by: Martin Steigerwald Martin.Steigerwald@proact.de Suggested-by: Johannes Weiner hannes@cmpxchg.org Signed-off-by: Chengming Zhou zhouchengming@bytedance.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Johannes Weiner hannes@cmpxchg.org Link: https://lore.kernel.org/r/20220408121914.82855-1-zhouchengming@bytedance.com Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/accounting/psi.rst | 9 ++++----- kernel/sched/psi.c | 15 +++++++++------ 2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/Documentation/accounting/psi.rst b/Documentation/accounting/psi.rst index 860fe651d645..5e40b3f437f9 100644 --- a/Documentation/accounting/psi.rst +++ b/Documentation/accounting/psi.rst @@ -37,11 +37,7 @@ Pressure interface Pressure information for each resource is exported through the respective file in /proc/pressure/ -- cpu, memory, and io.
-The format for CPU is as such:: - - some avg10=0.00 avg60=0.00 avg300=0.00 total=0 - -and for memory and IO:: +The format is as such::
some avg10=0.00 avg60=0.00 avg300=0.00 total=0 full avg10=0.00 avg60=0.00 avg300=0.00 total=0 @@ -58,6 +54,9 @@ situation from a state where some tasks are stalled but the CPU is still doing productive work. As such, time spent in this subset of the stall state is tracked separately and exported in the "full" averages.
+CPU full is undefined at the system level, but has been reported +since 5.13, so it is set to zero for backward compatibility. + The ratios (in %) are tracked as recent trends over ten, sixty, and three hundred second windows, which gives insight into short term events as well as medium and long term trends. The total absolute stall time diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index a4fa3aadfcba..ed9fb557dadd 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -1060,14 +1060,17 @@ int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res) mutex_unlock(&group->avgs_lock);
for (full = 0; full < 2; full++) { - unsigned long avg[3]; - u64 total; + unsigned long avg[3] = { 0, }; + u64 total = 0; int w;
- for (w = 0; w < 3; w++) - avg[w] = group->avg[res * 2 + full][w]; - total = div_u64(group->total[PSI_AVGS][res * 2 + full], - NSEC_PER_USEC); + /* CPU FULL is undefined at the system level */ + if (!(group == &psi_system && res == PSI_CPU && full)) { + for (w = 0; w < 3; w++) + avg[w] = group->avg[res * 2 + full][w]; + total = div_u64(group->total[PSI_AVGS][res * 2 + full], + NSEC_PER_USEC); + }
seq_printf(m, "%s avg10=%lu.%02lu avg60=%lu.%02lu avg300=%lu.%02lu total=%llu\n", full ? "full" : "some",
From: Zheng Yongjun zhengyongjun3@huawei.com
[ Upstream commit cc470d55343056d6b2a5c32e10e0aad06f324078 ]
If the device is already in a runtime PM enabled state pm_runtime_get_sync() will return 1, so a test for negative value should be used to check for errors.
Fixes: deba25800a12b ("spi: Add driver for IMG SPFI controller") Signed-off-by: Zheng Yongjun zhengyongjun3@huawei.com Link: https://lore.kernel.org/r/20220422062641.10486-1-zhengyongjun3@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-img-spfi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 5f05d519fbbd..71376b6df89d 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -731,7 +731,7 @@ static int img_spfi_resume(struct device *dev) int ret;
ret = pm_runtime_get_sync(dev); - if (ret) { + if (ret < 0) { pm_runtime_put_noidle(dev); return ret; }
From: Robert Foss robert.foss@linaro.org
[ Upstream commit c5060b09f460fc83846d361018a124fcade1b9e9 ]
it6505 depends on DRM_DP_AUX_BUS, the kconfig for it6505 should reflect this dependency using 'select'.
Fixes: b5c84a9edcd4 ("drm/bridge: add it6505 driver") Reported-by: kernel test robot lkp@intel.com Suggested-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Robert Foss robert.foss@linaro.org Reviewed-by: Neil Armstrong narmstrong@baylibre.com Link: https://patchwork.freedesktop.org/patch/msgid/20220421131415.1289469-1-rober... 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 becd9867f3a0..be2fc4791c1d 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -77,6 +77,7 @@ config DRM_DISPLAY_CONNECTOR config DRM_ITE_IT6505 tristate "ITE IT6505 DisplayPort bridge" depends on OF + select DRM_DP_AUX_BUS select DRM_DP_HELPER select DRM_KMS_HELPER select DRM_DP_HELPER
From: Schspa Shi schspa@gmail.com
[ Upstream commit f346e96267cd76175d6c201b40f770c0116a8a04 ]
When cpufreq online fails, the policy->cpus mask is not cleared and policy->rwsem is released too early, so the driver can be invoked via the cpuinfo_cur_freq sysfs attribute while its ->offline() or ->exit() callbacks are being run.
Take policy->clk as an example:
static int cpufreq_online(unsigned int cpu) { ... // policy->cpus != 0 at this time down_write(&policy->rwsem); ret = cpufreq_add_dev_interface(policy); up_write(&policy->rwsem);
return 0;
out_destroy_policy: for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j)); up_write(&policy->rwsem); ... out_exit_policy: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); clk_put(policy->clk); // policy->clk is a wild pointer ... ^ | Another process access __cpufreq_get cpufreq_verify_current_freq cpufreq_generic_get // acces wild pointer of policy->clk; | | out_offline_policy: | cpufreq_policy_free(policy); | // deleted here, and will wait for no body reference cpufreq_policy_put_kobj(policy); }
Address this by modifying cpufreq_online() to release policy->rwsem in the error path after the driver callbacks have run and to clear policy->cpus before releasing the semaphore.
Fixes: 7106e02baed4 ("cpufreq: release policy->rwsem on error") Signed-off-by: Schspa Shi schspa@gmail.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/cpufreq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index fbaa8e6c7d23..233e8af48848 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1534,8 +1534,6 @@ static int cpufreq_online(unsigned int cpu) for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j));
- up_write(&policy->rwsem); - out_offline_policy: if (cpufreq_driver->offline) cpufreq_driver->offline(policy); @@ -1544,6 +1542,9 @@ static int cpufreq_online(unsigned int cpu) if (cpufreq_driver->exit) cpufreq_driver->exit(policy);
+ cpumask_clear(policy->cpus); + up_write(&policy->rwsem); + out_free_policy: cpufreq_policy_free(policy); return ret;
From: John Ogness john.ogness@linutronix.de
[ Upstream commit 1f5d783094cf28b4905f51cad846eb5d1db6673e ]
It is important that any new records are visible to preparing waiters before the waker checks if the wait queue is empty. Otherwise it is possible that:
- there are new records available - the waker sees an empty wait queue and does not wake - the preparing waiter sees no new records and begins to wait
This is exactly the problem that the function description of waitqueue_active() warns about.
Use wq_has_sleeper() instead of waitqueue_active() because it includes the necessary full memory barrier.
Signed-off-by: John Ogness john.ogness@linutronix.de Reviewed-by: Petr Mladek pmladek@suse.com Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20220421212250.565456-4-john.ogness@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/printk/printk.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index da03c15ecc89..ed6f20992915 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -746,8 +746,19 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, goto out; }
+ /* + * Guarantee this task is visible on the waitqueue before + * checking the wake condition. + * + * The full memory barrier within set_current_state() of + * prepare_to_wait_event() pairs with the full memory barrier + * within wq_has_sleeper(). + * + * This pairs with wake_up_klogd:A. + */ ret = wait_event_interruptible(log_wait, - prb_read_valid(prb, atomic64_read(&user->seq), r)); + prb_read_valid(prb, + atomic64_read(&user->seq), r)); /* LMM(devkmsg_read:A) */ if (ret) goto out; } @@ -1513,7 +1524,18 @@ static int syslog_print(char __user *buf, int size) seq = syslog_seq;
mutex_unlock(&syslog_lock); - len = wait_event_interruptible(log_wait, prb_read_valid(prb, seq, NULL)); + /* + * Guarantee this task is visible on the waitqueue before + * checking the wake condition. + * + * The full memory barrier within set_current_state() of + * prepare_to_wait_event() pairs with the full memory barrier + * within wq_has_sleeper(). + * + * This pairs with wake_up_klogd:A. + */ + len = wait_event_interruptible(log_wait, + prb_read_valid(prb, seq, NULL)); /* LMM(syslog_print:A) */ mutex_lock(&syslog_lock);
if (len) @@ -3316,7 +3338,18 @@ void wake_up_klogd(void) return;
preempt_disable(); - if (waitqueue_active(&log_wait)) { + /* + * Guarantee any new records can be seen by tasks preparing to wait + * before this context checks if the wait queue is empty. + * + * The full memory barrier within wq_has_sleeper() pairs with the full + * memory barrier within set_current_state() of + * prepare_to_wait_event(), which is called after ___wait_event() adds + * the waiter but before it has checked the wait condition. + * + * This pairs with devkmsg_read:A and syslog_print:A. + */ + if (wq_has_sleeper(&log_wait)) { /* LMM(wake_up_klogd:A) */ this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); }
From: John Ogness john.ogness@linutronix.de
[ Upstream commit 5341b93dea8c39d7612f7a227015d4b1d5cf30db ]
When printk() is called from safe or NMI contexts, it will directly store the record (vprintk_store()) and then defer the console output. However, defer_console_output() only causes console printing and does not wake any waiters of new records.
Wake waiters from defer_console_output() so that they also are aware of the new records from safe and NMI contexts.
Fixes: 03fc7f9c99c1 ("printk/nmi: Prevent deadlock when accessing the main log buffer in NMI") Signed-off-by: John Ogness john.ogness@linutronix.de Reviewed-by: Petr Mladek pmladek@suse.com Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20220421212250.565456-6-john.ogness@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/printk/printk.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index ed6f20992915..1ead794fc2f4 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -754,7 +754,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, * prepare_to_wait_event() pairs with the full memory barrier * within wq_has_sleeper(). * - * This pairs with wake_up_klogd:A. + * This pairs with __wake_up_klogd:A. */ ret = wait_event_interruptible(log_wait, prb_read_valid(prb, @@ -1532,7 +1532,7 @@ static int syslog_print(char __user *buf, int size) * prepare_to_wait_event() pairs with the full memory barrier * within wq_has_sleeper(). * - * This pairs with wake_up_klogd:A. + * This pairs with __wake_up_klogd:A. */ len = wait_event_interruptible(log_wait, prb_read_valid(prb, seq, NULL)); /* LMM(syslog_print:A) */ @@ -3332,7 +3332,7 @@ static void wake_up_klogd_work_func(struct irq_work *irq_work) static DEFINE_PER_CPU(struct irq_work, wake_up_klogd_work) = IRQ_WORK_INIT_LAZY(wake_up_klogd_work_func);
-void wake_up_klogd(void) +static void __wake_up_klogd(int val) { if (!printk_percpu_data_ready()) return; @@ -3349,22 +3349,26 @@ void wake_up_klogd(void) * * This pairs with devkmsg_read:A and syslog_print:A. */ - if (wq_has_sleeper(&log_wait)) { /* LMM(wake_up_klogd:A) */ - this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); + if (wq_has_sleeper(&log_wait) || /* LMM(__wake_up_klogd:A) */ + (val & PRINTK_PENDING_OUTPUT)) { + this_cpu_or(printk_pending, val); irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); } preempt_enable(); }
-void defer_console_output(void) +void wake_up_klogd(void) { - if (!printk_percpu_data_ready()) - return; + __wake_up_klogd(PRINTK_PENDING_WAKEUP); +}
- preempt_disable(); - this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT); - irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); - preempt_enable(); +void defer_console_output(void) +{ + /* + * New messages may have been added directly to the ringbuffer + * using vprintk_store(), so wake any waiters as well. + */ + __wake_up_klogd(PRINTK_PENDING_WAKEUP | PRINTK_PENDING_OUTPUT); }
void printk_trigger_flush(void)
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 2dc509305cf956381532792cb8dceef2b1504765 ]
The "rxstatus->rs_keyix" eventually gets passed to test_bit() so we need to ensure that it is within the bitmap.
drivers/net/wireless/ath/ath9k/common.c:46 ath9k_cmn_rx_accept() error: passing untrusted data 'rx_stats->rs_keyix' to 'test_bit()'
Fixes: 4ed1a8d4a257 ("ath9k_htc: use ath9k_cmn_rx_accept") Signed-off-by: Dan Carpenter dan.carpenter@oracle.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/20220409061225.GA5447@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 6a850a0bfa8a..a23eaca0326d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1016,6 +1016,14 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, goto rx_next; }
+ if (rxstatus->rs_keyix >= ATH_KEYMAX && + rxstatus->rs_keyix != ATH9K_RXKEYIX_INVALID) { + ath_dbg(common, ANY, + "Invalid keyix, dropping (keyix: %d)\n", + rxstatus->rs_keyix); + goto rx_next; + } + /* Get the RX status information */
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
From: Laurentiu Palcu laurentiu.palcu@oss.nxp.com
[ Upstream commit 365ab7ebc24eebb42b9e020aeb440d51af8960cd ]
When removing the max9286 module we get a kernel oops:
Unable to handle kernel paging request at virtual address 000000aa00000094 Mem abort info: ESR = 0x96000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 user pgtable: 4k pages, 48-bit VAs, pgdp=0000000880d85000 [000000aa00000094] pgd=0000000000000000, p4d=0000000000000000 Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: fsl_jr_uio caam_jr rng_core libdes caamkeyblob_desc caamhash_desc caamalg_desc crypto_engine max9271 authenc crct10dif_ce mxc_jpeg_encdec CPU: 2 PID: 713 Comm: rmmod Tainted: G C 5.15.5-00057-gaebcd29c8ed7-dirty #5 Hardware name: Freescale i.MX8QXP MEK (DT) pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : i2c_mux_del_adapters+0x24/0xf0 lr : max9286_remove+0x28/0xd0 [max9286] sp : ffff800013a9bbf0 x29: ffff800013a9bbf0 x28: ffff00080b6da940 x27: 0000000000000000 x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000 x23: ffff000801a5b970 x22: ffff0008048b0890 x21: ffff800009297000 x20: ffff0008048b0f70 x19: 000000aa00000064 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 0000000000000014 x13: 0000000000000000 x12: ffff000802da49e8 x11: ffff000802051918 x10: ffff000802da4920 x9 : ffff000800030098 x8 : 0101010101010101 x7 : 7f7f7f7f7f7f7f7f x6 : fefefeff6364626d x5 : 8080808000000000 x4 : 0000000000000000 x3 : 0000000000000000 x2 : ffffffffffffffff x1 : ffff00080b6da940 x0 : 0000000000000000 Call trace: i2c_mux_del_adapters+0x24/0xf0 max9286_remove+0x28/0xd0 [max9286] i2c_device_remove+0x40/0x110 __device_release_driver+0x188/0x234 driver_detach+0xc4/0x150 bus_remove_driver+0x60/0xe0 driver_unregister+0x34/0x64 i2c_del_driver+0x58/0xa0 max9286_i2c_driver_exit+0x1c/0x490 [max9286] __arm64_sys_delete_module+0x194/0x260 invoke_syscall+0x48/0x114 el0_svc_common.constprop.0+0xd4/0xfc do_el0_svc+0x2c/0x94 el0_svc+0x28/0x80 el0t_64_sync_handler+0xa8/0x130 el0t_64_sync+0x1a0/0x1a4
The Oops happens because the I2C client data does not point to max9286_priv anymore but to v4l2_subdev. The change happened in max9286_init() which calls v4l2_i2c_subdev_init() later on...
Besides fixing the max9286_remove() function, remove the call to i2c_set_clientdata() in max9286_probe(), to avoid confusion, and make the necessary changes to max9286_init() so that it doesn't have to use i2c_get_clientdata() in order to fetch the pointer to priv.
Fixes: 66d8c9d2422d ("media: i2c: Add MAX9286 driver") Signed-off-by: Laurentiu Palcu laurentiu.palcu@oss.nxp.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/max9286.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index d2a4915ed9f7..3684faa72253 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -1147,22 +1147,18 @@ static int max9286_poc_enable(struct max9286_priv *priv, bool enable) return ret; }
-static int max9286_init(struct device *dev) +static int max9286_init(struct max9286_priv *priv) { - struct max9286_priv *priv; - struct i2c_client *client; + struct i2c_client *client = priv->client; int ret;
- client = to_i2c_client(dev); - priv = i2c_get_clientdata(client); - ret = max9286_poc_enable(priv, true); if (ret) return ret;
ret = max9286_setup(priv); if (ret) { - dev_err(dev, "Unable to setup max9286\n"); + dev_err(&client->dev, "Unable to setup max9286\n"); goto err_poc_disable; }
@@ -1172,13 +1168,13 @@ static int max9286_init(struct device *dev) */ ret = max9286_v4l2_register(priv); if (ret) { - dev_err(dev, "Failed to register with V4L2\n"); + dev_err(&client->dev, "Failed to register with V4L2\n"); goto err_poc_disable; }
ret = max9286_i2c_mux_init(priv); if (ret) { - dev_err(dev, "Unable to initialize I2C multiplexer\n"); + dev_err(&client->dev, "Unable to initialize I2C multiplexer\n"); goto err_v4l2_register; }
@@ -1333,7 +1329,6 @@ static int max9286_probe(struct i2c_client *client) mutex_init(&priv->mutex);
priv->client = client; - i2c_set_clientdata(client, priv);
priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_HIGH); @@ -1369,7 +1364,7 @@ static int max9286_probe(struct i2c_client *client) if (ret) goto err_powerdown;
- ret = max9286_init(&client->dev); + ret = max9286_init(priv); if (ret < 0) goto err_cleanup_dt;
@@ -1385,7 +1380,7 @@ static int max9286_probe(struct i2c_client *client)
static int max9286_remove(struct i2c_client *client) { - struct max9286_priv *priv = i2c_get_clientdata(client); + struct max9286_priv *priv = sd_to_max9286(i2c_get_clientdata(client));
i2c_mux_del_adapters(priv->mux);
From: Ming Qian ming.qian@nxp.com
[ Upstream commit d9a6a70d65cd7d25bad00580157ad660330023d8 ]
For interlaced frame, the amphion vpu will store the two fields sequential into one buffer, top-bottom order so the field should be set to V4L2_FIELD_SEQ_TB. fix the previous bug that set it to V4L2_FIELD_SEQ_BT wrongly.
Fixes: 6de8d628df6e ("media: amphion: add v4l2 m2m vpu decoder stateful driver") Signed-off-by: Ming Qian ming.qian@nxp.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/media/platform/amphion/vdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 8f8dfd6ce2c6..c0dfede11ab7 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -782,7 +782,7 @@ static void vdec_init_fmt(struct vpu_inst *inst) if (vdec->codec_info.progressive) inst->cap_format.field = V4L2_FIELD_NONE; else - inst->cap_format.field = V4L2_FIELD_SEQ_BT; + inst->cap_format.field = V4L2_FIELD_SEQ_TB; if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT) vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709; if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit daf3999c12dcef14151710052fca9adfbc3967bc ]
The V4L2 stateful encoder uAPI specification requires that drivers support the ENCODER_CMD ioctl to allow draining of buffers. This however was not implemented, and causes issues for some userspace applications.
Implement support for the ENCODER_CMD ioctl using v4l2-mem2mem helpers. This is entirely based on existing code found in the vicodec test driver.
Fixes: 775fec69008d ("media: add Rockchip VPU JPEG encoder driver") Signed-off-by: Chen-Yu Tsai wenst@chromium.org 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/hantro/hantro_drv.c | 17 ++++++- drivers/staging/media/hantro/hantro_v4l2.c | 59 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index dc768884cb79..bd7d11032c94 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -56,6 +56,10 @@ dma_addr_t hantro_get_ref(struct hantro_ctx *ctx, u64 ts) return hantro_get_dec_buf_addr(ctx, buf); }
+static const struct v4l2_event hantro_eos_event = { + .type = V4L2_EVENT_EOS +}; + static void hantro_job_finish_no_pm(struct hantro_dev *vpu, struct hantro_ctx *ctx, enum vb2_buffer_state result) @@ -73,6 +77,12 @@ static void hantro_job_finish_no_pm(struct hantro_dev *vpu, src->sequence = ctx->sequence_out++; dst->sequence = ctx->sequence_cap++;
+ if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src)) { + dst->flags |= V4L2_BUF_FLAG_LAST; + v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); + v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); + } + v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, ctx->fh.m2m_ctx, result); } @@ -809,10 +819,13 @@ static int hantro_add_func(struct hantro_dev *vpu, unsigned int funcid) snprintf(vfd->name, sizeof(vfd->name), "%s-%s", match->compatible, funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER ? "enc" : "dec");
- if (funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER) + if (funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER) { vpu->encoder = func; - else + } else { vpu->decoder = func; + v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD); + }
video_set_drvdata(vfd, vpu);
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index 67148ba346f5..8b8276ff7b28 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -628,6 +628,38 @@ static int vidioc_s_selection(struct file *file, void *priv, return 0; }
+static const struct v4l2_event hantro_eos_event = { + .type = V4L2_EVENT_EOS +}; + +static int vidioc_encoder_cmd(struct file *file, void *priv, + struct v4l2_encoder_cmd *ec) +{ + struct hantro_ctx *ctx = fh_to_ctx(priv); + int ret; + + ret = v4l2_m2m_ioctl_try_encoder_cmd(file, priv, ec); + if (ret < 0) + return ret; + + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx)) || + !vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx))) + return 0; + + ret = v4l2_m2m_ioctl_encoder_cmd(file, priv, ec); + if (ret < 0) + return ret; + + if (ec->cmd == V4L2_ENC_CMD_STOP && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) + v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); + + if (ec->cmd == V4L2_ENC_CMD_START) + vb2_clear_last_buffer_dequeued(&ctx->fh.m2m_ctx->cap_q_ctx.q); + + return 0; +} + const struct v4l2_ioctl_ops hantro_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_framesizes = vidioc_enum_framesizes, @@ -657,6 +689,9 @@ const struct v4l2_ioctl_ops hantro_ioctl_ops = {
.vidioc_g_selection = vidioc_g_selection, .vidioc_s_selection = vidioc_s_selection, + + .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, + .vidioc_encoder_cmd = vidioc_encoder_cmd, };
static int @@ -744,6 +779,22 @@ static void hantro_buf_queue(struct vb2_buffer *vb) struct hantro_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+ 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)) { + unsigned int i; + + for (i = 0; i < vb->num_planes; i++) + vb2_set_plane_payload(vb, i, 0); + + vbuf->field = V4L2_FIELD_NONE; + vbuf->sequence = ctx->sequence_cap++; + + v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); + v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); + return; + } + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); }
@@ -759,6 +810,8 @@ static int hantro_start_streaming(struct vb2_queue *q, unsigned int count) struct hantro_ctx *ctx = vb2_get_drv_priv(q); int ret = 0;
+ v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); + if (V4L2_TYPE_IS_OUTPUT(q->type)) ctx->sequence_out = 0; else @@ -831,6 +884,12 @@ static void hantro_stop_streaming(struct vb2_queue *q) hantro_return_bufs(q, v4l2_m2m_src_buf_remove); else hantro_return_bufs(q, v4l2_m2m_dst_buf_remove); + + 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)) + v4l2_event_queue_fh(&ctx->fh, &hantro_eos_event); }
static void hantro_buf_request_complete(struct vb2_buffer *vb)
From: Chen-Yu Tsai wenst@chromium.org
[ Upstream commit 309373a3571ef7175bd9da0c9b13476a718e8478 ]
The payload size for encoder capture buffers is set by the driver upon finishing encoding each frame, based on the encoded length returned from hardware, and whatever header and padding length used. Setting a non-zero default serves no real purpose, and also causes issues if the capture buffer is returned to userspace unused, confusing the application.
Instead, always set the payload size to 0 for encoder capture buffers when preparing them.
Fixes: 775fec69008d ("media: add Rockchip VPU JPEG encoder driver") Fixes: 082aaecff35f ("media: hantro: Fix .buf_prepare") Signed-off-by: Chen-Yu Tsai wenst@chromium.org 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/hantro/hantro_v4l2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index 8b8276ff7b28..71a6279750bf 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -768,8 +768,12 @@ static int hantro_buf_prepare(struct vb2_buffer *vb) * (for OUTPUT buffers, if userspace passes 0 bytesused, v4l2-core sets * it to buffer length). */ - if (V4L2_TYPE_IS_CAPTURE(vq->type)) - vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); + if (V4L2_TYPE_IS_CAPTURE(vq->type)) { + if (ctx->is_encoder) + vb2_set_plane_payload(vb, 0, 0); + else + vb2_set_plane_payload(vb, 0, pix_fmt->plane_fmt[0].sizeimage); + }
return 0; }
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit c1cc03eafd319369075dd66b091bd8d309a5b726 ]
Usage of "state" for the device-specific data structure is confusing, as it can also refer to the subdev state. Rename the structure to mipi_csis_device, and the corresponding state variables to csis.
Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Jacopo Mondi jacopo@jmondi.org Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/nxp/imx-mipi-csis.c | 553 +++++++++++---------- 1 file changed, 277 insertions(+), 276 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c index 0a72734db55e..d9719d0b2f0a 100644 --- a/drivers/media/platform/nxp/imx-mipi-csis.c +++ b/drivers/media/platform/nxp/imx-mipi-csis.c @@ -310,7 +310,7 @@ struct mipi_csis_info { unsigned int num_clocks; };
-struct csi_state { +struct mipi_csis_device { struct device *dev; void __iomem *regs; struct clk_bulk_data *clks; @@ -487,59 +487,60 @@ static const struct csis_pix_format *find_csis_format(u32 code) * Hardware configuration */
-static inline u32 mipi_csis_read(struct csi_state *state, u32 reg) +static inline u32 mipi_csis_read(struct mipi_csis_device *csis, u32 reg) { - return readl(state->regs + reg); + return readl(csis->regs + reg); }
-static inline void mipi_csis_write(struct csi_state *state, u32 reg, u32 val) +static inline void mipi_csis_write(struct mipi_csis_device *csis, u32 reg, + u32 val) { - writel(val, state->regs + reg); + writel(val, csis->regs + reg); }
-static void mipi_csis_enable_interrupts(struct csi_state *state, bool on) +static void mipi_csis_enable_interrupts(struct mipi_csis_device *csis, bool on) { - mipi_csis_write(state, MIPI_CSIS_INT_MSK, on ? 0xffffffff : 0); - mipi_csis_write(state, MIPI_CSIS_DBG_INTR_MSK, on ? 0xffffffff : 0); + mipi_csis_write(csis, MIPI_CSIS_INT_MSK, on ? 0xffffffff : 0); + mipi_csis_write(csis, MIPI_CSIS_DBG_INTR_MSK, on ? 0xffffffff : 0); }
-static void mipi_csis_sw_reset(struct csi_state *state) +static void mipi_csis_sw_reset(struct mipi_csis_device *csis) { - u32 val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + u32 val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL);
- mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, + mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL, val | MIPI_CSIS_CMN_CTRL_RESET); usleep_range(10, 20); }
-static void mipi_csis_system_enable(struct csi_state *state, int on) +static void mipi_csis_system_enable(struct mipi_csis_device *csis, int on) { u32 val, mask;
- val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL); if (on) val |= MIPI_CSIS_CMN_CTRL_ENABLE; else val &= ~MIPI_CSIS_CMN_CTRL_ENABLE; - mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); + mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL, val);
- val = mipi_csis_read(state, MIPI_CSIS_DPHY_CMN_CTRL); + val = mipi_csis_read(csis, MIPI_CSIS_DPHY_CMN_CTRL); val &= ~MIPI_CSIS_DPHY_CMN_CTRL_ENABLE; if (on) { - mask = (1 << (state->bus.num_data_lanes + 1)) - 1; + mask = (1 << (csis->bus.num_data_lanes + 1)) - 1; val |= (mask & MIPI_CSIS_DPHY_CMN_CTRL_ENABLE); } - mipi_csis_write(state, MIPI_CSIS_DPHY_CMN_CTRL, val); + mipi_csis_write(csis, MIPI_CSIS_DPHY_CMN_CTRL, val); }
-/* Called with the state.lock mutex held */ -static void __mipi_csis_set_format(struct csi_state *state) +/* Called with the csis.lock mutex held */ +static void __mipi_csis_set_format(struct mipi_csis_device *csis) { - struct v4l2_mbus_framefmt *mf = &state->format_mbus[CSIS_PAD_SINK]; + struct v4l2_mbus_framefmt *mf = &csis->format_mbus[CSIS_PAD_SINK]; u32 val;
/* Color format */ - val = mipi_csis_read(state, MIPI_CSIS_ISP_CONFIG_CH(0)); + val = mipi_csis_read(csis, MIPI_CSIS_ISP_CONFIG_CH(0)); val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK | MIPI_CSIS_ISPCFG_PIXEL_MASK);
@@ -556,28 +557,28 @@ static void __mipi_csis_set_format(struct csi_state *state) * * TODO: Verify which other formats require DUAL (or QUAD) modes. */ - if (state->csis_fmt->data_type == MIPI_CSI2_DATA_TYPE_YUV422_8) + if (csis->csis_fmt->data_type == MIPI_CSI2_DATA_TYPE_YUV422_8) val |= MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL;
- val |= MIPI_CSIS_ISPCFG_FMT(state->csis_fmt->data_type); - mipi_csis_write(state, MIPI_CSIS_ISP_CONFIG_CH(0), val); + val |= MIPI_CSIS_ISPCFG_FMT(csis->csis_fmt->data_type); + mipi_csis_write(csis, MIPI_CSIS_ISP_CONFIG_CH(0), val);
/* Pixel resolution */ val = mf->width | (mf->height << 16); - mipi_csis_write(state, MIPI_CSIS_ISP_RESOL_CH(0), val); + mipi_csis_write(csis, MIPI_CSIS_ISP_RESOL_CH(0), val); }
-static int mipi_csis_calculate_params(struct csi_state *state) +static int mipi_csis_calculate_params(struct mipi_csis_device *csis) { s64 link_freq; u32 lane_rate;
/* Calculate the line rate from the pixel rate. */ - link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler, - state->csis_fmt->width, - state->bus.num_data_lanes * 2); + link_freq = v4l2_get_link_freq(csis->src_sd->ctrl_handler, + csis->csis_fmt->width, + csis->bus.num_data_lanes * 2); if (link_freq < 0) { - dev_err(state->dev, "Unable to obtain link frequency: %d\n", + dev_err(csis->dev, "Unable to obtain link frequency: %d\n", (int)link_freq); return link_freq; } @@ -585,7 +586,7 @@ static int mipi_csis_calculate_params(struct csi_state *state) lane_rate = link_freq * 2;
if (lane_rate < 80000000 || lane_rate > 1500000000) { - dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate); + dev_dbg(csis->dev, "Out-of-bound lane rate %u\n", lane_rate); return -EINVAL; }
@@ -595,57 +596,57 @@ static int mipi_csis_calculate_params(struct csi_state *state) * (which is documented as corresponding to CSI-2 v0.87 to v1.00) until * we figure out how to compute it correctly. */ - state->hs_settle = (lane_rate - 5000000) / 45000000; - state->clk_settle = 0; + csis->hs_settle = (lane_rate - 5000000) / 45000000; + csis->clk_settle = 0;
- dev_dbg(state->dev, "lane rate %u, Tclk_settle %u, Ths_settle %u\n", - lane_rate, state->clk_settle, state->hs_settle); + dev_dbg(csis->dev, "lane rate %u, Tclk_settle %u, Ths_settle %u\n", + lane_rate, csis->clk_settle, csis->hs_settle);
- if (state->debug.hs_settle < 0xff) { - dev_dbg(state->dev, "overriding Ths_settle with %u\n", - state->debug.hs_settle); - state->hs_settle = state->debug.hs_settle; + if (csis->debug.hs_settle < 0xff) { + dev_dbg(csis->dev, "overriding Ths_settle with %u\n", + csis->debug.hs_settle); + csis->hs_settle = csis->debug.hs_settle; }
- if (state->debug.clk_settle < 4) { - dev_dbg(state->dev, "overriding Tclk_settle with %u\n", - state->debug.clk_settle); - state->clk_settle = state->debug.clk_settle; + if (csis->debug.clk_settle < 4) { + dev_dbg(csis->dev, "overriding Tclk_settle with %u\n", + csis->debug.clk_settle); + csis->clk_settle = csis->debug.clk_settle; }
return 0; }
-static void mipi_csis_set_params(struct csi_state *state) +static void mipi_csis_set_params(struct mipi_csis_device *csis) { - int lanes = state->bus.num_data_lanes; + int lanes = csis->bus.num_data_lanes; u32 val;
- val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); + val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL); val &= ~MIPI_CSIS_CMN_CTRL_LANE_NR_MASK; val |= (lanes - 1) << MIPI_CSIS_CMN_CTRL_LANE_NR_OFFSET; - if (state->info->version == MIPI_CSIS_V3_3) + if (csis->info->version == MIPI_CSIS_V3_3) val |= MIPI_CSIS_CMN_CTRL_INTER_MODE; - mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); + mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL, val);
- __mipi_csis_set_format(state); + __mipi_csis_set_format(csis);
- mipi_csis_write(state, MIPI_CSIS_DPHY_CMN_CTRL, - MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(state->hs_settle) | - MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(state->clk_settle)); + mipi_csis_write(csis, MIPI_CSIS_DPHY_CMN_CTRL, + MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(csis->hs_settle) | + MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(csis->clk_settle));
val = (0 << MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET) | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET) | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_EINTV_OFFSET); - mipi_csis_write(state, MIPI_CSIS_ISP_SYNC_CH(0), val); + mipi_csis_write(csis, MIPI_CSIS_ISP_SYNC_CH(0), val);
- val = mipi_csis_read(state, MIPI_CSIS_CLK_CTRL); + val = mipi_csis_read(csis, MIPI_CSIS_CLK_CTRL); val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC; val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(15); val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK; - mipi_csis_write(state, MIPI_CSIS_CLK_CTRL, val); + mipi_csis_write(csis, MIPI_CSIS_CLK_CTRL, val);
- mipi_csis_write(state, MIPI_CSIS_DPHY_BCTRL_L, + mipi_csis_write(csis, MIPI_CSIS_DPHY_BCTRL_L, MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_715MV | MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_FREQ_3MHZ | MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_2V | @@ -653,95 +654,95 @@ static void mipi_csis_set_params(struct csi_state *state) MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_715MV | MIPI_CSIS_DPHY_BCTRL_L_LP_CD_HYS_60MV | MIPI_CSIS_DPHY_BCTRL_L_B_DPHYCTRL(20000000)); - mipi_csis_write(state, MIPI_CSIS_DPHY_BCTRL_H, 0); + mipi_csis_write(csis, MIPI_CSIS_DPHY_BCTRL_H, 0);
/* Update the shadow register. */ - val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); - mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, + val = mipi_csis_read(csis, MIPI_CSIS_CMN_CTRL); + mipi_csis_write(csis, MIPI_CSIS_CMN_CTRL, val | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW | MIPI_CSIS_CMN_CTRL_UPDATE_SHADOW_CTRL); }
-static int mipi_csis_clk_enable(struct csi_state *state) +static int mipi_csis_clk_enable(struct mipi_csis_device *csis) { - return clk_bulk_prepare_enable(state->info->num_clocks, state->clks); + return clk_bulk_prepare_enable(csis->info->num_clocks, csis->clks); }
-static void mipi_csis_clk_disable(struct csi_state *state) +static void mipi_csis_clk_disable(struct mipi_csis_device *csis) { - clk_bulk_disable_unprepare(state->info->num_clocks, state->clks); + clk_bulk_disable_unprepare(csis->info->num_clocks, csis->clks); }
-static int mipi_csis_clk_get(struct csi_state *state) +static int mipi_csis_clk_get(struct mipi_csis_device *csis) { unsigned int i; int ret;
- state->clks = devm_kcalloc(state->dev, state->info->num_clocks, - sizeof(*state->clks), GFP_KERNEL); + csis->clks = devm_kcalloc(csis->dev, csis->info->num_clocks, + sizeof(*csis->clks), GFP_KERNEL);
- if (!state->clks) + if (!csis->clks) return -ENOMEM;
- for (i = 0; i < state->info->num_clocks; i++) - state->clks[i].id = mipi_csis_clk_id[i]; + for (i = 0; i < csis->info->num_clocks; i++) + csis->clks[i].id = mipi_csis_clk_id[i];
- ret = devm_clk_bulk_get(state->dev, state->info->num_clocks, - state->clks); + ret = devm_clk_bulk_get(csis->dev, csis->info->num_clocks, + csis->clks); if (ret < 0) return ret;
/* Set clock rate */ - ret = clk_set_rate(state->clks[MIPI_CSIS_CLK_WRAP].clk, - state->clk_frequency); + ret = clk_set_rate(csis->clks[MIPI_CSIS_CLK_WRAP].clk, + csis->clk_frequency); if (ret < 0) - dev_err(state->dev, "set rate=%d failed: %d\n", - state->clk_frequency, ret); + dev_err(csis->dev, "set rate=%d failed: %d\n", + csis->clk_frequency, ret);
return ret; }
-static void mipi_csis_start_stream(struct csi_state *state) +static void mipi_csis_start_stream(struct mipi_csis_device *csis) { - mipi_csis_sw_reset(state); - mipi_csis_set_params(state); - mipi_csis_system_enable(state, true); - mipi_csis_enable_interrupts(state, true); + mipi_csis_sw_reset(csis); + mipi_csis_set_params(csis); + mipi_csis_system_enable(csis, true); + mipi_csis_enable_interrupts(csis, true); }
-static void mipi_csis_stop_stream(struct csi_state *state) +static void mipi_csis_stop_stream(struct mipi_csis_device *csis) { - mipi_csis_enable_interrupts(state, false); - mipi_csis_system_enable(state, false); + mipi_csis_enable_interrupts(csis, false); + mipi_csis_system_enable(csis, false); }
static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) { - struct csi_state *state = dev_id; + struct mipi_csis_device *csis = dev_id; unsigned long flags; unsigned int i; u32 status; u32 dbg_status;
- status = mipi_csis_read(state, MIPI_CSIS_INT_SRC); - dbg_status = mipi_csis_read(state, MIPI_CSIS_DBG_INTR_SRC); + status = mipi_csis_read(csis, MIPI_CSIS_INT_SRC); + dbg_status = mipi_csis_read(csis, MIPI_CSIS_DBG_INTR_SRC);
- spin_lock_irqsave(&state->slock, flags); + spin_lock_irqsave(&csis->slock, flags);
/* Update the event/error counters */ - if ((status & MIPI_CSIS_INT_SRC_ERRORS) || state->debug.enable) { + if ((status & MIPI_CSIS_INT_SRC_ERRORS) || csis->debug.enable) { for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { - struct mipi_csis_event *event = &state->events[i]; + struct mipi_csis_event *event = &csis->events[i];
if ((!event->debug && (status & event->mask)) || (event->debug && (dbg_status & event->mask))) event->counter++; } } - spin_unlock_irqrestore(&state->slock, flags); + spin_unlock_irqrestore(&csis->slock, flags);
- mipi_csis_write(state, MIPI_CSIS_INT_SRC, status); - mipi_csis_write(state, MIPI_CSIS_DBG_INTR_SRC, dbg_status); + mipi_csis_write(csis, MIPI_CSIS_INT_SRC, status); + mipi_csis_write(csis, MIPI_CSIS_DBG_INTR_SRC, dbg_status);
return IRQ_HANDLED; } @@ -750,47 +751,47 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) * PHY regulator and reset */
-static int mipi_csis_phy_enable(struct csi_state *state) +static int mipi_csis_phy_enable(struct mipi_csis_device *csis) { - if (state->info->version != MIPI_CSIS_V3_3) + if (csis->info->version != MIPI_CSIS_V3_3) return 0;
- return regulator_enable(state->mipi_phy_regulator); + return regulator_enable(csis->mipi_phy_regulator); }
-static int mipi_csis_phy_disable(struct csi_state *state) +static int mipi_csis_phy_disable(struct mipi_csis_device *csis) { - if (state->info->version != MIPI_CSIS_V3_3) + if (csis->info->version != MIPI_CSIS_V3_3) return 0;
- return regulator_disable(state->mipi_phy_regulator); + return regulator_disable(csis->mipi_phy_regulator); }
-static void mipi_csis_phy_reset(struct csi_state *state) +static void mipi_csis_phy_reset(struct mipi_csis_device *csis) { - if (state->info->version != MIPI_CSIS_V3_3) + if (csis->info->version != MIPI_CSIS_V3_3) return;
- reset_control_assert(state->mrst); + reset_control_assert(csis->mrst); msleep(20); - reset_control_deassert(state->mrst); + reset_control_deassert(csis->mrst); }
-static int mipi_csis_phy_init(struct csi_state *state) +static int mipi_csis_phy_init(struct mipi_csis_device *csis) { - if (state->info->version != MIPI_CSIS_V3_3) + if (csis->info->version != MIPI_CSIS_V3_3) return 0;
/* Get MIPI PHY reset and regulator. */ - state->mrst = devm_reset_control_get_exclusive(state->dev, NULL); - if (IS_ERR(state->mrst)) - return PTR_ERR(state->mrst); + csis->mrst = devm_reset_control_get_exclusive(csis->dev, NULL); + if (IS_ERR(csis->mrst)) + return PTR_ERR(csis->mrst);
- state->mipi_phy_regulator = devm_regulator_get(state->dev, "phy"); - if (IS_ERR(state->mipi_phy_regulator)) - return PTR_ERR(state->mipi_phy_regulator); + csis->mipi_phy_regulator = devm_regulator_get(csis->dev, "phy"); + if (IS_ERR(csis->mipi_phy_regulator)) + return PTR_ERR(csis->mipi_phy_regulator);
- return regulator_set_voltage(state->mipi_phy_regulator, 1000000, + return regulator_set_voltage(csis->mipi_phy_regulator, 1000000, 1000000); }
@@ -798,36 +799,36 @@ static int mipi_csis_phy_init(struct csi_state *state) * Debug */
-static void mipi_csis_clear_counters(struct csi_state *state) +static void mipi_csis_clear_counters(struct mipi_csis_device *csis) { unsigned long flags; unsigned int i;
- spin_lock_irqsave(&state->slock, flags); + spin_lock_irqsave(&csis->slock, flags); for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) - state->events[i].counter = 0; - spin_unlock_irqrestore(&state->slock, flags); + csis->events[i].counter = 0; + spin_unlock_irqrestore(&csis->slock, flags); }
-static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) +static void mipi_csis_log_counters(struct mipi_csis_device *csis, bool non_errors) { unsigned int num_events = non_errors ? MIPI_CSIS_NUM_EVENTS : MIPI_CSIS_NUM_EVENTS - 8; unsigned long flags; unsigned int i;
- spin_lock_irqsave(&state->slock, flags); + spin_lock_irqsave(&csis->slock, flags);
for (i = 0; i < num_events; ++i) { - if (state->events[i].counter > 0 || state->debug.enable) - dev_info(state->dev, "%s events: %d\n", - state->events[i].name, - state->events[i].counter); + if (csis->events[i].counter > 0 || csis->debug.enable) + dev_info(csis->dev, "%s events: %d\n", + csis->events[i].name, + csis->events[i].counter); } - spin_unlock_irqrestore(&state->slock, flags); + spin_unlock_irqrestore(&csis->slock, flags); }
-static int mipi_csis_dump_regs(struct csi_state *state) +static int mipi_csis_dump_regs(struct mipi_csis_device *csis) { static const struct { u32 offset; @@ -851,11 +852,11 @@ static int mipi_csis_dump_regs(struct csi_state *state) unsigned int i; u32 cfg;
- dev_info(state->dev, "--- REGISTERS ---\n"); + dev_info(csis->dev, "--- REGISTERS ---\n");
for (i = 0; i < ARRAY_SIZE(registers); i++) { - cfg = mipi_csis_read(state, registers[i].offset); - dev_info(state->dev, "%14s: 0x%08x\n", registers[i].name, cfg); + cfg = mipi_csis_read(csis, registers[i].offset); + dev_info(csis->dev, "%14s: 0x%08x\n", registers[i].name, cfg); }
return 0; @@ -863,123 +864,123 @@ static int mipi_csis_dump_regs(struct csi_state *state)
static int mipi_csis_dump_regs_show(struct seq_file *m, void *private) { - struct csi_state *state = m->private; + struct mipi_csis_device *csis = m->private;
- return mipi_csis_dump_regs(state); + return mipi_csis_dump_regs(csis); } DEFINE_SHOW_ATTRIBUTE(mipi_csis_dump_regs);
-static void mipi_csis_debugfs_init(struct csi_state *state) +static void mipi_csis_debugfs_init(struct mipi_csis_device *csis) { - state->debug.hs_settle = UINT_MAX; - state->debug.clk_settle = UINT_MAX; + csis->debug.hs_settle = UINT_MAX; + csis->debug.clk_settle = UINT_MAX;
- state->debugfs_root = debugfs_create_dir(dev_name(state->dev), NULL); + csis->debugfs_root = debugfs_create_dir(dev_name(csis->dev), NULL);
- debugfs_create_bool("debug_enable", 0600, state->debugfs_root, - &state->debug.enable); - debugfs_create_file("dump_regs", 0600, state->debugfs_root, state, + debugfs_create_bool("debug_enable", 0600, csis->debugfs_root, + &csis->debug.enable); + debugfs_create_file("dump_regs", 0600, csis->debugfs_root, csis, &mipi_csis_dump_regs_fops); - debugfs_create_u32("tclk_settle", 0600, state->debugfs_root, - &state->debug.clk_settle); - debugfs_create_u32("ths_settle", 0600, state->debugfs_root, - &state->debug.hs_settle); + debugfs_create_u32("tclk_settle", 0600, csis->debugfs_root, + &csis->debug.clk_settle); + debugfs_create_u32("ths_settle", 0600, csis->debugfs_root, + &csis->debug.hs_settle); }
-static void mipi_csis_debugfs_exit(struct csi_state *state) +static void mipi_csis_debugfs_exit(struct mipi_csis_device *csis) { - debugfs_remove_recursive(state->debugfs_root); + debugfs_remove_recursive(csis->debugfs_root); }
/* ----------------------------------------------------------------------------- * V4L2 subdev operations */
-static struct csi_state *mipi_sd_to_csis_state(struct v4l2_subdev *sdev) +static struct mipi_csis_device *sd_to_mipi_csis_device(struct v4l2_subdev *sdev) { - return container_of(sdev, struct csi_state, sd); + return container_of(sdev, struct mipi_csis_device, sd); }
static int mipi_csis_s_stream(struct v4l2_subdev *sd, int enable) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); int ret;
if (enable) { - ret = mipi_csis_calculate_params(state); + ret = mipi_csis_calculate_params(csis); if (ret < 0) return ret;
- mipi_csis_clear_counters(state); + mipi_csis_clear_counters(csis);
- ret = pm_runtime_resume_and_get(state->dev); + ret = pm_runtime_resume_and_get(csis->dev); if (ret < 0) return ret;
- ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); + ret = v4l2_subdev_call(csis->src_sd, core, s_power, 1); if (ret < 0 && ret != -ENOIOCTLCMD) goto done; }
- mutex_lock(&state->lock); + mutex_lock(&csis->lock);
if (enable) { - if (state->state & ST_SUSPENDED) { + if (csis->state & ST_SUSPENDED) { ret = -EBUSY; goto unlock; }
- mipi_csis_start_stream(state); - ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1); + mipi_csis_start_stream(csis); + ret = v4l2_subdev_call(csis->src_sd, video, s_stream, 1); if (ret < 0) goto unlock;
- mipi_csis_log_counters(state, true); + mipi_csis_log_counters(csis, true);
- state->state |= ST_STREAMING; + csis->state |= ST_STREAMING; } else { - v4l2_subdev_call(state->src_sd, video, s_stream, 0); - ret = v4l2_subdev_call(state->src_sd, core, s_power, 0); + v4l2_subdev_call(csis->src_sd, video, s_stream, 0); + ret = v4l2_subdev_call(csis->src_sd, core, s_power, 0); if (ret == -ENOIOCTLCMD) ret = 0; - mipi_csis_stop_stream(state); - state->state &= ~ST_STREAMING; - if (state->debug.enable) - mipi_csis_log_counters(state, true); + mipi_csis_stop_stream(csis); + csis->state &= ~ST_STREAMING; + if (csis->debug.enable) + mipi_csis_log_counters(csis, true); }
unlock: - mutex_unlock(&state->lock); + mutex_unlock(&csis->lock);
done: if (!enable || ret < 0) - pm_runtime_put(state->dev); + pm_runtime_put(csis->dev);
return ret; }
static struct v4l2_mbus_framefmt * -mipi_csis_get_format(struct csi_state *state, +mipi_csis_get_format(struct mipi_csis_device *csis, struct v4l2_subdev_state *sd_state, enum v4l2_subdev_format_whence which, unsigned int pad) { if (which == V4L2_SUBDEV_FORMAT_TRY) - return v4l2_subdev_get_try_format(&state->sd, sd_state, pad); + return v4l2_subdev_get_try_format(&csis->sd, sd_state, pad);
- return &state->format_mbus[pad]; + return &csis->format_mbus[pad]; }
static int mipi_csis_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); struct v4l2_mbus_framefmt *fmt_sink; struct v4l2_mbus_framefmt *fmt_source; enum v4l2_subdev_format_whence which;
which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; - fmt_sink = mipi_csis_get_format(state, sd_state, which, CSIS_PAD_SINK); + fmt_sink = mipi_csis_get_format(csis, sd_state, which, CSIS_PAD_SINK);
fmt_sink->code = MEDIA_BUS_FMT_UYVY8_1X16; fmt_sink->width = MIPI_CSIS_DEF_PIX_WIDTH; @@ -1001,7 +1002,7 @@ static int mipi_csis_init_cfg(struct v4l2_subdev *sd, if (!sd_state) return 0;
- fmt_source = mipi_csis_get_format(state, sd_state, which, + fmt_source = mipi_csis_get_format(csis, sd_state, which, CSIS_PAD_SOURCE); *fmt_source = *fmt_sink;
@@ -1012,15 +1013,15 @@ static int mipi_csis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); struct v4l2_mbus_framefmt *fmt;
- fmt = mipi_csis_get_format(state, sd_state, sdformat->which, + fmt = mipi_csis_get_format(csis, sd_state, sdformat->which, sdformat->pad);
- mutex_lock(&state->lock); + mutex_lock(&csis->lock); sdformat->format = *fmt; - mutex_unlock(&state->lock); + mutex_unlock(&csis->lock);
return 0; } @@ -1029,7 +1030,7 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd);
/* * The CSIS can't transcode in any way, the source format is identical @@ -1041,7 +1042,7 @@ static int mipi_csis_enum_mbus_code(struct v4l2_subdev *sd, if (code->index > 0) return -EINVAL;
- fmt = mipi_csis_get_format(state, sd_state, code->which, + fmt = mipi_csis_get_format(csis, sd_state, code->which, code->pad); code->code = fmt->code; return 0; @@ -1062,7 +1063,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *sdformat) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); struct csis_pix_format const *csis_fmt; struct v4l2_mbus_framefmt *fmt; unsigned int align; @@ -1110,10 +1111,10 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd, &sdformat->format.height, 1, CSIS_MAX_PIX_HEIGHT, 0, 0);
- fmt = mipi_csis_get_format(state, sd_state, sdformat->which, + fmt = mipi_csis_get_format(csis, sd_state, sdformat->which, sdformat->pad);
- mutex_lock(&state->lock); + mutex_lock(&csis->lock);
fmt->code = csis_fmt->code; fmt->width = sdformat->format.width; @@ -1126,7 +1127,7 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd, sdformat->format = *fmt;
/* Propagate the format from sink to source. */ - fmt = mipi_csis_get_format(state, sd_state, sdformat->which, + fmt = mipi_csis_get_format(csis, sd_state, sdformat->which, CSIS_PAD_SOURCE); *fmt = sdformat->format;
@@ -1135,22 +1136,22 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *sd,
/* Store the CSIS format descriptor for active formats. */ if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) - state->csis_fmt = csis_fmt; + csis->csis_fmt = csis_fmt;
- mutex_unlock(&state->lock); + mutex_unlock(&csis->lock);
return 0; }
static int mipi_csis_log_status(struct v4l2_subdev *sd) { - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd);
- mutex_lock(&state->lock); - mipi_csis_log_counters(state, true); - if (state->debug.enable && (state->state & ST_POWERED)) - mipi_csis_dump_regs(state); - mutex_unlock(&state->lock); + mutex_lock(&csis->lock); + mipi_csis_log_counters(csis, true); + if (csis->debug.enable && (csis->state & ST_POWERED)) + mipi_csis_dump_regs(csis); + mutex_unlock(&csis->lock);
return 0; } @@ -1185,10 +1186,10 @@ static int mipi_csis_link_setup(struct media_entity *entity, const struct media_pad *remote_pad, u32 flags) { struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); struct v4l2_subdev *remote_sd;
- dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, + dev_dbg(csis->dev, "link setup %s -> %s", remote_pad->entity->name, local_pad->entity->name);
/* We only care about the link to the source. */ @@ -1198,12 +1199,12 @@ static int mipi_csis_link_setup(struct media_entity *entity, remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity);
if (flags & MEDIA_LNK_FL_ENABLED) { - if (state->src_sd) + if (csis->src_sd) return -EBUSY;
- state->src_sd = remote_sd; + csis->src_sd = remote_sd; } else { - state->src_sd = NULL; + csis->src_sd = NULL; }
return 0; @@ -1219,18 +1220,18 @@ static const struct media_entity_operations mipi_csis_entity_ops = { * Async subdev notifier */
-static struct csi_state * +static struct mipi_csis_device * mipi_notifier_to_csis_state(struct v4l2_async_notifier *n) { - return container_of(n, struct csi_state, notifier); + return container_of(n, struct mipi_csis_device, notifier); }
static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) { - struct csi_state *state = mipi_notifier_to_csis_state(notifier); - struct media_pad *sink = &state->sd.entity.pads[CSIS_PAD_SINK]; + struct mipi_csis_device *csis = mipi_notifier_to_csis_state(notifier); + struct media_pad *sink = &csis->sd.entity.pads[CSIS_PAD_SINK];
return v4l2_create_fwnode_links_to_pad(sd, sink, 0); } @@ -1239,7 +1240,7 @@ static const struct v4l2_async_notifier_operations mipi_csis_notify_ops = { .bound = mipi_csis_notify_bound, };
-static int mipi_csis_async_register(struct csi_state *state) +static int mipi_csis_async_register(struct mipi_csis_device *csis) { struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY, @@ -1249,9 +1250,9 @@ static int mipi_csis_async_register(struct csi_state *state) unsigned int i; int ret;
- v4l2_async_nf_init(&state->notifier); + v4l2_async_nf_init(&csis->notifier);
- ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0, + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csis->dev), 0, 0, FWNODE_GRAPH_ENDPOINT_NEXT); if (!ep) return -ENOTCONN; @@ -1262,19 +1263,19 @@ static int mipi_csis_async_register(struct csi_state *state)
for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) { if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) { - dev_err(state->dev, + dev_err(csis->dev, "data lanes reordering is not supported"); ret = -EINVAL; goto err_parse; } }
- state->bus = vep.bus.mipi_csi2; + csis->bus = vep.bus.mipi_csi2;
- dev_dbg(state->dev, "data lanes: %d\n", state->bus.num_data_lanes); - dev_dbg(state->dev, "flags: 0x%08x\n", state->bus.flags); + dev_dbg(csis->dev, "data lanes: %d\n", csis->bus.num_data_lanes); + dev_dbg(csis->dev, "flags: 0x%08x\n", csis->bus.flags);
- asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep, + asd = v4l2_async_nf_add_fwnode_remote(&csis->notifier, ep, struct v4l2_async_subdev); if (IS_ERR(asd)) { ret = PTR_ERR(asd); @@ -1283,13 +1284,13 @@ static int mipi_csis_async_register(struct csi_state *state)
fwnode_handle_put(ep);
- state->notifier.ops = &mipi_csis_notify_ops; + csis->notifier.ops = &mipi_csis_notify_ops;
- ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier); + ret = v4l2_async_subdev_nf_register(&csis->sd, &csis->notifier); if (ret) return ret;
- return v4l2_async_register_subdev(&state->sd); + return v4l2_async_register_subdev(&csis->sd);
err_parse: fwnode_handle_put(ep); @@ -1304,23 +1305,23 @@ static int mipi_csis_async_register(struct csi_state *state) static int mipi_csis_pm_suspend(struct device *dev, bool runtime) { struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); int ret = 0;
- mutex_lock(&state->lock); - if (state->state & ST_POWERED) { - mipi_csis_stop_stream(state); - ret = mipi_csis_phy_disable(state); + mutex_lock(&csis->lock); + if (csis->state & ST_POWERED) { + mipi_csis_stop_stream(csis); + ret = mipi_csis_phy_disable(csis); if (ret) goto unlock; - mipi_csis_clk_disable(state); - state->state &= ~ST_POWERED; + mipi_csis_clk_disable(csis); + csis->state &= ~ST_POWERED; if (!runtime) - state->state |= ST_SUSPENDED; + csis->state |= ST_SUSPENDED; }
unlock: - mutex_unlock(&state->lock); + mutex_unlock(&csis->lock);
return ret ? -EAGAIN : 0; } @@ -1328,28 +1329,28 @@ static int mipi_csis_pm_suspend(struct device *dev, bool runtime) static int mipi_csis_pm_resume(struct device *dev, bool runtime) { struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd); int ret = 0;
- mutex_lock(&state->lock); - if (!runtime && !(state->state & ST_SUSPENDED)) + mutex_lock(&csis->lock); + if (!runtime && !(csis->state & ST_SUSPENDED)) goto unlock;
- if (!(state->state & ST_POWERED)) { - ret = mipi_csis_phy_enable(state); + if (!(csis->state & ST_POWERED)) { + ret = mipi_csis_phy_enable(csis); if (ret) goto unlock;
- state->state |= ST_POWERED; - mipi_csis_clk_enable(state); + csis->state |= ST_POWERED; + mipi_csis_clk_enable(csis); } - if (state->state & ST_STREAMING) - mipi_csis_start_stream(state); + if (csis->state & ST_STREAMING) + mipi_csis_start_stream(csis);
- state->state &= ~ST_SUSPENDED; + csis->state &= ~ST_SUSPENDED;
unlock: - mutex_unlock(&state->lock); + mutex_unlock(&csis->lock);
return ret ? -EAGAIN : 0; } @@ -1384,14 +1385,14 @@ static const struct dev_pm_ops mipi_csis_pm_ops = { * Probe/remove & platform driver */
-static int mipi_csis_subdev_init(struct csi_state *state) +static int mipi_csis_subdev_init(struct mipi_csis_device *csis) { - struct v4l2_subdev *sd = &state->sd; + struct v4l2_subdev *sd = &csis->sd;
v4l2_subdev_init(sd, &mipi_csis_subdev_ops); sd->owner = THIS_MODULE; snprintf(sd->name, sizeof(sd->name), "csis-%s", - dev_name(state->dev)); + dev_name(csis->dev));
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; sd->ctrl_handler = NULL; @@ -1399,26 +1400,26 @@ static int mipi_csis_subdev_init(struct csi_state *state) sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; sd->entity.ops = &mipi_csis_entity_ops;
- sd->dev = state->dev; + sd->dev = csis->dev;
- state->csis_fmt = &mipi_csis_formats[0]; + csis->csis_fmt = &mipi_csis_formats[0]; mipi_csis_init_cfg(sd, NULL);
- state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK + csis->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; - state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE + csis->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_MUST_CONNECT; return media_entity_pads_init(&sd->entity, CSIS_PADS_NUM, - state->pads); + csis->pads); }
-static int mipi_csis_parse_dt(struct csi_state *state) +static int mipi_csis_parse_dt(struct mipi_csis_device *csis) { - struct device_node *node = state->dev->of_node; + struct device_node *node = csis->dev->of_node;
if (of_property_read_u32(node, "clock-frequency", - &state->clk_frequency)) - state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; + &csis->clk_frequency)) + csis->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
return 0; } @@ -1426,78 +1427,78 @@ static int mipi_csis_parse_dt(struct csi_state *state) static int mipi_csis_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct csi_state *state; + struct mipi_csis_device *csis; int irq; int ret;
- state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); - if (!state) + csis = devm_kzalloc(dev, sizeof(*csis), GFP_KERNEL); + if (!csis) return -ENOMEM;
- mutex_init(&state->lock); - spin_lock_init(&state->slock); + mutex_init(&csis->lock); + spin_lock_init(&csis->slock);
- state->dev = dev; - state->info = of_device_get_match_data(dev); + csis->dev = dev; + csis->info = of_device_get_match_data(dev);
- memcpy(state->events, mipi_csis_events, sizeof(state->events)); + memcpy(csis->events, mipi_csis_events, sizeof(csis->events));
/* Parse DT properties. */ - ret = mipi_csis_parse_dt(state); + ret = mipi_csis_parse_dt(csis); if (ret < 0) { dev_err(dev, "Failed to parse device tree: %d\n", ret); return ret; }
/* Acquire resources. */ - state->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(state->regs)) - return PTR_ERR(state->regs); + csis->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(csis->regs)) + return PTR_ERR(csis->regs);
irq = platform_get_irq(pdev, 0); if (irq < 0) return irq;
- ret = mipi_csis_phy_init(state); + ret = mipi_csis_phy_init(csis); if (ret < 0) return ret;
- ret = mipi_csis_clk_get(state); + ret = mipi_csis_clk_get(csis); if (ret < 0) return ret;
/* Reset PHY and enable the clocks. */ - mipi_csis_phy_reset(state); + mipi_csis_phy_reset(csis);
- ret = mipi_csis_clk_enable(state); + ret = mipi_csis_clk_enable(csis); if (ret < 0) { - dev_err(state->dev, "failed to enable clocks: %d\n", ret); + dev_err(csis->dev, "failed to enable clocks: %d\n", ret); return ret; }
/* Now that the hardware is initialized, request the interrupt. */ ret = devm_request_irq(dev, irq, mipi_csis_irq_handler, 0, - dev_name(dev), state); + dev_name(dev), csis); if (ret) { dev_err(dev, "Interrupt request failed\n"); goto disable_clock; }
/* Initialize and register the subdev. */ - ret = mipi_csis_subdev_init(state); + ret = mipi_csis_subdev_init(csis); if (ret < 0) goto disable_clock;
- platform_set_drvdata(pdev, &state->sd); + platform_set_drvdata(pdev, &csis->sd);
- ret = mipi_csis_async_register(state); + ret = mipi_csis_async_register(csis); if (ret < 0) { dev_err(dev, "async register failed: %d\n", ret); goto cleanup; }
/* Initialize debugfs. */ - mipi_csis_debugfs_init(state); + mipi_csis_debugfs_init(csis);
/* Enable runtime PM. */ pm_runtime_enable(dev); @@ -1508,20 +1509,20 @@ static int mipi_csis_probe(struct platform_device *pdev) }
dev_info(dev, "lanes: %d, freq: %u\n", - state->bus.num_data_lanes, state->clk_frequency); + csis->bus.num_data_lanes, csis->clk_frequency);
return 0;
unregister_all: - mipi_csis_debugfs_exit(state); + mipi_csis_debugfs_exit(csis); cleanup: - media_entity_cleanup(&state->sd.entity); - v4l2_async_nf_unregister(&state->notifier); - v4l2_async_nf_cleanup(&state->notifier); - v4l2_async_unregister_subdev(&state->sd); + media_entity_cleanup(&csis->sd.entity); + v4l2_async_nf_unregister(&csis->notifier); + v4l2_async_nf_cleanup(&csis->notifier); + v4l2_async_unregister_subdev(&csis->sd); disable_clock: - mipi_csis_clk_disable(state); - mutex_destroy(&state->lock); + mipi_csis_clk_disable(csis); + mutex_destroy(&csis->lock);
return ret; } @@ -1529,18 +1530,18 @@ static int mipi_csis_probe(struct platform_device *pdev) static int mipi_csis_remove(struct platform_device *pdev) { struct v4l2_subdev *sd = platform_get_drvdata(pdev); - struct csi_state *state = mipi_sd_to_csis_state(sd); + struct mipi_csis_device *csis = sd_to_mipi_csis_device(sd);
- mipi_csis_debugfs_exit(state); - v4l2_async_nf_unregister(&state->notifier); - v4l2_async_nf_cleanup(&state->notifier); - v4l2_async_unregister_subdev(&state->sd); + mipi_csis_debugfs_exit(csis); + v4l2_async_nf_unregister(&csis->notifier); + v4l2_async_nf_cleanup(&csis->notifier); + v4l2_async_unregister_subdev(&csis->sd);
pm_runtime_disable(&pdev->dev); mipi_csis_pm_suspend(&pdev->dev, true); - mipi_csis_clk_disable(state); - media_entity_cleanup(&state->sd.entity); - mutex_destroy(&state->lock); + mipi_csis_clk_disable(csis); + media_entity_cleanup(&csis->sd.entity); + mutex_destroy(&csis->lock); pm_runtime_set_suspended(&pdev->dev);
return 0;
From: Laurent Pinchart laurent.pinchart@ideasonboard.com
[ Upstream commit fe14b546d6e57542dbd4f5ccdb5a382904d26c5a ]
Commit 5c0701a0e791 ("media: imx: csis: Store pads format separately") broke initialization of the active format on the source pad, as it forgot to update the .init_cfg() handler. Fix it.
Fixes: 5c0701a0e791 ("media: imx: csis: Store pads format separately") Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Acked-by: Rui Miguel Silva rmfrfs@gmail.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/nxp/imx-mipi-csis.c | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c index d9719d0b2f0a..e0e345fbb00f 100644 --- a/drivers/media/platform/nxp/imx-mipi-csis.c +++ b/drivers/media/platform/nxp/imx-mipi-csis.c @@ -994,14 +994,6 @@ static int mipi_csis_init_cfg(struct v4l2_subdev *sd, V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace, fmt_sink->ycbcr_enc);
- /* - * When called from mipi_csis_subdev_init() to initialize the active - * configuration, cfg is NULL, which indicates there's no source pad - * configuration to set. - */ - if (!sd_state) - return 0; - fmt_source = mipi_csis_get_format(csis, sd_state, which, CSIS_PAD_SOURCE); *fmt_source = *fmt_sink;
From: Marek Vasut marex@denx.de
[ Upstream commit 0f73a559f916b618c0c05186bd644c90cc9e9695 ]
The DE signal is active high on this display, fill in the missing bus_flags. This aligns panel_desc with its display_timing .
Fixes: a5d2ade627dca ("drm/panel: simple: Add support for Innolux G070Y2-L01") Signed-off-by: Marek Vasut marex@denx.de Cc: Christoph Fritz chf.fritz@googlemail.com Cc: Laurent Pinchart Laurent.pinchart@ideasonboard.com Cc: Maxime Ripard maxime@cerno.tech Cc: Sam Ravnborg sam@ravnborg.org Cc: Thomas Zimmermann tzimmermann@suse.de Acked-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/20220406093627.18011-1-marex@d... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index a34f4198a534..00b9e1d22087 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -2029,6 +2029,7 @@ static const struct panel_desc innolux_g070y2_l01 = { .unprepare = 800, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, .connector_type = DRM_MODE_CONNECTOR_LVDS, };
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit 011b559be832194f992f73d6c0d5485f5925a10b ]
Pointer substream is being dereferenced on the assignment of pointer card before substream is being null checked with the macro PCM_RUNTIME_CHECK. Although PCM_RUNTIME_CHECK calls BUG_ON, it still is useful to perform the the pointer check before card is assigned.
Fixes: d4cfb30fce03 ("ALSA: pcm: Set per-card upper limit of PCM buffer allocations") Signed-off-by: Colin Ian King colin.i.king@gmail.com Link: https://lore.kernel.org/r/20220424205945.1372247-1-colin.i.king@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/pcm_memory.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 8848d2f3160d..b8296b6eb2c1 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -453,7 +453,6 @@ EXPORT_SYMBOL(snd_pcm_lib_malloc_pages); */ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) { - struct snd_card *card = substream->pcm->card; struct snd_pcm_runtime *runtime;
if (PCM_RUNTIME_CHECK(substream)) @@ -462,6 +461,8 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream) if (runtime->dma_area == NULL) return 0; if (runtime->dma_buffer_p != &substream->dma_buffer) { + struct snd_card *card = substream->pcm->card; + /* it's a newly allocated buffer. release it now. */ do_free_pages(card, runtime->dma_buffer_p); kfree(runtime->dma_buffer_p);
From: Bjørn Mork bjorn@mork.no
[ Upstream commit 96a3295c351da82d7af99b2fc004a3cf9f4716a9 ]
Warning on every translated mtd partition results in excessive log noise if this driver is loaded:
nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1 nand: Macronix MX30LF1G18AC nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 mt7621-nand 1e003000.nand: ECC strength adjusted to 4 bits read_bbt: found bbt at block 1023 10 fixed-partitions partitions found on MTD device mt7621-nand Creating 10 MTD partitions on "mt7621-nand": 0x000000000000-0x000000080000 : "Bootloader" mtdblock: MTD device 'Bootloader' is NAND, please consider using UBI block devices instead. 0x000000080000-0x000000100000 : "Config" mtdblock: MTD device 'Config' is NAND, please consider using UBI block devices instead. 0x000000100000-0x000000140000 : "Factory" mtdblock: MTD device 'Factory' is NAND, please consider using UBI block devices instead. 0x000000140000-0x000002000000 : "Kernel" mtdblock: MTD device 'Kernel' is NAND, please consider using UBI block devices instead. 0x000000540000-0x000002000000 : "ubi" mtdblock: MTD device 'ubi' is NAND, please consider using UBI block devices instead. 0x000002140000-0x000004000000 : "Kernel2" mtdblock: MTD device 'Kernel2' is NAND, please consider using UBI block devices instead. 0x000004000000-0x000004100000 : "wwan" mtdblock: MTD device 'wwan' is NAND, please consider using UBI block devices instead. 0x000004100000-0x000005100000 : "data" mtdblock: MTD device 'data' is NAND, please consider using UBI block devices instead. 0x000005100000-0x000005200000 : "rom-d" mtdblock: MTD device 'rom-d' is NAND, please consider using UBI block devices instead. 0x000005200000-0x000005280000 : "reserve" mtdblock: MTD device 'reserve' is NAND, please consider using UBI block devices instead. mtk_soc_eth 1e100000.ethernet eth0: mediatek frame engine at 0xbe100000, irq 21
This is more likely to annoy than to help users of embedded distros where this driver is enabled by default. Making the blockdevs available does not imply that they are in use, and warning about bootloader partitions or other devices which obviously never will be mounted is more confusing than helpful.
Move the warning to open(), where it will be of more use - actually warning anyone who mounts a file system on NAND using mtdblock.
Fixes: e07403a8c6be ("mtdblock: Warn if added for a NAND device") Signed-off-by: Bjørn Mork bjorn@mork.no Reviewed-by: Ezequiel Garcia ezequiel@vanguardiasur.com.ar Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220328161108.87757-1-bjorn@mork.no Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/mtdblock.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index 03e3de3a5d79..1e94e7d10b8b 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -257,6 +257,10 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd) return 0; }
+ if (mtd_type_is_nand(mbd->mtd)) + pr_warn("%s: MTD device '%s' is NAND, please consider using UBI block devices instead.\n", + mbd->tr->name, mbd->mtd->name); + /* OK, it's not open. Create cache info for it */ mtdblk->count = 1; mutex_init(&mtdblk->cache_mutex); @@ -322,10 +326,6 @@ static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) if (!(mtd->flags & MTD_WRITEABLE)) dev->mbd.readonly = 1;
- if (mtd_type_is_nand(mtd)) - pr_warn("%s: MTD device '%s' is NAND, please consider using UBI block devices instead.\n", - tr->name, mtd->name); - if (add_mtd_blktrans_dev(&dev->mbd)) kfree(dev); }
From: Amir Goldstein amir73il@gmail.com
[ Upstream commit a32e697cda27679a0327ae2cafdad8c7170f548f ]
The inotify mask flags IN_ONESHOT and IN_EXCL_UNLINK are not "internal to kernel" and should be exposed in procfs fdinfo so CRIU can restore them.
Fixes: 6933599697c9 ("inotify: hide internal kernel bits from fdinfo") Link: https://lore.kernel.org/r/20220422120327.3459282-2-amir73il@gmail.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/notify/fdinfo.c | 11 ++--------- fs/notify/inotify/inotify.h | 12 ++++++++++++ fs/notify/inotify/inotify_user.c | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c index 57f0d5d9f934..3451708fd035 100644 --- a/fs/notify/fdinfo.c +++ b/fs/notify/fdinfo.c @@ -83,16 +83,9 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark) inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark); inode = igrab(fsnotify_conn_inode(mark->connector)); if (inode) { - /* - * IN_ALL_EVENTS represents all of the mask bits - * that we expose to userspace. There is at - * least one bit (FS_EVENT_ON_CHILD) which is - * used only internally to the kernel. - */ - u32 mask = mark->mask & IN_ALL_EVENTS; - seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ", + seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:0 ", inode_mark->wd, inode->i_ino, inode->i_sb->s_dev, - mask, mark->ignored_mask); + inotify_mark_user_mask(mark)); show_mark_fhandle(m, inode); seq_putc(m, '\n'); iput(inode); diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index 2007e3711916..8f00151eb731 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h @@ -22,6 +22,18 @@ static inline struct inotify_event_info *INOTIFY_E(struct fsnotify_event *fse) return container_of(fse, struct inotify_event_info, fse); }
+/* + * INOTIFY_USER_FLAGS represents all of the mask bits that we expose to + * userspace. There is at least one bit (FS_EVENT_ON_CHILD) which is + * used only internally to the kernel. + */ +#define INOTIFY_USER_MASK (IN_ALL_EVENTS | IN_ONESHOT | IN_EXCL_UNLINK) + +static inline __u32 inotify_mark_user_mask(struct fsnotify_mark *fsn_mark) +{ + return fsn_mark->mask & INOTIFY_USER_MASK; +} + extern void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group); extern int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 54583f62dc44..3ef57db0ec9d 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -110,7 +110,7 @@ static inline __u32 inotify_arg_to_mask(struct inode *inode, u32 arg) mask |= FS_EVENT_ON_CHILD;
/* mask off the flags used to open the fd */ - mask |= (arg & (IN_ALL_EVENTS | IN_ONESHOT | IN_EXCL_UNLINK)); + mask |= (arg & INOTIFY_USER_MASK);
return mask; }
From: Amir Goldstein amir73il@gmail.com
[ Upstream commit 623af4f538b5df9b416e1b82f720af7371b4c771 ]
Commit 6960b0d909cd ("fsnotify: change locking order") changed some of the mark_mutex locks in direct reclaim path to use: mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
This change is explained: "...It uses nested locking to avoid deadlock in case we do the final iput() on an inode which still holds marks and thus would take the mutex again when calling fsnotify_inode_delete() in destroy_inode()."
The problem is that the mutex_lock_nested() is not a nested lock at all. In fact, it has the opposite effect of preventing lockdep from warning about a very possible deadlock.
Due to these wrong annotations, a deadlock that was introduced with nfsd filecache in kernel v5.4 went unnoticed in v5.4.y for over two years until it was reported recently by Khazhismel Kumykov, only to find out that the deadlock was already fixed in kernel v5.5.
Fix the wrong lockdep annotations.
Cc: Khazhismel Kumykov khazhy@google.com Fixes: 6960b0d909cd ("fsnotify: change locking order") Link: https://lore.kernel.org/r/20220321112310.vpr7oxro2xkz5llh@quack3.lan/ Link: https://lore.kernel.org/r/20220422120327.3459282-4-amir73il@gmail.com Signed-off-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- fs/notify/mark.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 4853184f7dde..c86982be2d50 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -452,7 +452,7 @@ void fsnotify_free_mark(struct fsnotify_mark *mark) void fsnotify_destroy_mark(struct fsnotify_mark *mark, struct fsnotify_group *group) { - mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); + mutex_lock(&group->mark_mutex); fsnotify_detach_mark(mark); mutex_unlock(&group->mark_mutex); fsnotify_free_mark(mark); @@ -770,7 +770,7 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group, * move marks to free to to_free list in one go and then free marks in * to_free list one by one. */ - mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); + mutex_lock(&group->mark_mutex); list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) { if (mark->connector->type == obj_type) list_move(&mark->g_list, &to_free); @@ -779,7 +779,7 @@ void fsnotify_clear_marks_by_group(struct fsnotify_group *group,
clear: while (1) { - mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING); + mutex_lock(&group->mark_mutex); if (list_empty(head)) { mutex_unlock(&group->mark_mutex); break;
From: Luca Ceresoli luca.ceresoli@bootlin.com
[ Upstream commit d5d933f09ac326aebad85bfb787cc786ad477711 ]
The hardware (except for the ROCKCHIP_SPI_VER2_TYPE2 version) does not support active-high native chip selects. However if such a CS is configured the core does not error as it normally should, because the 'ctlr->use_gpio_descriptors = true' line in rockchip_spi_probe() makes the core set SPI_CS_HIGH in ctlr->mode_bits.
In such a case the spi-rockchip driver operates normally but produces an active-low chip select signal without notice.
There is no provision in the current core code to handle this situation. Fix by adding a check in the ctlr->setup function (similarly to what spi-atmel.c does).
This cannot be done reading the SPI_CS_HIGH but in ctlr->mode_bits because that bit gets always set by the core for master mode (see above).
Fixes: eb1262e3cc8b ("spi: spi-rockchip: use num-cs property and ctlr->enable_gpiods") Signed-off-by: Luca Ceresoli luca.ceresoli@bootlin.com Link: https://lore.kernel.org/r/20220421213251.1077899-1-luca.ceresoli@bootlin.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-rockchip.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c index cdc16eecaf6b..a08215eb9e14 100644 --- a/drivers/spi/spi-rockchip.c +++ b/drivers/spi/spi-rockchip.c @@ -196,6 +196,8 @@ struct rockchip_spi {
bool slave_abort; bool cs_inactive; /* spi slave tansmition stop when cs inactive */ + bool cs_high_supported; /* native CS supports active-high polarity */ + struct spi_transfer *xfer; /* Store xfer temporarily */ };
@@ -719,6 +721,11 @@ static int rockchip_spi_setup(struct spi_device *spi) struct rockchip_spi *rs = spi_controller_get_devdata(spi->controller); u32 cr0;
+ if (!spi->cs_gpiod && (spi->mode & SPI_CS_HIGH) && !rs->cs_high_supported) { + dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n"); + return -EINVAL; + } + pm_runtime_get_sync(rs->dev);
cr0 = readl_relaxed(rs->regs + ROCKCHIP_SPI_CTRLR0); @@ -899,6 +906,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
switch (readl_relaxed(rs->regs + ROCKCHIP_SPI_VERSION)) { case ROCKCHIP_SPI_VER2_TYPE2: + rs->cs_high_supported = true; ctlr->mode_bits |= SPI_CS_HIGH; if (ctlr->can_dma && slave_mode) rs->cs_inactive = true;
From: Nuno Sá nuno.sa@analog.com
[ Upstream commit 5f756a2eaa4436d7d3dc1e040147f5e992ae34b5 ]
We should not break overlay notifications on NOTIFY_{OK|STOP} otherwise we might break on the first fragment. We should only stop notifications if a *real* errno is returned by one of the listeners.
Fixes: a1d19bd4cf1fe ("of: overlay: pr_err from return NOTIFY_OK to overlay apply/remove") Signed-off-by: Nuno Sá nuno.sa@analog.com Signed-off-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20220420130205.89435-1-nuno.sa@analog.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/overlay.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index d80160cf34bb..d1187123c4fc 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -170,9 +170,7 @@ static int overlay_notify(struct overlay_changeset *ovcs,
ret = blocking_notifier_call_chain(&overlay_notify_chain, action, &nd); - if (ret == NOTIFY_OK || ret == NOTIFY_STOP) - return 0; - if (ret) { + if (notifier_to_errno(ret)) { ret = notifier_to_errno(ret); pr_err("overlay changeset %s notifier error %d, target: %pOF\n", of_overlay_action_name[action], ret, nd.target);
From: Yuanchu Xie yuanchu@google.com
[ Upstream commit 678f0cdc572c5fda940cb038d70eebb8d818adc8 ]
Currently the damon selftests are not built with the rest of the selftests. We add damon to the list of targets.
Fixes: b348eb7abd09 ("mm/damon: add user space selftests") Reviewed-by: SeongJae Park sj@kernel.org Signed-off-by: Yuanchu Xie yuanchu@google.com Acked-by: David Rientjes rientjes@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 2319ec87f53d..bd2ac8b3bf1f 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -9,6 +9,7 @@ TARGETS += clone3 TARGETS += core TARGETS += cpufreq TARGETS += cpu-hotplug +TARGETS += damon TARGETS += drivers/dma-buf TARGETS += efivarfs TARGETS += exec
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit d28ea556267c4f2ec7264ab49f1b1296834321ec ]
Add calls to drm_bridge_add()/drm_bridge_remove() DRM bridges created by the driver. This fixes the following warning.
WARNING: CPU: 0 PID: 1 at kernel/locking/mutex.c:579 __mutex_lock+0x840/0x9f4 DEBUG_LOCKS_WARN_ON(lock->magic != lock) Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.18.0-rc1-00002-g3054695a0d27-dirty #55 Hardware name: Generic DT based system unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x58/0x70 dump_stack_lvl from __warn+0xc8/0x1e8 __warn from warn_slowpath_fmt+0x78/0xa8 warn_slowpath_fmt from __mutex_lock+0x840/0x9f4 __mutex_lock from mutex_lock_nested+0x1c/0x24 mutex_lock_nested from drm_bridge_hpd_enable+0x2c/0x84 drm_bridge_hpd_enable from msm_hdmi_modeset_init+0xc0/0x21c msm_hdmi_modeset_init from mdp4_kms_init+0x53c/0x90c mdp4_kms_init from msm_drm_bind+0x514/0x698 msm_drm_bind from try_to_bring_up_aggregate_device+0x160/0x1bc try_to_bring_up_aggregate_device from component_master_add_with_match+0xc4/0xf8 component_master_add_with_match from msm_pdev_probe+0x274/0x350 msm_pdev_probe from platform_probe+0x5c/0xbc platform_probe from really_probe.part.0+0x9c/0x290 really_probe.part.0 from __driver_probe_device+0xa8/0x13c __driver_probe_device from driver_probe_device+0x34/0x10c driver_probe_device from __driver_attach+0xbc/0x178 __driver_attach from bus_for_each_dev+0x74/0xc0 bus_for_each_dev from bus_add_driver+0x160/0x1e4 bus_add_driver from driver_register+0x88/0x118 driver_register from do_one_initcall+0x6c/0x334 do_one_initcall from kernel_init_freeable+0x1bc/0x220 kernel_init_freeable from kernel_init+0x18/0x12c kernel_init from ret_from_fork+0x14/0x2c
Fixes: 3d3f8b1f8b62 ("drm/bridge: make bridge registration independent of drm flow") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Patchwork: https://patchwork.freedesktop.org/patch/481778/ Link: https://lore.kernel.org/r/20220411234953.2425280-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/dp/dp_drm.c | 4 ++++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +++ drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 3 +++ drivers/gpu/drm/msm/msm_drv.c | 3 +++ 4 files changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 80f59cf99089..262744914f97 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -230,9 +230,13 @@ struct drm_bridge *msm_dp_bridge_init(struct msm_dp *dp_display, struct drm_devi bridge->funcs = &dp_bridge_ops; bridge->encoder = encoder;
+ drm_bridge_add(bridge); + rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (rc) { DRM_ERROR("failed to attach bridge, rc=%d\n", rc); + drm_bridge_remove(bridge); + return ERR_PTR(rc); }
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 9f6af0f0fe00..1db93e562fe6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -665,6 +665,8 @@ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) bridge = &dsi_bridge->base; bridge->funcs = &dsi_mgr_bridge_funcs;
+ drm_bridge_add(bridge); + ret = drm_bridge_attach(encoder, bridge, NULL, 0); if (ret) goto fail; @@ -735,6 +737,7 @@ struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge) { + drm_bridge_remove(bridge); }
int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 10ebe2089cb6..97c24010c4d1 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -15,6 +15,7 @@ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge) struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
msm_hdmi_hpd_disable(hdmi_bridge); + drm_bridge_remove(bridge); }
static void msm_hdmi_power_on(struct drm_bridge *bridge) @@ -349,6 +350,8 @@ struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi) DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID;
+ drm_bridge_add(bridge); + ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index affa95eb05fc..71e1b7393f6f 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -232,6 +232,9 @@ static int msm_drm_uninit(struct device *dev)
drm_mode_config_cleanup(ddev);
+ for (i = 0; i < priv->num_bridges; i++) + drm_bridge_remove(priv->bridges[i]); + pm_runtime_get_sync(dev); msm_irq_uninstall(ddev); pm_runtime_put_sync(dev);
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit e18aeea7f5efb9508722c8c7fd4d32e6f8cdfe50 ]
The “DP timing” requires the active region to be defined in the bottom-right corner of the frame dimensions which is different with DSI. Therefore both display_h_end and display_v_end need to be adjusted accordingly. However current implementation has only display_h_end adjusted.
Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com
Fixes: fc3a69ec68d3 ("drm/msm/dpu: intf timing path for displayport") Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/476277/ Link: https://lore.kernel.org/r/1645824192-29670-2-git-send-email-quic_khsieh@quic... 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_intf.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index 116e2b5b1a90..284f5610dc35 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -148,6 +148,7 @@ static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx, active_v_end = active_v_start + (p->yres * hsync_period) - 1;
display_v_start += p->hsync_pulse_width + p->h_back_porch; + display_v_end -= p->h_front_porch;
active_hctl = (active_h_end << 16) | active_h_start; display_hctl = active_hctl;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 565138ac5f8a5330669a20e5f94759764e9165ec ]
These flags are supposed to be bit numbers. Right now they cause a double shift bug where we use BIT(BIT(2)) instead of BIT(2). Fortunately, the bit numbers are small and it's done consistently so it does not cause an issue at run time.
Link: https://lore.kernel.org/r/YmFyWHf8nrrx+SHa@kili Fixes: 5bd856256f8c ("scsi: iscsi: Merge suspend fields") Reviewed-by: Mike Christie michael.christie@oracle.com Reviewed-by: Lee Duncan lduncan@suse.com 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 --- include/scsi/libiscsi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index d0a24779c52d..c0703cd20a99 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -54,9 +54,9 @@ enum { #define ISID_SIZE 6
/* Connection flags */ -#define ISCSI_CONN_FLAG_SUSPEND_TX BIT(0) -#define ISCSI_CONN_FLAG_SUSPEND_RX BIT(1) -#define ISCSI_CONN_FLAG_BOUND BIT(2) +#define ISCSI_CONN_FLAG_SUSPEND_TX 0 +#define ISCSI_CONN_FLAG_SUSPEND_RX 1 +#define ISCSI_CONN_FLAG_BOUND 2
#define ISCSI_ITT_MASK 0x1fff #define ISCSI_TOTAL_CMDS_MAX 4096
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit bee40dc167da159ea5b939c074e1da258610a3d6 ]
Clearing hba->is_sys_suspended if ufs_qcom_resume() succeeds is wrong. That variable must only be cleared if all actions involved in a resume succeed. Hence remove the statement that clears hba->is_sys_suspended from ufs_qcom_resume().
Link: https://lore.kernel.org/r/20220419225811.4127248-23-bvanassche@acm.org Fixes: 81c0fc51b7a7 ("ufs-qcom: add support for Qualcomm Technologies Inc platforms") Tested-by: Bean Huo beanhuo@micron.com Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Bean Huo beanhuo@micron.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/ufs/ufs-qcom.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 586c0e567ff9..e61083d01f6e 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -641,12 +641,7 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) return err; }
- err = ufs_qcom_ice_resume(host); - if (err) - return err; - - hba->is_sys_suspended = false; - return 0; + return ufs_qcom_ice_resume(host); }
static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_qcom_host *host, bool enable)
From: Kiwoong Kim kwmad.kim@samsung.com
[ Upstream commit ef60031022eb6d972aac86ca26c98c33e1289436 ]
Some devices may return invalid or zeroed data during an UIC error condition. In addition, reading these SFRs will clear them. This means the subsequent error handling will not be able to see them and therefore no error handling will be scheduled.
Skip reading these SFRs in ufshcd_dump_regs().
Link: https://lore.kernel.org/r/1648689845-33521-1-git-send-email-kwmad.kim@samsun... Fixes: d67247566450 ("scsi: ufs: Use explicit access size in ufshcd_dump_regs") Signed-off-by: Kiwoong Kim kwmad.kim@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3f9caafa91bf..4c9eb4be449c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -113,8 +113,13 @@ int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, if (!regs) return -ENOMEM;
- for (pos = 0; pos < len; pos += 4) + for (pos = 0; pos < len; pos += 4) { + if (offset == 0 && + pos >= REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER && + pos <= REG_UIC_ERROR_CODE_DME) + continue; regs[pos / 4] = ufshcd_readl(hba, offset + pos); + }
ufshcd_hex_dump(prefix, regs, len); kfree(regs);
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit ce7a1ecf3f9f1fccaf67295307614511d8e11b13 ]
In the unlikely event that pointer perfmon is null the WARN_ON return path occurs after the pointer has already been deferenced. Fix this by only dereferencing perfmon after it has been null checked.
Fixes: 26a4dc29b74a ("drm/v3d: Expose performance counters to userspace") Signed-off-by: Colin Ian King colin.i.king@gmail.com Reviewed-by: Juan A. Suarez jasuarez@igalia.com Signed-off-by: Melissa Wen melissa.srw@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20220424183512.1365683-1-colin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/v3d/v3d_perfmon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c index 0288ef063513..f6a88abccc7d 100644 --- a/drivers/gpu/drm/v3d/v3d_perfmon.c +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c @@ -25,11 +25,12 @@ void v3d_perfmon_start(struct v3d_dev *v3d, struct v3d_perfmon *perfmon) { unsigned int i; u32 mask; - u8 ncounters = perfmon->ncounters; + u8 ncounters;
if (WARN_ON_ONCE(!perfmon || v3d->active_perfmon)) return;
+ ncounters = perfmon->ncounters; mask = GENMASK(ncounters - 1, 0);
for (i = 0; i < ncounters; i++) {
From: Colin Ian King colin.i.king@gmail.com
[ Upstream commit c7b607fa9325ccc94982774c505176677117689c ]
Currently if opening /dev/null fails to open then file pointer fp is null and further access to fp via fprintf will cause a null pointer dereference. Fix this by returning a negative error value when a null fp is detected.
Detected using cppcheck static analysis: tools/testing/selftests/resctrl/fill_buf.c:124:6: note: Assuming that condition '!fp' is not redundant if (!fp) ^ tools/testing/selftests/resctrl/fill_buf.c:126:10: note: Null pointer dereference fprintf(fp, "Sum: %d ", ret);
Fixes: a2561b12fe39 ("selftests/resctrl: Add built in benchmark") Signed-off-by: Colin Ian King colin.i.king@gmail.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/resctrl/fill_buf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/resctrl/fill_buf.c b/tools/testing/selftests/resctrl/fill_buf.c index 51e5cf22632f..56ccbeae0638 100644 --- a/tools/testing/selftests/resctrl/fill_buf.c +++ b/tools/testing/selftests/resctrl/fill_buf.c @@ -121,8 +121,10 @@ static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
/* Consume read result so that reading memory is not optimized out. */ fp = fopen("/dev/null", "w"); - if (!fp) + if (!fp) { perror("Unable to write to /dev/null"); + return -1; + } fprintf(fp, "Sum: %d ", ret); fclose(fp);
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 966a7509325395c51c5f6d89e7352b0585e4804b ]
Fix the bug in bpf_object__relocate_core() which can lead to finding invalid matching BPF program when processing CO-RE relocation. IF matching program is not found, last encountered program will be assumed to be correct program and thus error detection won't detect the problem.
Fixes: 9c82a63cf370 ("libbpf: Fix CO-RE relocs against .text section") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20220426004511.2691730-4-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 7af6805a863d..881ea905ca81 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -5646,9 +5646,10 @@ bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path) */ prog = NULL; for (i = 0; i < obj->nr_programs; i++) { - prog = &obj->programs[i]; - if (strcmp(prog->sec_name, sec_name) == 0) + if (strcmp(obj->programs[i].sec_name, sec_name) == 0) { + prog = &obj->programs[i]; break; + } } if (!prog) { pr_warn("sec '%s': failed to find a BPF program\n", sec_name);
From: Chen-Tsung Hsieh chentsung@chromium.org
[ Upstream commit 70dd83d737d8900b2d98db6dc6b928c596334d37 ]
Read back Status Register 1 to ensure that the written byte match the received value and return -EIO if read back test failed.
Without this patch, spi_nor_write_16bit_sr_and_check() only check the second half of the 16bit. It causes errors like spi_nor_sr_unlock() return success incorrectly when spi_nor_write_16bit_sr_and_check() doesn't write SR successfully.
Fixes: 39d1e3340c73 ("mtd: spi-nor: Fix clearing of QE bit on lock()/unlock()") Signed-off-by: Chen-Tsung Hsieh chentsung@chromium.org Signed-off-by: Pratyush Yadav p.yadav@ti.com Reviewed-by: Michael Walle michael@walle.cc Reviewed-by: Tudor Ambarus tudor.ambarus@microchip.com Acked-by: Pratyush Yadav p.yadav@ti.com Link: https://lore.kernel.org/r/20220126073227.3401275-1-chentsung@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/spi-nor/core.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index b4f141ad9c9c..c1630131c734 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -788,6 +788,15 @@ static int spi_nor_write_16bit_sr_and_check(struct spi_nor *nor, u8 sr1) if (ret) return ret;
+ ret = spi_nor_read_sr(nor, sr_cr); + if (ret) + return ret; + + if (sr1 != sr_cr[0]) { + dev_dbg(nor->dev, "SR: Read back test failed\n"); + return -EIO; + } + if (nor->flags & SNOR_F_NO_READ_CR) return 0;
From: Matthieu Baerts matthieu.baerts@tessares.net
[ Upstream commit b0b592cf08367719e1d1ef07c9f136e8c17f7ec3 ]
Since
e2a1256b17b1 ("x86/speculation: Restore speculation related MSRs during S3 resume")
kmemleak reports this issue:
unreferenced object 0xffff888009cedc00 (size 256): comm "swapper/0", pid 1, jiffies 4294693823 (age 73.764s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00 ........H....... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: msr_build_context (include/linux/slab.h:621) pm_check_save_msr (arch/x86/power/cpu.c:520) do_one_initcall (init/main.c:1298) kernel_init_freeable (init/main.c:1370) kernel_init (init/main.c:1504) ret_from_fork (arch/x86/entry/entry_64.S:304)
Reproducer:
- boot the VM with a debug kernel config (see https://github.com/multipath-tcp/mptcp_net-next/issues/268) - wait ~1 minute - start a kmemleak scan
The root cause here is alignment within the packed struct saved_context (from suspend_64.h). Kmemleak only searches for pointers that are aligned (see how pointers are scanned in kmemleak.c), but pahole shows that the saved_msrs struct member and all members after it in the structure are unaligned:
struct saved_context { struct pt_regs regs; /* 0 168 */ /* --- cacheline 2 boundary (128 bytes) was 40 bytes ago --- */ u16 ds; /* 168 2 */
...
u64 misc_enable; /* 232 8 */ bool misc_enable_saved; /* 240 1 */
/* Note below odd offset values for the remainder of this struct */
struct saved_msrs saved_msrs; /* 241 16 */ /* --- cacheline 4 boundary (256 bytes) was 1 bytes ago --- */ long unsigned int efer; /* 257 8 */ u16 gdt_pad; /* 265 2 */ struct desc_ptr gdt_desc; /* 267 10 */ u16 idt_pad; /* 277 2 */ struct desc_ptr idt; /* 279 10 */ u16 ldt; /* 289 2 */ u16 tss; /* 291 2 */ long unsigned int tr; /* 293 8 */ long unsigned int safety; /* 301 8 */ long unsigned int return_address; /* 309 8 */
/* size: 317, cachelines: 5, members: 25 */ /* last cacheline: 61 bytes */ } __attribute__((__packed__));
Move misc_enable_saved to the end of the struct declaration so that saved_msrs fits in before the cacheline 4 boundary.
The comment above the saved_context declaration says to fix wakeup_64.S file and __save/__restore_processor_state() if the struct is modified: it looks like all the accesses in wakeup_64.S are done through offsets which are computed at build-time. Update that comment accordingly.
At the end, the false positive kmemleak report is due to a limitation from kmemleak but it is always good to avoid unaligned members for optimisation purposes.
Please note that it looks like this issue is not new, e.g.
https://lore.kernel.org/all/9f1bb619-c4ee-21c4-a251-870bd4db04fa@lwfinger.ne... https://lore.kernel.org/all/94e48fcd-1dbd-ebd2-4c91-f39941735909@molgen.mpg....
[ bp: Massage + cleanup commit message. ]
Fixes: 7a9c2dd08ead ("x86/pm: Introduce quirk framework to save/restore extra MSR registers around suspend/resume") Suggested-by: Mat Martineau mathew.j.martineau@linux.intel.com Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Link: https://lore.kernel.org/r/20220426202138.498310-1-matthieu.baerts@tessares.n... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/suspend_32.h | 2 +- arch/x86/include/asm/suspend_64.h | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h index 7b132d0312eb..a800abb1a992 100644 --- a/arch/x86/include/asm/suspend_32.h +++ b/arch/x86/include/asm/suspend_32.h @@ -19,7 +19,6 @@ struct saved_context { u16 gs; unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; - bool misc_enable_saved; struct saved_msrs saved_msrs; struct desc_ptr gdt_desc; struct desc_ptr idt; @@ -28,6 +27,7 @@ struct saved_context { unsigned long tr; unsigned long safety; unsigned long return_address; + bool misc_enable_saved; } __attribute__((packed));
/* routines for saving/restoring kernel state */ diff --git a/arch/x86/include/asm/suspend_64.h b/arch/x86/include/asm/suspend_64.h index 35bb35d28733..54df06687d83 100644 --- a/arch/x86/include/asm/suspend_64.h +++ b/arch/x86/include/asm/suspend_64.h @@ -14,9 +14,13 @@ * Image of the saved processor state, used by the low level ACPI suspend to * RAM code and by the low level hibernation code. * - * If you modify it, fix arch/x86/kernel/acpi/wakeup_64.S and make sure that - * __save/__restore_processor_state(), defined in arch/x86/kernel/suspend_64.c, - * still work as required. + * If you modify it, check how it is used in arch/x86/kernel/acpi/wakeup_64.S + * and make sure that __save/__restore_processor_state(), defined in + * arch/x86/power/cpu.c, still work as required. + * + * Because the structure is packed, make sure to avoid unaligned members. For + * optimisation purposes but also because tools like kmemleak only search for + * pointers that are aligned. */ struct saved_context { struct pt_regs regs; @@ -36,7 +40,6 @@ struct saved_context {
unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; - bool misc_enable_saved; struct saved_msrs saved_msrs; unsigned long efer; u16 gdt_pad; /* Unused */ @@ -48,6 +51,7 @@ struct saved_context { unsigned long tr; unsigned long safety; unsigned long return_address; + bool misc_enable_saved; } __attribute__((packed));
#define loaddebug(thread,register) \
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit a28ed09dafee20da51eb26452950839633afd824 ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref. And use devm_platform_get_and_ioremap_resource() to simplify code.
Fixes: ec4ba01e894d ("mtd: rawnand: Add new Cadence NAND driver to MTD subsystem") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220426084913.4021868-1-yangyingliang@hua... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/raw/cadence-nand-controller.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c index 7eec60ea9056..0d72672f8b64 100644 --- a/drivers/mtd/nand/raw/cadence-nand-controller.c +++ b/drivers/mtd/nand/raw/cadence-nand-controller.c @@ -2983,11 +2983,10 @@ static int cadence_nand_dt_probe(struct platform_device *ofdev) if (IS_ERR(cdns_ctrl->reg)) return PTR_ERR(cdns_ctrl->reg);
- res = platform_get_resource(ofdev, IORESOURCE_MEM, 1); - cdns_ctrl->io.dma = res->start; - cdns_ctrl->io.virt = devm_ioremap_resource(&ofdev->dev, res); + cdns_ctrl->io.virt = devm_platform_get_and_ioremap_resource(ofdev, 1, &res); if (IS_ERR(cdns_ctrl->io.virt)) return PTR_ERR(cdns_ctrl->io.virt); + cdns_ctrl->io.dma = res->start;
dt->clk = devm_clk_get(cdns_ctrl->dev, "nf_clk"); if (IS_ERR(dt->clk))
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit ddf66aefd685fd46500b9917333e1b1e118276dc ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref.
Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220426084913.4021868-2-yangyingliang@hua... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/raw/intel-nand-controller.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index 7c1c80dae826..e91b879b32bd 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -619,9 +619,9 @@ static int ebu_nand_probe(struct platform_device *pdev) resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname); ebu_host->cs[cs].chipaddr = devm_ioremap_resource(dev, res); - ebu_host->cs[cs].nand_pa = res->start; if (IS_ERR(ebu_host->cs[cs].chipaddr)) return PTR_ERR(ebu_host->cs[cs].chipaddr); + ebu_host->cs[cs].nand_pa = res->start;
ebu_host->clk = devm_clk_get(dev, NULL); if (IS_ERR(ebu_host->clk))
From: Josh Poimboeuf jpoimboe@redhat.com
[ Upstream commit 2147c438fde135d6c145a96e373d9348e7076f7f ]
Fix the following warnings seen with "make W=1":
kernel/sysctl.c:183:13: warning: no previous prototype for ‘unpriv_ebpf_notify’ [-Wmissing-prototypes] 183 | void __weak unpriv_ebpf_notify(int new_state) | ^~~~~~~~~~~~~~~~~~
arch/x86/kernel/cpu/bugs.c:659:6: warning: no previous prototype for ‘unpriv_ebpf_notify’ [-Wmissing-prototypes] 659 | void unpriv_ebpf_notify(int new_state) | ^~~~~~~~~~~~~~~~~~
Fixes: 44a3918c8245 ("x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation reporting") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Josh Poimboeuf jpoimboe@redhat.com Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/5689d065f739602ececaee1e05e68b8644009608.165093000... Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/bpf.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 67efaa38c33f..83bd5598ec4d 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1984,6 +1984,8 @@ void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev, struct net_device *netdev); bool bpf_offload_dev_match(struct bpf_prog *prog, struct net_device *netdev);
+void unpriv_ebpf_notify(int new_state); + #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr);
From: Nicolas Frattaroli frattaroli.nicolas@gmail.com
[ Upstream commit dd508e324cdde1c06ace08a8143fa50333a90703 ]
If preparing/enabling the pclk fails, the probe function should unprepare and disable the previously prepared and enabled mclk, which it doesn't do. This commit rectifies this.
Fixes: c32759035ad2 ("ASoC: rockchip: support ACODEC for rk3328") Signed-off-by: Nicolas Frattaroli frattaroli.nicolas@gmail.com Reviewed-by: Katsuhiro Suzuki katsuhiro@katsuster.net Link: https://lore.kernel.org/r/20220427172310.138638-1-frattaroli.nicolas@gmail.c... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rk3328_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rk3328_codec.c b/sound/soc/codecs/rk3328_codec.c index 758d439e8c7a..86b679cf7aef 100644 --- a/sound/soc/codecs/rk3328_codec.c +++ b/sound/soc/codecs/rk3328_codec.c @@ -481,7 +481,7 @@ static int rk3328_platform_probe(struct platform_device *pdev) ret = clk_prepare_enable(rk3328->pclk); if (ret < 0) { dev_err(&pdev->dev, "failed to enable acodec pclk\n"); - return ret; + goto err_unprepare_mclk; }
base = devm_platform_ioremap_resource(pdev, 0);
From: Yang Jihong yangjihong1@huawei.com
[ Upstream commit 4d27cf1d9de5becfa4d1efb2ea54dba1b9fc962a ]
'struct perf_data' in util/data.h uses the "u64" data type, which is defined in "linux/types.h".
If we only include util/data.h, the following compilation error occurs:
util/data.h:38:3: error: unknown type name ‘u64’ u64 version; ^~~
Solution: include "linux/types.h." to add the needed type definitions.
Fixes: 258031c017c353e8 ("perf header: Add DIR_FORMAT feature to describe directory data") Signed-off-by: Yang Jihong yangjihong1@huawei.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20220429090539.212448-1-yangjihong1@huawei.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/data.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/perf/util/data.h b/tools/perf/util/data.h index c9de82af5584..1402d9657ef2 100644 --- a/tools/perf/util/data.h +++ b/tools/perf/util/data.h @@ -4,6 +4,7 @@
#include <stdio.h> #include <stdbool.h> +#include <linux/types.h>
enum perf_data_mode { PERF_DATA_MODE_WRITE,
From: Vinod Polimera quic_vpolimer@quicinc.com
[ Upstream commit fa5186b279ecf44b14fb435540d2065be91cb1ed ]
BUG: Unable to handle kernel paging request at virtual address 006b6b6b6b6b6be3
Call trace: dpu_vbif_init_memtypes+0x40/0xb8 dpu_runtime_resume+0xcc/0x1c0 pm_generic_runtime_resume+0x30/0x44 __genpd_runtime_resume+0x68/0x7c genpd_runtime_resume+0x134/0x258 __rpm_callback+0x98/0x138 rpm_callback+0x30/0x88 rpm_resume+0x36c/0x49c __pm_runtime_resume+0x80/0xb0 dpu_core_irq_uninstall+0x30/0xb0 dpu_irq_uninstall+0x18/0x24 msm_drm_uninit+0xd8/0x16c
Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Vinod Polimera quic_vpolimer@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/483255/ Link: https://lore.kernel.org/r/1650857213-30075-1-git-send-email-quic_vpolimer@qu... [DB: fixed Fixes tag] Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index e29796c4f27b..ad13a9423601 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -793,8 +793,10 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms) for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
- if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) + if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) { dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]); + dpu_kms->hw_vbif[vbif_idx] = NULL; + } } }
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit 570d3e5d28db7a94557fa179167a9fb8642fb8a1 ]
Current DP driver implementation, event thread is kept running after DP display is unbind. This patch fix this problem by disabling DP irq and stop event thread to exit gracefully at dp_display_unbind().
Changes in v2: -- start event thread at dp_display_bind()
Changes in v3: -- disable all HDP interrupts at unbind -- replace dp_hpd_event_setup() with dp_hpd_event_thread_start() -- replace dp_hpd_event_stop() with dp_hpd_event_thread_stop() -- move init_waitqueue_head(&dp->event_q) to probe() -- move spin_lock_init(&dp->event_lock) to probe()
Changes in v4: -- relocate both dp_display_bind() and dp_display_unbind() to bottom of file
Changes in v5: -- cancel relocation of both dp_display_bind() and dp_display_unbind()
Changes in v6: -- move empty event q to dp_event_thread_start()
Changes in v7: -- call ktheread_stop() directly instead of dp_hpd_event_thread_stop() function
Changes in v8: -- return error immediately if audio registration failed.
Changes in v9: -- return error immediately if event thread create failed.
Changes in v10: -- delete extra DRM_ERROR("failed to create DP event thread\n");
Fixes: 8ede2ecc3e5e ("drm/msm/dp: Add DP compliance tests on Snapdragon Chipsets") Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com Reported-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/482399/ Link: https://lore.kernel.org/r/1650318988-17580-1-git-send-email-quic_khsieh@quic... [DB: fixed Fixes tag] Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_display.c | 39 +++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 178b774a5fbd..332065b882af 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -113,6 +113,7 @@ struct dp_display_private { u32 hpd_state; u32 event_pndx; u32 event_gndx; + struct task_struct *ev_tsk; struct dp_event event_list[DP_EVENT_Q_MAX]; spinlock_t event_lock;
@@ -249,6 +250,8 @@ void dp_display_signal_audio_complete(struct msm_dp *dp_display) complete_all(&dp->audio_comp); }
+static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv); + static int dp_display_bind(struct device *dev, struct device *master, void *data) { @@ -282,9 +285,18 @@ static int dp_display_bind(struct device *dev, struct device *master, }
rc = dp_register_audio_driver(dev, dp->audio); - if (rc) + if (rc) { DRM_ERROR("Audio registration Dp failed\n"); + goto end; + }
+ rc = dp_hpd_event_thread_start(dp); + if (rc) { + DRM_ERROR("Event thread create failed\n"); + goto end; + } + + return 0; end: return rc; } @@ -295,6 +307,11 @@ static void dp_display_unbind(struct device *dev, struct device *master, struct dp_display_private *dp = dev_get_dp_display_private(dev); struct msm_drm_private *priv = dev_get_drvdata(master);
+ /* disable all HPD interrupts */ + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false); + + kthread_stop(dp->ev_tsk); + dp_power_client_deinit(dp->power); dp_aux_unregister(dp->aux); priv->dp[dp->id] = NULL; @@ -1090,7 +1107,7 @@ static int hpd_event_thread(void *data)
dp_priv = (struct dp_display_private *)data;
- while (1) { + while (!kthread_should_stop()) { if (timeout_mode) { wait_event_timeout(dp_priv->event_q, (dp_priv->event_pndx == dp_priv->event_gndx), @@ -1168,12 +1185,17 @@ static int hpd_event_thread(void *data) return 0; }
-static void dp_hpd_event_setup(struct dp_display_private *dp_priv) +static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv) { - init_waitqueue_head(&dp_priv->event_q); - spin_lock_init(&dp_priv->event_lock); + /* set event q to empty */ + dp_priv->event_gndx = 0; + dp_priv->event_pndx = 0;
- kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler"); + dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler"); + if (IS_ERR(dp_priv->ev_tsk)) + return PTR_ERR(dp_priv->ev_tsk); + + return 0; }
static irqreturn_t dp_display_irq_handler(int irq, void *dev_id) @@ -1303,7 +1325,10 @@ static int dp_display_probe(struct platform_device *pdev) return -EPROBE_DEFER; }
+ /* setup event q */ mutex_init(&dp->event_mutex); + init_waitqueue_head(&dp->event_q); + spin_lock_init(&dp->event_lock);
/* Store DP audio handle inside DP display */ dp->dp_display.dp_audio = dp->audio; @@ -1483,8 +1508,6 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display)
dp = container_of(dp_display, struct dp_display_private, dp_display);
- dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); }
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit e92d0d93f86699b7b25c7906613fdc374d66c8ca ]
The irq_of_parse_and_map() function returns 0 on failure, and does not return an negative value.
Fixes: 8ede2ecc3e5e ("drm/msm/dp: Add DP compliance tests on Snapdragon Chipsets") Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/483176/ Link: https://lore.kernel.org/r/20220424032418.3173632-1-lv.ruyi@zte.com.cn Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_display.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 332065b882af..b3bfe9ac9d80 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1255,10 +1255,9 @@ int dp_display_request_irq(struct msm_dp *dp_display) dp = container_of(dp_display, struct dp_display_private, dp_display);
dp->irq = irq_of_parse_and_map(dp->pdev->dev.of_node, 0); - if (dp->irq < 0) { - rc = dp->irq; - DRM_ERROR("failed to get irq: %d\n", rc); - return rc; + if (!dp->irq) { + DRM_ERROR("failed to get irq\n"); + return -EINVAL; }
rc = devm_request_irq(&dp->pdev->dev, dp->irq,
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit 581d69981159b00f0443d171a4b900089f34ccfe ]
DP controller state can not switch from video ready state to transmit phy pattern state at run time. DP mainlink has to be teared down followed by reset controller to default state to have DP controller switch to transmit phy test pattern state and start generate specified phy test pattern to sinker once main link setup again.
Changes in v2: -- correct Fixes's commit id
Fixes: 52352fe2f866 ("drm/msm/dp: use dp_ctrl_off_link_stream during PHY compliance test run") Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/483563/ Link: https://lore.kernel.org/r/1650995939-28467-2-git-send-email-quic_khsieh@quic... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 53568567e05b..193cc1a597ff 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1532,7 +1532,7 @@ static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl) * running. Add the global reset just before disabling the * link clocks and core clocks. */ - ret = dp_ctrl_off_link_stream(&ctrl->dp_ctrl); + ret = dp_ctrl_off(&ctrl->dp_ctrl); if (ret) { DRM_ERROR("failed to disable DP controller\n"); return ret;
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit 2788b4efa60c1e03ac10a156f3fdbd3be0f9198c ]
At normal operation, transmit phy test pattern has to be terminated before DP controller switch to video ready state. However during phy compliance testing, transmit phy test pattern should not be terminated until end of compliance test which usually indicated by unplugged interrupt.
Only stop sending the train pattern in dp_ctrl_on_stream() if we're not doing compliance testing. We also no longer reset 'p_level' and 'v_level' within dp_ctrl_on_link() due to both 'p_level' and 'v_level' are acquired from link status at previous dpcd read and we like to use those level to start link training.
Changes in v2: -- add more details commit text -- correct Fixes
Changes in v3: -- drop unnecessary braces
Fixes: 2e0adc765d88 ("drm/msm/dp: do not end dp link training until video is ready") Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/483564/ Link: https://lore.kernel.org/r/1650995939-28467-3-git-send-email-quic_khsieh@quic... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 193cc1a597ff..08cc48af03b7 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1699,8 +1699,6 @@ int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl) ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes, ctrl->dp_ctrl.pixel_rate);
- ctrl->link->phy_params.p_level = 0; - ctrl->link->phy_params.v_level = 0;
rc = dp_ctrl_enable_mainlink_clocks(ctrl); if (rc) @@ -1822,12 +1820,6 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) } }
- if (!dp_ctrl_channel_eq_ok(ctrl)) - dp_ctrl_link_retrain(ctrl); - - /* stop txing train pattern to end link training */ - dp_ctrl_clear_training_pattern(ctrl); - ret = dp_ctrl_enable_stream_clocks(ctrl); if (ret) { DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret); @@ -1839,6 +1831,12 @@ int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl) return 0; }
+ if (!dp_ctrl_channel_eq_ok(ctrl)) + dp_ctrl_link_retrain(ctrl); + + /* stop txing train pattern to end link training */ + dp_ctrl_clear_training_pattern(ctrl); + /* * Set up transfer unit values and set controller state to send * video.
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit f0e7e9ed379c012c4d6b09a09b868accc426223c ]
As noticed by Dan ([1] an the followup thread) there are multiple issues with the return values for MSM DSI command transmission callback. In the error case it can easily return a positive value when it should have returned a proper error code.
This commits attempts to fix these issues both in TX and in RX paths.
[1]: https://lore.kernel.org/linux-arm-msm/20211001123617.GH2283@kili/
Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Tested-by: Marijn Suijten marijn.suijten@somainline.org Patchwork: https://patchwork.freedesktop.org/patch/480501/ Link: https://lore.kernel.org/r/20220401231104.967193-1-dmitry.baryshkov@linaro.or... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/dsi_host.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index d51e70fab93d..8925f60fd9ec 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1341,10 +1341,10 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host, dsi_get_bpp(msm_host->format) / 8;
len = dsi_cmd_dma_add(msm_host, msg); - if (!len) { + if (len < 0) { pr_err("%s: failed to add cmd type = 0x%x\n", __func__, msg->type); - return -EINVAL; + return len; }
/* for video mode, do not send cmds more than @@ -1363,10 +1363,14 @@ static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host, }
ret = dsi_cmd_dma_tx(msm_host, len); - if (ret < len) { - pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d\n", - __func__, msg->type, (*(u8 *)(msg->tx_buf)), len); - return -ECOMM; + if (ret < 0) { + pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d, ret=%d\n", + __func__, msg->type, (*(u8 *)(msg->tx_buf)), len, ret); + return ret; + } else if (ret < len) { + pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, ret=%d len=%d\n", + __func__, msg->type, (*(u8 *)(msg->tx_buf)), ret, len); + return -EIO; }
return len; @@ -2092,9 +2096,12 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host, }
ret = dsi_cmds2buf_tx(msm_host, msg); - if (ret < msg->tx_len) { + if (ret < 0) { pr_err("%s: Read cmd Tx failed, %d\n", __func__, ret); return ret; + } else if (ret < msg->tx_len) { + pr_err("%s: Read cmd Tx failed, too short: %d\n", __func__, ret); + return -ECOMM; }
/*
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit a36e506711548df923ceb7ec9f6001375be799a5 ]
It will cause null-ptr-deref if platform_get_resource_byname() returns NULL, we need check the return value.
Fixes: c6a57a50ad56 ("drm/msm/hdmi: add hdmi hdcp support (V3)") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/482992/ Link: https://lore.kernel.org/r/20220422032227.2991553-1-yangyingliang@huawei.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/hdmi/hdmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index ec324352e862..07e2ad527af9 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -142,6 +142,10 @@ static struct hdmi *msm_hdmi_init(struct platform_device *pdev) /* HDCP needs physical address of hdmi register */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, config->mmio_name); + if (!res) { + ret = -EINVAL; + goto fail; + } hdmi->mmio_phy_addr = res->start;
hdmi->qfprom_mmio = msm_ioremap(pdev, config->qfprom_mmio_name);
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit 03371e4fbdeb7f596cbceacb59e474248b6d95ac ]
The irq_of_parse_and_map() function returns 0 on failure, and does not return a negative value anyhow, so never enter this conditional branch.
Fixes: f6a8eaca0ea1 ("drm/msm/mdp5: use irqdomains") Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/483294/ Link: https://lore.kernel.org/r/20220425091831.3500487-1-lv.ruyi@zte.com.cn Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/hdmi/hdmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 07e2ad527af9..f6229262dcb0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -302,9 +302,9 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, drm_connector_attach_encoder(hdmi->connector, hdmi->encoder);
hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - if (hdmi->irq < 0) { - ret = hdmi->irq; - DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); + if (!hdmi->irq) { + ret = -EINVAL; + DRM_DEV_ERROR(dev->dev, "failed to get irq\n"); goto fail; }
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 8123fe83c3a3448bbfa5b5b1cacfdfe7d076fca6 ]
Add explicit include of drm_bridge.h to the msm_drv.c to fix the following warning:
drivers/gpu/drm/msm/msm_drv.c:236:17: error: implicit declaration of function 'drm_bridge_remove'; did you mean 'drm_bridge_detach'? [-Werror=implicit-function-declaration]
Fixes: d28ea556267c ("drm/msm: properly add and remove internal bridges") Reported-by: kernel test robot lkp@intel.com Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/484310/ Link: https://lore.kernel.org/r/20220430180917.3819294-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/msm_drv.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 71e1b7393f6f..e3d83963ad54 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -11,6 +11,7 @@ #include <linux/uaccess.h> #include <uapi/linux/sched/types.h>
+#include <drm/drm_bridge.h> #include <drm/drm_drv.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h>
From: Jagan Teki jagan@amarulasolutions.com
[ Upstream commit 7eafbecd2288c542ea15ea20cf1a7e64a25c21bc ]
AM-1280800N3TZQW-T00H panel support 8 bpc not 6 bpc as per recent testing in i.MX8MM platform.
Fix it.
Fixes: bca684e69c4c ("drm/panel: simple: Add AM-1280800N3TZQW-T00H") Signed-off-by: Jagan Teki jagan@amarulasolutions.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/20211111094103.494831-1-jagan@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/panel/panel-simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 00b9e1d22087..6880dc59fa88 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -720,7 +720,7 @@ static const struct drm_display_mode ampire_am_1280800n3tzqw_t00h_mode = { static const struct panel_desc ampire_am_1280800n3tzqw_t00h = { .modes = &ire_am_1280800n3tzqw_t00h_mode, .num_modes = 1, - .bpc = 6, + .bpc = 8, .size = { .width = 217, .height = 136,
From: Pin-Yen Lin treapking@chromium.org
[ Upstream commit 46ca7da7f1e8592af6059419176dd58c10dcdb5b ]
Send DPCD SET_POWER command to downstream in .atomic_disable to make the downstream monitor enter the power down mode, so the device suspend won't be affected.
Fixes: b5c84a9edcd418 ("drm/bridge: add it6505 driver") Signed-off-by: Pin-Yen Lin treapking@chromium.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20220425134424.1150965-1-treap... Reviewed-by: Robert Foss robert.foss@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ite-it6505.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c index f2f101220ade..c54664677172 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -737,8 +737,9 @@ static int it6505_drm_dp_link_probe(struct drm_dp_aux *aux, return 0; }
-static int it6505_drm_dp_link_power_up(struct drm_dp_aux *aux, - struct it6505_drm_dp_link *link) +static int it6505_drm_dp_link_set_power(struct drm_dp_aux *aux, + struct it6505_drm_dp_link *link, + u8 mode) { u8 value; int err; @@ -752,18 +753,20 @@ static int it6505_drm_dp_link_power_up(struct drm_dp_aux *aux, return err;
value &= ~DP_SET_POWER_MASK; - value |= DP_SET_POWER_D0; + value |= mode;
err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); if (err < 0) return err;
- /* - * According to the DP 1.1 specification, a "Sink Device must exit the - * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink - * Control Field" (register 0x600). - */ - usleep_range(1000, 2000); + if (mode == DP_SET_POWER_D0) { + /* + * According to the DP 1.1 specification, a "Sink Device must + * exit the power saving state within 1 ms" (Section 2.5.3.1, + * Table 5-52, "Sink Control Field" (register 0x600). + */ + usleep_range(1000, 2000); + }
return 0; } @@ -2624,7 +2627,8 @@ static enum drm_connector_status it6505_detect(struct it6505 *it6505) if (it6505_get_sink_hpd_status(it6505)) { it6505_aux_on(it6505); it6505_drm_dp_link_probe(&it6505->aux, &it6505->link); - it6505_drm_dp_link_power_up(&it6505->aux, &it6505->link); + it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, + DP_SET_POWER_D0); it6505->auto_train_retry = AUTO_TRAIN_RETRY;
if (it6505->dpcd[0] == 0) { @@ -2960,8 +2964,11 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
DRM_DEV_DEBUG_DRIVER(dev, "start");
- if (it6505->powered) + if (it6505->powered) { it6505_video_disable(it6505); + it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, + DP_SET_POWER_D3); + } }
static enum drm_connector_status
From: Luca Weiss luca@z3ntu.xyz
[ Upstream commit 36a1d1bda77e1851bddfa9cf4e8ada94476dbaff ]
Check if 'aspace' is set before using it as it will stay null without IOMMU, such as on msm8974.
Fixes: bc2112583a0b ("drm/msm/gpu: Track global faults per address-space") Signed-off-by: Luca Weiss luca@z3ntu.xyz Link: https://lore.kernel.org/r/20220421203455.313523-1-luca@z3ntu.xyz Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 5 ++++- drivers/gpu/drm/msm/msm_gpu.c | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9efc84929be0..1219f71629a5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -272,7 +272,10 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, *value = 0; return 0; case MSM_PARAM_FAULTS: - *value = gpu->global_faults + ctx->aspace->faults; + if (ctx->aspace) + *value = gpu->global_faults + ctx->aspace->faults; + else + *value = gpu->global_faults; return 0; case MSM_PARAM_SUSPENDS: *value = gpu->suspend_count; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index faf0c242874e..58eb3e1662cb 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -371,7 +371,8 @@ static void recover_worker(struct kthread_work *work)
/* Increment the fault counts */ submit->queue->faults++; - submit->aspace->faults++; + if (submit->aspace) + submit->aspace->faults++;
task = get_pid_task(submit->pid, PIDTYPE_PID); if (task) {
From: Daniel Latypov dlatypov@google.com
[ Upstream commit 38289a26e1b8a37755f3e07056ca416c1ee2a2e8 ]
Commit 6d2426b2f258 ("kunit: Support skipped tests") switched to using `enum kunit_status` to track the result of running a test/suite since we now have more than just pass/fail.
This callsite wasn't updated, silently converting to enum to a bool and then back.
Fixes: 6d2426b2f258 ("kunit: Support skipped tests") Signed-off-by: Daniel Latypov dlatypov@google.com Reviewed-by: Brendan Higgins brendanhiggins@google.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/kunit/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/kunit/debugfs.c b/lib/kunit/debugfs.c index b71db0abc12b..1048ef1b8d6e 100644 --- a/lib/kunit/debugfs.c +++ b/lib/kunit/debugfs.c @@ -52,7 +52,7 @@ static void debugfs_print_result(struct seq_file *seq, static int debugfs_print_results(struct seq_file *seq, void *v) { struct kunit_suite *suite = (struct kunit_suite *)seq->private; - bool success = kunit_suite_has_succeeded(suite); + enum kunit_status success = kunit_suite_has_succeeded(suite); struct kunit_case *test_case;
if (!suite || !suite->log)
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit f8c242908ad15bbd604d3bcb54961b7d454c43f8 ]
It will cause null-ptr-deref in resource_size(), if platform_get_resource() returns NULL, move calling resource_size() after devm_ioremap_resource() that will check 'res' to avoid null-ptr-deref.
Fixes: 2048e3286f34 ("drm: rockchip: Add basic drm driver") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://patchwork.freedesktop.org/patch/msgid/20220422032854.2995175-1-yangy... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 3e8d9e2d1b67..d53037531f40 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -2118,10 +2118,10 @@ static int vop_bind(struct device *dev, struct device *master, void *data) vop_win_init(vop);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - vop->len = resource_size(res); vop->regs = devm_ioremap_resource(dev, res); if (IS_ERR(vop->regs)) return PTR_ERR(vop->regs); + vop->len = resource_size(res);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (res) {
From: Ian Abbott abbotti@mev.co.uk
[ Upstream commit f724c296f2f2cc3f9342b0fc26239635cbed856e ]
The Cadence QSPI compatible string required for the SoCFPGA platform changed from the default "cdns,qspi-nor" to "intel,socfpga-qspi" with the introduction of an additional quirk in commit 98d948eb8331 ("spi: cadence-quadspi: fix write completion support"). However, that change did not preserve the previously used quirk for this platform. Reinstate the `CQSPI_DISABLE_DAC_MODE` quirk for the SoCFPGA platform.
Fixes: 98d948eb8331 ("spi: cadence-quadspi: fix write completion support") Cc: Dinh Nguyen dinguyen@kernel.org Signed-off-by: Ian Abbott abbotti@mev.co.uk Link: https://lore.kernel.org/r/20220427153446.10113-1-abbotti@mev.co.uk Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-cadence-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 19686fb47bb3..ec53b807909e 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1865,7 +1865,7 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = { };
static const struct cqspi_driver_platdata socfpga_qspi = { - .quirks = CQSPI_NO_SUPPORT_WR_COMPLETION, + .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NO_SUPPORT_WR_COMPLETION, };
static const struct cqspi_driver_platdata versal_ospi = {
From: James Clark james.clark@arm.com
[ Upstream commit 630af16eee495f583db5202c3613d1b191f10694 ]
This fixes the issue where the build will fail if only the Python2 runtime is installed but the Python3 devtools are installed. Currently the workaround is 'make PYTHON=python3'.
Fix it by autodetecting Python based on whether python[x]-config exists rather than just python[x] because both are needed for the build. Then -config is stripped to find the Python runtime.
Testing =======
* Auto detect links with Python3 when the v3 devtools are installed and only Python 2 runtime is installed * Auto detect links with Python2 when both devtools are installed * Sensible warning is printed if no Python devtools are installed * 'make PYTHON=x' still automatically sets PYTHON_CONFIG=x-config * 'make PYTHON=x' fails if x-config doesn't exist * 'make PYTHON=python3' overrides Python2 devtools * 'make PYTHON=python2' overrides Python3 devtools * 'make PYTHON_CONFIG=x-config' works * 'make PYTHON=x PYTHON_CONFIG=x' works * 'make PYTHON=missing' reports an error * 'make PYTHON_CONFIG=missing' reports an error
Fixes: 79373082fa9de8be ("perf python: Autodetect python3 binary") Signed-off-by: James Clark james.clark@arm.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: James Clark james.clark@arm.com Cc: Jiri Olsa jolsa@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Link: https://lore.kernel.org/r/20220309194313.3350126-2-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/Makefile.config | 39 ++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 1bd64e7404b9..c38423807d01 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -239,18 +239,33 @@ ifdef PARSER_DEBUG endif
# Try different combinations to accommodate systems that only have -# python[2][-config] in weird combinations but always preferring -# python2 and python2-config as per pep-0394. If python2 or python -# aren't found, then python3 is used. -PYTHON_AUTO := python -PYTHON_AUTO := $(if $(call get-executable,python3),python3,$(PYTHON_AUTO)) -PYTHON_AUTO := $(if $(call get-executable,python),python,$(PYTHON_AUTO)) -PYTHON_AUTO := $(if $(call get-executable,python2),python2,$(PYTHON_AUTO)) -override PYTHON := $(call get-executable-or-default,PYTHON,$(PYTHON_AUTO)) -PYTHON_AUTO_CONFIG := \ - $(if $(call get-executable,$(PYTHON)-config),$(PYTHON)-config,python-config) -override PYTHON_CONFIG := \ - $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON_AUTO_CONFIG)) +# python[2][3]-config in weird combinations in the following order of +# priority from lowest to highest: +# * python3-config +# * python-config +# * python2-config as per pep-0394. +# * $(PYTHON)-config (If PYTHON is user supplied but PYTHON_CONFIG isn't) +# +PYTHON_AUTO := python-config +PYTHON_AUTO := $(if $(call get-executable,python3-config),python3-config,$(PYTHON_AUTO)) +PYTHON_AUTO := $(if $(call get-executable,python-config),python-config,$(PYTHON_AUTO)) +PYTHON_AUTO := $(if $(call get-executable,python2-config),python2-config,$(PYTHON_AUTO)) + +# If PYTHON is defined but PYTHON_CONFIG isn't, then take $(PYTHON)-config as if it was the user +# supplied value for PYTHON_CONFIG. Because it's "user supplied", error out if it doesn't exist. +ifdef PYTHON + ifndef PYTHON_CONFIG + PYTHON_CONFIG_AUTO := $(call get-executable,$(PYTHON)-config) + PYTHON_CONFIG := $(if $(PYTHON_CONFIG_AUTO),$(PYTHON_CONFIG_AUTO),\ + $(call $(error $(PYTHON)-config not found))) + endif +endif + +# Select either auto detected python and python-config or use user supplied values if they are +# defined. get-executable-or-default fails with an error if the first argument is supplied but +# doesn't exist. +override PYTHON_CONFIG := $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON_AUTO)) +override PYTHON := $(call get-executable-or-default,PYTHON,$(subst -config,,$(PYTHON_AUTO)))
grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1))
From: Christoph Hellwig hch@lst.de
[ Upstream commit 62952cc5bccd89b76d710de1d0b43244af0f2903 ]
The discard_alignment queue limit is named a bit misleading means the offset into the block device at which the discard granularity starts.
On the other hand the discard_sector_alignment from the virtio 1.1 looks similar to what Linux uses as discard granularity (even if not very well described):
"discard_sector_alignment can be used by OS when splitting a request based on alignment. "
And at least qemu does set it to the discard granularity.
So stop setting the discard_alignment and use the virtio discard_sector_alignment to set the discard granularity.
Fixes: 1f23816b8eb8 ("virtio_blk: add discard and write zeroes support") Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Martin K. Petersen martin.petersen@oracle.com Link: https://lore.kernel.org/r/20220418045314.360785-5-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/virtio_blk.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index a8bcf3f664af..10bba1e00f2b 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -867,11 +867,12 @@ static int virtblk_probe(struct virtio_device *vdev) blk_queue_io_opt(q, blk_size * opt_io_size);
if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD)) { - q->limits.discard_granularity = blk_size; - virtio_cread(vdev, struct virtio_blk_config, discard_sector_alignment, &v); - q->limits.discard_alignment = v ? v << SECTOR_SHIFT : 0; + if (v) + q->limits.discard_granularity = v << SECTOR_SHIFT; + else + q->limits.discard_granularity = blk_size;
virtio_cread(vdev, struct virtio_blk_config, max_discard_sectors, &v);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 1b550a0bebfc0b69d6ec08fe6eb58953a8aec48a ]
It's not necessary to hold the RTNL across color change requests, since all the inner locking needs only the wiphy mutex which we already hold as well.
Fixes: 0d2ab3aea50b ("nl80211: add support for BSS coloring") Link: https://lore.kernel.org/r/20220414140402.32e03e8c261b.I5e7dc6bc563a129b938c4... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/nl80211.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 02a29052e41d..fd8b48b88968 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -16287,8 +16287,7 @@ static const struct genl_small_ops nl80211_small_ops[] = { .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .doit = nl80211_color_change, .flags = GENL_UNS_ADMIN_PERM, - .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | - NL80211_FLAG_NEED_RTNL, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP, }, { .cmd = NL80211_CMD_SET_FILS_AAD,
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 12441ccdf5e2f5a01a46e344976cbbd3d46845c9 ]
__setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled. A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument (no '=') or environment (with '=') strings. So return 1 from these x86 __setup handlers.
Examples:
Unknown kernel command line parameters "apicpmtimer BOOT_IMAGE=/boot/bzImage-517rc8 vdso=1 ring3mwait=disable", will be passed to user space.
Run /sbin/init as init process with arguments: /sbin/init apicpmtimer with environment: HOME=/ TERM=linux BOOT_IMAGE=/boot/bzImage-517rc8 vdso=1 ring3mwait=disable
Fixes: 2aae950b21e4 ("x86_64: Add vDSO for x86-64 with gettimeofday/clock_gettime/getcpu") Fixes: 77b52b4c5c66 ("x86: add "debugpat" boot option") Fixes: e16fd002afe2 ("x86/cpufeature: Enable RING3MWAIT for Knights Landing") Fixes: b8ce33590687 ("x86_64: convert to clock events") Reported-by: Igor Zhbanov i.zhbanov@omprussia.ru Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru Link: https://lore.kernel.org/r/20220314012725.26661-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/entry/vdso/vma.c | 2 +- arch/x86/kernel/apic/apic.c | 2 +- arch/x86/kernel/cpu/intel.c | 2 +- arch/x86/mm/pat/memtype.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 235a5794296a..1000d457c332 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -438,7 +438,7 @@ bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs) static __init int vdso_setup(char *s) { vdso64_enabled = simple_strtoul(s, NULL, 0); - return 0; + return 1; } __setup("vdso=", vdso_setup);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index b70344bf6600..ed7d9cf71f68 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -170,7 +170,7 @@ static __init int setup_apicpmtimer(char *s) { apic_calibrate_pmtmr = 1; notsc_setup(NULL); - return 0; + return 1; } __setup("apicpmtimer", setup_apicpmtimer); #endif diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index f7a5370a9b3b..2c87d62f191e 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -91,7 +91,7 @@ static bool ring3mwait_disabled __read_mostly; static int __init ring3mwait_disable(char *__unused) { ring3mwait_disabled = true; - return 0; + return 1; } __setup("ring3mwait=disable", ring3mwait_disable);
diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c index 4ba2a3ee4bce..d5ef64ddd35e 100644 --- a/arch/x86/mm/pat/memtype.c +++ b/arch/x86/mm/pat/memtype.c @@ -101,7 +101,7 @@ int pat_debug_enable; static int __init pat_debug_setup(char *str) { pat_debug_enable = 1; - return 0; + return 1; } __setup("debugpat", pat_debug_setup);
From: Daniel Thompson daniel.thompson@linaro.org
[ Upstream commit 4efc851c36e389f7ed432edac0149acc5f94b0c7 ]
Currently the EXIU uses the fasteoi interrupt flow that is configured by it's parent (irq-gic-v3.c). With this flow the only chance to clear the interrupt request happens during .irq_eoi() and (obviously) this happens after the interrupt handler has run. EXIU requires edge triggered interrupts to be acked prior to interrupt handling. Without this we risk incorrect interrupt dismissal when a new interrupt is delivered after the handler reads and acknowledges the peripheral but before the irq_eoi() takes place.
Fix this by clearing the interrupt request from .irq_ack() if we are configured for edge triggered interrupts. This requires adopting the fasteoi-ack flow instead of the fasteoi to ensure the ack gets called.
These changes have been tested using the power button on a Developerbox/SC2A11 combined with some hackery in gpio-keys so I can play with the different trigger mode [and an mdelay(500) so I can can check what happens on a double click in both modes].
Fixes: 706cffc1b912 ("irqchip/exiu: Add support for Socionext Synquacer EXIU controller") Signed-off-by: Daniel Thompson daniel.thompson@linaro.org Reviewed-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220503134541.2566457-1-daniel.thompson@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/Kconfig.platforms | 1 + drivers/irqchip/irq-sni-exiu.c | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 30b123cde02c..aaeaf57c8222 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -253,6 +253,7 @@ config ARCH_INTEL_SOCFPGA
config ARCH_SYNQUACER bool "Socionext SynQuacer SoC Family" + select IRQ_FASTEOI_HIERARCHY_HANDLERS
config ARCH_TEGRA bool "NVIDIA Tegra SoC Family" diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c index abd011fcecf4..c7db617e1a2f 100644 --- a/drivers/irqchip/irq-sni-exiu.c +++ b/drivers/irqchip/irq-sni-exiu.c @@ -37,11 +37,26 @@ struct exiu_irq_data { u32 spi_base; };
-static void exiu_irq_eoi(struct irq_data *d) +static void exiu_irq_ack(struct irq_data *d) { struct exiu_irq_data *data = irq_data_get_irq_chip_data(d);
writel(BIT(d->hwirq), data->base + EIREQCLR); +} + +static void exiu_irq_eoi(struct irq_data *d) +{ + struct exiu_irq_data *data = irq_data_get_irq_chip_data(d); + + /* + * Level triggered interrupts are latched and must be cleared during + * EOI or the interrupt will be jammed on. Of course if a level + * triggered interrupt is still asserted then the write will not clear + * the interrupt. + */ + if (irqd_is_level_type(d)) + writel(BIT(d->hwirq), data->base + EIREQCLR); + irq_chip_eoi_parent(d); }
@@ -91,10 +106,13 @@ static int exiu_irq_set_type(struct irq_data *d, unsigned int type) writel_relaxed(val, data->base + EILVL);
val = readl_relaxed(data->base + EIEDG); - if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) + if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) { val &= ~BIT(d->hwirq); - else + irq_set_handler_locked(d, handle_fasteoi_irq); + } else { val |= BIT(d->hwirq); + irq_set_handler_locked(d, handle_fasteoi_ack_irq); + } writel_relaxed(val, data->base + EIEDG);
writel_relaxed(BIT(d->hwirq), data->base + EIREQCLR); @@ -104,6 +122,7 @@ static int exiu_irq_set_type(struct irq_data *d, unsigned int type)
static struct irq_chip exiu_irq_chip = { .name = "EXIU", + .irq_ack = exiu_irq_ack, .irq_eoi = exiu_irq_eoi, .irq_enable = exiu_irq_enable, .irq_mask = exiu_irq_mask,
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 50f0f26e7c8665763d0d7d3372dbcf191f94d077 ]
The irq_of_parse_and_map() returns 0 on failure, not a negative ERRNO.
Fixes: f48e699ddf70 ("irqchip/aspeed-i2c-ic: Add I2C IRQ controller for Aspeed") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220423094227.33148-1-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-aspeed-i2c-ic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-aspeed-i2c-ic.c b/drivers/irqchip/irq-aspeed-i2c-ic.c index a47db16ff960..9c9fc3e2967e 100644 --- a/drivers/irqchip/irq-aspeed-i2c-ic.c +++ b/drivers/irqchip/irq-aspeed-i2c-ic.c @@ -77,8 +77,8 @@ static int __init aspeed_i2c_ic_of_init(struct device_node *node, }
i2c_ic->parent_irq = irq_of_parse_and_map(node, 0); - if (i2c_ic->parent_irq < 0) { - ret = i2c_ic->parent_irq; + if (!i2c_ic->parent_irq) { + ret = -EINVAL; goto err_iounmap; }
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit f03a9670d27d23fe734a456f16e2579b21ec02b4 ]
The irq_of_parse_and_map() returns 0 on failure, not a negative ERRNO.
Fixes: 04f605906ff0 ("irqchip: Add Aspeed SCU interrupt controller") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220423094227.33148-2-krzysztof.kozlowski@linaro.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-aspeed-scu-ic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-aspeed-scu-ic.c b/drivers/irqchip/irq-aspeed-scu-ic.c index 18b77c3e6db4..279e92cf0b16 100644 --- a/drivers/irqchip/irq-aspeed-scu-ic.c +++ b/drivers/irqchip/irq-aspeed-scu-ic.c @@ -157,8 +157,8 @@ static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic, }
irq = irq_of_parse_and_map(node, 0); - if (irq < 0) { - rc = irq; + if (!irq) { + rc = -EINVAL; goto err; }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 1ef64b1e89e6d4018da46e08ffc32779a31160c7 ]
Clean up control_va_addr_alignment():
a. Make '=' required instead of optional (as documented). b. Print a warning if an invalid option value is used. c. Return 1 from the __setup handler when an invalid option value is used. This prevents the kernel from polluting init's (limited) environment space with the entire string.
Fixes: dfb09f9b7ab0 ("x86, amd: Avoid cache aliasing penalties on AMD family 15h") Reported-by: Igor Zhbanov i.zhbanov@omprussia.ru Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Link: https://lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru Link: https://lore.kernel.org/r/20220315001045.7680-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/sys_x86_64.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c index 660b78827638..8cc653ffdccd 100644 --- a/arch/x86/kernel/sys_x86_64.c +++ b/arch/x86/kernel/sys_x86_64.c @@ -68,9 +68,6 @@ static int __init control_va_addr_alignment(char *str) if (*str == 0) return 1;
- if (*str == '=') - str++; - if (!strcmp(str, "32")) va_align.flags = ALIGN_VA_32; else if (!strcmp(str, "64")) @@ -80,11 +77,11 @@ static int __init control_va_addr_alignment(char *str) else if (!strcmp(str, "on")) va_align.flags = ALIGN_VA_32 | ALIGN_VA_64; else - return 0; + pr_warn("invalid option value: 'align_va_addr=%s'\n", str);
return 1; } -__setup("align_va_addr", control_va_addr_alignment); +__setup("align_va_addr=", control_va_addr_alignment);
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags,
From: Tong Tiangen tongtiangen@huawei.com
[ Upstream commit 921d161f15d6b090599f6a8c23f131969edbd1fa ]
In copy_highpage() the `kto` and `kfrom` local variables are pointers to struct page, but these are used to hold arbitrary pointers to kernel memory . Each call to page_address() returns a void pointer to memory associated with the relevant page, and copy_page() expects void pointers to this memory.
This inconsistency was introduced in commit 2563776b41c3 ("arm64: mte: Tags-aware copy_{user_,}highpage() implementations") and while this doesn't appear to be harmful in practice it is clearly wrong.
Correct this by making `kto` and `kfrom` void pointers.
Fixes: 2563776b41c3 ("arm64: mte: Tags-aware copy_{user_,}highpage() implementations") Signed-off-by: Tong Tiangen tongtiangen@huawei.com Acked-by: Mark Rutland mark.rutland@arm.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Link: https://lore.kernel.org/r/20220420030418.3189040-3-tongtiangen@huawei.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/mm/copypage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/copypage.c b/arch/arm64/mm/copypage.c index b5447e53cd73..0dea80bf6de4 100644 --- a/arch/arm64/mm/copypage.c +++ b/arch/arm64/mm/copypage.c @@ -16,8 +16,8 @@
void copy_highpage(struct page *to, struct page *from) { - struct page *kto = page_address(to); - struct page *kfrom = page_address(from); + void *kto = page_address(to); + void *kfrom = page_address(from);
copy_page(kto, kfrom);
From: Zev Weiss zev@bewilderbeest.net
[ Upstream commit c3e3ca05dae37f8f74bb80358efd540911cbc2c8 ]
Since the introduction of regulator->enable_count, a driver that did an exclusive get on an already-enabled regulator would end up with enable_count initialized to 0 but rdev->use_count initialized to 1. With that starting point the regulator is effectively stuck enabled, because if the driver attempted to disable it it would fail the enable_count underflow check in _regulator_handle_consumer_disable().
The EXCLUSIVE_GET path in _regulator_get() now initializes enable_count along with rdev->use_count so that the regulator can be disabled without underflowing the former.
Signed-off-by: Zev Weiss zev@bewilderbeest.net Fixes: 5451781dadf85 ("regulator: core: Only count load for enabled consumers") Link: https://lore.kernel.org/r/20220505043152.12933-1-zev@bewilderbeest.net Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index d2553970a67b..c4d844ffad7a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2133,10 +2133,13 @@ struct regulator *_regulator_get(struct device *dev, const char *id, rdev->exclusive = 1;
ret = _regulator_is_enabled(rdev); - if (ret > 0) + if (ret > 0) { rdev->use_count = 1; - else + regulator->enable_count = 1; + } else { rdev->use_count = 0; + regulator->enable_count = 0; + } }
link = device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS);
From: H. Nikolaus Schaller hns@goldelico.com
[ Upstream commit 454744754cbf2c21b3fc7344e46e10bee2768094 ]
With introduction of vmap'ed stacks, stack parameters can no longer be used for DMA and now leads to kernel panic.
It happens at several places for the wl1251 (e.g. when accessed through SDIO) making it unuseable on e.g. the OpenPandora.
We solve this by allocating temporary buffers or use wl1251_read32().
Tested on v5.18-rc5 with OpenPandora.
Fixes: a1c510d0adc6 ("ARM: implement support for vmap'ed stacks") Signed-off-by: H. Nikolaus Schaller hns@goldelico.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/1676021ae8b6d7aada0b1806fed99b1b8359bdc4.165149511... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ti/wl1251/event.c | 22 ++++++++++++++-------- drivers/net/wireless/ti/wl1251/io.c | 20 ++++++++++++++------ drivers/net/wireless/ti/wl1251/tx.c | 15 +++++++++++---- 3 files changed, 39 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index e6d426edab56..e945aafd88ee 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c @@ -169,11 +169,9 @@ int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms) msleep(1);
/* read from both event fields */ - wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector, - sizeof(events_vector)); + events_vector = wl1251_mem_read32(wl, wl->mbox_ptr[0]); event = events_vector & mask; - wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector, - sizeof(events_vector)); + events_vector = wl1251_mem_read32(wl, wl->mbox_ptr[1]); event |= events_vector & mask; } while (!event);
@@ -202,7 +200,7 @@ void wl1251_event_mbox_config(struct wl1251 *wl)
int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num) { - struct event_mailbox mbox; + struct event_mailbox *mbox; int ret;
wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num); @@ -210,12 +208,20 @@ int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num) if (mbox_num > 1) return -EINVAL;
+ mbox = kmalloc(sizeof(*mbox), GFP_KERNEL); + if (!mbox) { + wl1251_error("can not allocate mbox buffer"); + return -ENOMEM; + } + /* first we read the mbox descriptor */ - wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox, - sizeof(struct event_mailbox)); + wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], mbox, + sizeof(*mbox));
/* process the descriptor */ - ret = wl1251_event_process(wl, &mbox); + ret = wl1251_event_process(wl, mbox); + kfree(mbox); + if (ret < 0) return ret;
diff --git a/drivers/net/wireless/ti/wl1251/io.c b/drivers/net/wireless/ti/wl1251/io.c index 5ebe7958ed5c..e8d567af74b4 100644 --- a/drivers/net/wireless/ti/wl1251/io.c +++ b/drivers/net/wireless/ti/wl1251/io.c @@ -121,7 +121,13 @@ void wl1251_set_partition(struct wl1251 *wl, u32 mem_start, u32 mem_size, u32 reg_start, u32 reg_size) { - struct wl1251_partition partition[2]; + struct wl1251_partition_set *partition; + + partition = kmalloc(sizeof(*partition), GFP_KERNEL); + if (!partition) { + wl1251_error("can not allocate partition buffer"); + return; + }
wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X", mem_start, mem_size); @@ -164,10 +170,10 @@ void wl1251_set_partition(struct wl1251 *wl, reg_start, reg_size); }
- partition[0].start = mem_start; - partition[0].size = mem_size; - partition[1].start = reg_start; - partition[1].size = reg_size; + partition->mem.start = mem_start; + partition->mem.size = mem_size; + partition->reg.start = reg_start; + partition->reg.size = reg_size;
wl->physical_mem_addr = mem_start; wl->physical_reg_addr = reg_start; @@ -176,5 +182,7 @@ void wl1251_set_partition(struct wl1251 *wl, wl->virtual_reg_addr = mem_size;
wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition, - sizeof(partition)); + sizeof(*partition)); + + kfree(partition); } diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c index 98cd39619d57..e9dc3c72bb11 100644 --- a/drivers/net/wireless/ti/wl1251/tx.c +++ b/drivers/net/wireless/ti/wl1251/tx.c @@ -443,19 +443,25 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl, void wl1251_tx_complete(struct wl1251 *wl) { int i, result_index, num_complete = 0, queue_len; - struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr; + struct tx_result *result, *result_ptr; unsigned long flags;
if (unlikely(wl->state != WL1251_STATE_ON)) return;
+ result = kmalloc_array(FW_TX_CMPLT_BLOCK_SIZE, sizeof(*result), GFP_KERNEL); + if (!result) { + wl1251_error("can not allocate result buffer"); + return; + } + /* First we read the result */ - wl1251_mem_read(wl, wl->data_path->tx_complete_addr, - result, sizeof(result)); + wl1251_mem_read(wl, wl->data_path->tx_complete_addr, result, + FW_TX_CMPLT_BLOCK_SIZE * sizeof(*result));
result_index = wl->next_tx_complete;
- for (i = 0; i < ARRAY_SIZE(result); i++) { + for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++) { result_ptr = &result[result_index];
if (result_ptr->done_1 == 1 && @@ -538,6 +544,7 @@ void wl1251_tx_complete(struct wl1251 *wl)
}
+ kfree(result); wl->next_tx_complete = result_index; }
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 3ff5f7840979aa36d47a6a00694826c78d63bf3c ]
Occasionally, typically when a function doesn't end with 'ret', an alias on that function will have 0 size.
The difference between what GCC generates and our linkage magic, is that GCC doesn't appear to provide .size for the alias'ed symbol at all. And indeed, removing this directive cures the issue.
Additionally, GCC also doesn't emit .type for alias symbols either, so also omit that.
Fixes: e0891269a8c2 ("linkage: add SYM_FUNC_ALIAS{,_LOCAL,_WEAK}()") Suggested-by: Mark Rutland mark.rutland@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Mark Rutland mark.rutland@arm.com Acked-by: Josh Poimboeuf jpoimboe@redhat.com Link: https://lore.kernel.org/r/20220506121631.437480085@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/linkage.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/include/linux/linkage.h b/include/linux/linkage.h index acb1ad2356f1..1feab6136b5b 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -171,12 +171,9 @@
/* SYM_ALIAS -- use only if you have to */ #ifndef SYM_ALIAS -#define SYM_ALIAS(alias, name, sym_type, linkage) \ - linkage(alias) ASM_NL \ - .set alias, name ASM_NL \ - .type alias sym_type ASM_NL \ - .set .L__sym_size_##alias, .L__sym_size_##name ASM_NL \ - .size alias, .L__sym_size_##alias +#define SYM_ALIAS(alias, name, linkage) \ + linkage(alias) ASM_NL \ + .set alias, name ASM_NL #endif
/* === code annotations === */ @@ -261,7 +258,7 @@ */ #ifndef SYM_FUNC_ALIAS #define SYM_FUNC_ALIAS(alias, name) \ - SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_GLOBAL) + SYM_ALIAS(alias, name, SYM_L_GLOBAL) #endif
/* @@ -269,7 +266,7 @@ */ #ifndef SYM_FUNC_ALIAS_LOCAL #define SYM_FUNC_ALIAS_LOCAL(alias, name) \ - SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_LOCAL) + SYM_ALIAS(alias, name, SYM_L_LOCAL) #endif
/* @@ -277,7 +274,7 @@ */ #ifndef SYM_FUNC_ALIAS_WEAK #define SYM_FUNC_ALIAS_WEAK(alias, name) \ - SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_WEAK) + SYM_ALIAS(alias, name, SYM_L_WEAK) #endif
/* SYM_CODE_START -- use for non-C (special) functions */
From: Ilkka Koskinen ilkka@os.amperecomputing.com
[ Upstream commit 988d7a14408db4183202f16bb02b8149b9da3727 ]
When building with W=1, we get the following warning:
drivers/acpi/arm64/agdi.c:88:13: warning: no previous prototype for ‘acpi_agdi_init’ [-Wmissing-prototypes] void __init acpi_agdi_init(void)
Include AGDI driver's header file to pull in the prototype definition for acpi_agdi_init() to get rid of the compiler warning
Fixes: a2a591fb76e6 ("ACPI: AGDI: Add driver for Arm Generic Diagnostic Dump and Reset device") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Ilkka Koskinen ilkka@os.amperecomputing.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/arm64/agdi.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c index 4df337d545b7..cf31abd0ed1b 100644 --- a/drivers/acpi/arm64/agdi.c +++ b/drivers/acpi/arm64/agdi.c @@ -9,6 +9,7 @@ #define pr_fmt(fmt) "ACPI: AGDI: " fmt
#include <linux/acpi.h> +#include <linux/acpi_agdi.h> #include <linux/arm_sdei.h> #include <linux/io.h> #include <linux/kernel.h>
From: Vinod Polimera quic_vpolimer@quicinc.com
[ Upstream commit 01013ba9bbddc62f7d011163cebfd7ed06bb698b ]
If edp modeset init is failed due to panel being not ready and probe defers during drm bind, avoid clearing irqs and dereference hw_intr when hw_intr is null.
BUG: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Call trace: dpu_core_irq_uninstall+0x50/0xb0 dpu_irq_uninstall+0x18/0x24 msm_drm_uninit+0xd8/0x16c msm_drm_bind+0x580/0x5fc try_to_bring_up_master+0x168/0x1c0 __component_add+0xb4/0x178 component_add+0x1c/0x28 dp_display_probe+0x38c/0x400 platform_probe+0xb0/0xd0 really_probe+0xcc/0x2c8 __driver_probe_device+0xbc/0xe8 driver_probe_device+0x48/0xf0 __device_attach_driver+0xa0/0xc8 bus_for_each_drv+0x8c/0xd8 __device_attach+0xc4/0x150 device_initial_probe+0x1c/0x28
Changes in V2: - Update commit message and coreect fixes tag.
Fixes: f25f656608e3 ("drm/msm/dpu: merge struct dpu_irq into struct dpu_hw_intr") Signed-off-by: Vinod Polimera quic_vpolimer@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/484430/ Link: https://lore.kernel.org/r/1651509846-4842-1-git-send-email-quic_vpolimer@qui... 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_interrupts.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c index c61b5b283f08..cf9aa06ab8bd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c @@ -599,6 +599,9 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms) { int i;
+ if (!dpu_kms->hw_intr) + return; + pm_runtime_get_sync(&dpu_kms->pdev->dev); for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) if (!list_empty(&dpu_kms->hw_intr->irq_cb_tbl[i]))
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 9208c707650354dff5b164b586837454f7285124 ]
Correct a typo in the address of the second DSI PHY in the SDM660 device config.
Fixes: 694dd304cc29 ("drm/msm/dsi: Add phy configuration for SDM630/636/660") Cc: Konrad Dybcio konrad.dybcio@somainline.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Konrad Dybcio konrad.dybcio@somainline.org Patchwork: https://patchwork.freedesktop.org/patch/484697/ Link: https://lore.kernel.org/r/20220503204340.935532-1-dmitry.baryshkov@linaro.or... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 75557ac99adf..8199c53567f4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -1062,7 +1062,7 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs = { }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, - .io_start = { 0xc994400, 0xc996000 }, + .io_start = { 0xc994400, 0xc996400 }, .num_dsi_phy = 2, };
From: Kuogee Hsieh quic_khsieh@quicinc.com
[ Upstream commit 2f9b5b3ae2eb625b75a898212a76f3b8c6d0d2b0 ]
Event thread supposed to exit from its while loop after kthread_stop(). However there may has possibility that event thread is pending in the middle of wait_event due to condition checking never become true. To make sure event thread exit its loop after kthread_stop(), this patch OR kthread_should_stop() into wait_event's condition checking so that event thread will exit its loop after kernal_stop().
Changes in v2: -- correct spelling error at commit title
Changes in v3: -- remove unnecessary parenthesis -- while(1) to replace while (!kthread_should_stop())
Reported-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Fixes: 570d3e5d28db ("drm/msm/dp: stop event kernel thread when DP unbind") Signed-off-by: Kuogee Hsieh quic_khsieh@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/484576/ Link: https://lore.kernel.org/r/1651595136-24312-1-git-send-email-quic_khsieh@quic... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dp/dp_display.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index b3bfe9ac9d80..8deb92bddfde 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1107,15 +1107,20 @@ static int hpd_event_thread(void *data)
dp_priv = (struct dp_display_private *)data;
- while (!kthread_should_stop()) { + while (1) { if (timeout_mode) { wait_event_timeout(dp_priv->event_q, - (dp_priv->event_pndx == dp_priv->event_gndx), - EVENT_TIMEOUT); + (dp_priv->event_pndx == dp_priv->event_gndx) || + kthread_should_stop(), EVENT_TIMEOUT); } else { wait_event_interruptible(dp_priv->event_q, - (dp_priv->event_pndx != dp_priv->event_gndx)); + (dp_priv->event_pndx != dp_priv->event_gndx) || + kthread_should_stop()); } + + if (kthread_should_stop()) + break; + spin_lock_irqsave(&dp_priv->event_lock, flag); todo = &dp_priv->event_list[dp_priv->event_gndx]; if (todo->delay) {
From: Jessica Zhang quic_jesszhan@quicinc.com
[ Upstream commit d59be579fa932c46b908f37509f319cbd4ca9a68 ]
mdp5_get_global_state runs the risk of hitting a -EDEADLK when acquiring the modeset lock, but currently mdp5_pipe_release doesn't check for if an error is returned. Because of this, there is a possibility of mdp5_pipe_release hitting a NULL dereference error.
To avoid this, let's have mdp5_pipe_release check if mdp5_get_global_state returns an error and propogate that error.
Changes since v1: - Separated declaration and initialization of *new_state to avoid compiler warning - Fixed some spelling mistakes in commit message
Changes since v2: - Return 0 in case where hwpipe is NULL as this is considered normal behavior - Added 2nd patch in series to fix a similar NULL dereference issue in mdp5_mixer_release
Reported-by: Tomeu Vizoso tomeu.vizoso@collabora.com Signed-off-by: Jessica Zhang quic_jesszhan@quicinc.com Fixes: 7907a0d77cb4 ("drm/msm/mdp5: Use the new private_obj state") Reviewed-by: Rob Clark robdclark@gmail.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/485179/ Link: https://lore.kernel.org/r/20220505214051.155-1-quic_jesszhan@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 15 +++++++++++---- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h | 2 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 20 ++++++++++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c index ba6695963aa6..a4f5cb90f3e8 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c @@ -119,18 +119,23 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, return 0; }
-void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) +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_hw_pipe_state *new_state = &state->hwpipe; + struct mdp5_hw_pipe_state *new_state;
if (!hwpipe) - return; + return 0; + + if (IS_ERR(state)) + return PTR_ERR(state); + + new_state = &state->hwpipe;
if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx])) - return; + return -EINVAL;
DBG("%s: release from plane %s", hwpipe->name, new_state->hwpipe_to_plane[hwpipe->idx]->name); @@ -141,6 +146,8 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) }
new_state->hwpipe_to_plane[hwpipe->idx] = NULL; + + return 0; }
void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h index 9b26d0761bd4..cca67938cab2 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h @@ -37,7 +37,7 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, uint32_t caps, uint32_t blkcfg, struct mdp5_hw_pipe **hwpipe, struct mdp5_hw_pipe **r_hwpipe); -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);
struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, uint32_t reg_offset, uint32_t caps); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index c478d25f7825..f2d72497467b 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -314,12 +314,24 @@ static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, mdp5_state->r_hwpipe = NULL;
- mdp5_pipe_release(state->state, old_hwpipe); - mdp5_pipe_release(state->state, old_right_hwpipe); + ret = mdp5_pipe_release(state->state, old_hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, old_right_hwpipe); + if (ret) + return ret; + } } else { - mdp5_pipe_release(state->state, mdp5_state->hwpipe); - mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + if (ret) + return ret; + mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL; }
From: Jessica Zhang quic_jesszhan@quicinc.com
[ Upstream commit ca75f6f7c6f89365e40f10f641b15981b1f07c31 ]
There is a possibility for mdp5_get_global_state to return -EDEADLK when acquiring the modeset lock, but currently global_state in mdp5_mixer_release doesn't check for if an error is returned.
To avoid a NULL dereference error, let's have mdp5_mixer_release check if an error is returned and propagate that error.
Reported-by: Tomeu Vizoso tomeu.vizoso@collabora.com Signed-off-by: Jessica Zhang quic_jesszhan@quicinc.com Fixes: 7907a0d77cb4 ("drm/msm/mdp5: Use the new private_obj state") Reviewed-by: Rob Clark robdclark@gmail.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/485181/ Link: https://lore.kernel.org/r/20220505214051.155-2-quic_jesszhan@quicinc.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 10 ++++++++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 15 +++++++++++---- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index b966cd69f99d..fe2922c8d21b 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -612,9 +612,15 @@ static int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc, if (ret) return ret;
- mdp5_mixer_release(new_crtc_state->state, old_mixer); + ret = mdp5_mixer_release(new_crtc_state->state, old_mixer); + if (ret) + return ret; + if (old_r_mixer) { - mdp5_mixer_release(new_crtc_state->state, old_r_mixer); + ret = mdp5_mixer_release(new_crtc_state->state, old_r_mixer); + if (ret) + return ret; + if (!need_right_mixer) pipeline->r_mixer = NULL; } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c index 954db683ae44..2536def2a000 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c @@ -116,21 +116,28 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, return 0; }
-void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) +int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) { struct mdp5_global_state *global_state = mdp5_get_global_state(s); - struct mdp5_hw_mixer_state *new_state = &global_state->hwmixer; + struct mdp5_hw_mixer_state *new_state;
if (!mixer) - return; + return 0; + + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + new_state = &global_state->hwmixer;
if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx])) - return; + return -EINVAL;
DBG("%s: release from crtc %s", mixer->name, new_state->hwmixer_to_crtc[mixer->idx]->name);
new_state->hwmixer_to_crtc[mixer->idx] = NULL; + + return 0; }
void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h index 43c9ba43ce18..545ee223b9d7 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h @@ -30,7 +30,7 @@ void mdp5_mixer_destroy(struct mdp5_hw_mixer *lm); int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, uint32_t caps, struct mdp5_hw_mixer **mixer, struct mdp5_hw_mixer **r_mixer); -void mdp5_mixer_release(struct drm_atomic_state *s, - struct mdp5_hw_mixer *mixer); +int mdp5_mixer_release(struct drm_atomic_state *s, + struct mdp5_hw_mixer *mixer);
#endif /* __MDP5_LM_H__ */
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit cf575e31611eb6dccf08fad02e57e35b2187704d ]
The msm_gem_prime_get_sg_table() needs to return error pointers on error. This is called from drm_gem_map_dma_buf() and returning a NULL will lead to a crash in that function.
Fixes: ac45146733b0 ("drm/msm: fix msm_gem_prime_get_sg_table()") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Patchwork: https://patchwork.freedesktop.org/patch/485023/ Link: https://lore.kernel.org/r/YnOmtS5tfENywR9m@kili Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_gem_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c b/drivers/gpu/drm/msm/msm_gem_prime.c index e8f1b7a2ca9c..94ab705e9b8a 100644 --- a/drivers/gpu/drm/msm/msm_gem_prime.c +++ b/drivers/gpu/drm/msm/msm_gem_prime.c @@ -17,7 +17,7 @@ struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj) int npages = obj->size >> PAGE_SHIFT;
if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */ - return NULL; + return ERR_PTR(-ENOMEM);
return drm_prime_pages_to_sg(obj->dev, msm_obj->pages, npages); }
From: Xiaomeng Tong xiam0nd.tong@gmail.com
[ Upstream commit 261f33388c29f6f3c12a724e6d89172b7f6d5996 ]
The list iterator will point to a bogus position containing HEAD if the list is empty or the element is not found in list. This case should be checked before any use of the iterator, otherwise it will lead to a invalid memory access. The missing check here is before "pin = iterm->id;", just add check here to fix the security bug.
In addition, the list iterator value will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the element is not found in list, considering the (mis)use here: "if (iterm == NULL".
Use a new value 'it' as the list iterator, while use the old value 'iterm' as a dedicated pointer to point to the found element, which 1. can fix this bug, due to 'iterm' is NULL only if it's not found. 2. do not need to change all the uses of 'iterm' after the loop. 3. can also limit the scope of the list iterator 'it' *only inside* the traversal loop by simply declaring 'it' inside the loop in the future, as usage of the iterator outside of the list_for_each_entry is considered harmful. https://lkml.org/lkml/2022/2/17/1032
Fixes: d5e90b7a6cd1c ("[media] uvcvideo: Move to video_ioctl2") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_v4l2.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 711556d13d03..177181985345 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -871,29 +871,31 @@ static int uvc_ioctl_enum_input(struct file *file, void *fh, struct uvc_video_chain *chain = handle->chain; const struct uvc_entity *selector = chain->selector; struct uvc_entity *iterm = NULL; + struct uvc_entity *it; u32 index = input->index; - int pin = 0;
if (selector == NULL || (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { if (index != 0) return -EINVAL; - list_for_each_entry(iterm, &chain->entities, chain) { - if (UVC_ENTITY_IS_ITERM(iterm)) + list_for_each_entry(it, &chain->entities, chain) { + if (UVC_ENTITY_IS_ITERM(it)) { + iterm = it; break; + } } - pin = iterm->id; } else if (index < selector->bNrInPins) { - pin = selector->baSourceID[index]; - list_for_each_entry(iterm, &chain->entities, chain) { - if (!UVC_ENTITY_IS_ITERM(iterm)) + list_for_each_entry(it, &chain->entities, chain) { + if (!UVC_ENTITY_IS_ITERM(it)) continue; - if (iterm->id == pin) + if (it->id == selector->baSourceID[index]) { + iterm = it; break; + } } }
- if (iterm == NULL || iterm->id != pin) + if (iterm == NULL) return -EINVAL;
memset(input, 0, sizeof(*input));
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit e85094c31ddb794ac41c299a5a7a68243148f829 ]
Due to some historical confusion, arm64's current_top_of_stack() isn't what the stackleak code expects. This could in theory result in a number of problems, and practically results in an unnecessary performance hit. We can avoid this by aligning the arm64 implementation with the x86 implementation.
The arm64 implementation of current_top_of_stack() was added specifically for stackleak in commit:
0b3e336601b82c6a ("arm64: Add support for STACKLEAK gcc plugin")
This was intended to be equivalent to the x86 implementation, but the implementation, semantics, and performance characteristics differ wildly:
* On x86, current_top_of_stack() returns the top of the current task's task stack, regardless of which stack is in active use.
The implementation accesses a percpu variable which the x86 entry code maintains, and returns the location immediately above the pt_regs on the task stack (above which x86 has some padding).
* On arm64 current_top_of_stack() returns the top of the stack in active use (i.e. the one which is currently being used).
The implementation checks the SP against a number of potentially-accessible stacks, and will BUG() if no stack is found.
The core stackleak_erase() code determines the upper bound of stack to erase with:
| if (on_thread_stack()) | boundary = current_stack_pointer; | else | boundary = current_top_of_stack();
On arm64 stackleak_erase() is always called on a task stack, and on_thread_stack() should always be true. On x86, stackleak_erase() is mostly called on a trampoline stack, and is sometimes called on a task stack.
Currently, this results in a lot of unnecessary code being generated for arm64 for the impossible !on_thread_stack() case. Some of this is inlined, bloating stackleak_erase(), while portions of this are left out-of-line and permitted to be instrumented (which would be a functional problem if that code were reachable).
As a first step towards improving this, this patch aligns arm64's implementation of current_top_of_stack() with x86's, always returning the top of the current task's stack. With GCC 11.1.0 this results in the bulk of the unnecessary code being removed, including all of the out-of-line instrumentable code.
While I don't believe there's a functional problem in practice I've marked this as a fix since the semantic was clearly wrong, the fix itself is simple, and other code might rely upon this in future.
Fixes: 0b3e336601b82c6a ("arm64: Add support for STACKLEAK gcc plugin") Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Alexander Popov alex.popov@linux.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Andy Lutomirski luto@kernel.org Cc: Catalin Marinas catalin.marinas@arm.com Cc: Kees Cook keescook@chromium.org Cc: Will Deacon will@kernel.org Acked-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20220427173128.2603085-2-mark.rutland@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/processor.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 73e38d9a540c..6b1a12c23fe7 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -381,12 +381,10 @@ long get_tagged_addr_ctrl(struct task_struct *task); * of header definitions for the use of task_stack_page. */
-#define current_top_of_stack() \ -({ \ - struct stack_info _info; \ - BUG_ON(!on_accessible_stack(current, current_stack_pointer, 1, &_info)); \ - _info.high; \ -}) +/* + * The top of the current task's task stack + */ +#define current_top_of_stack() ((unsigned long)current->stack + THREAD_SIZE) #define on_thread_stack() (on_task_stack(current, current_stack_pointer, 1, NULL))
#endif /* __ASSEMBLY__ */
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit b71450e2cc4b3c79f33c5bd276d152af9bd54f79 ]
The @lend parameter of truncate_pagecache_range() should be the offset of the last byte of the hole, not the first byte beyond it.
Fixes: ae259a9c8593 ("fs: introduce iomap infrastructure") Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Reviewed-by: Darrick J. Wong djwong@kernel.org Signed-off-by: Darrick J. Wong djwong@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/iomap/buffered-io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 8ce8720093b9..358ee1fb6f0d 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -531,7 +531,8 @@ iomap_write_failed(struct inode *inode, loff_t pos, unsigned len) * write started inside the existing inode size. */ if (pos + len > i_size) - truncate_pagecache_range(inode, max(pos, i_size), pos + len); + truncate_pagecache_range(inode, max(pos, i_size), + pos + len - 1); }
static int iomap_read_folio_sync(loff_t block_start, struct folio *folio,
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit a2b331ac11e1cac56f5b7d367e9f3c5796deaaed ]
It will cause null-ptr-deref if platform_get_resource_byname() returns NULL, we need check the return value.
Fixes: 858e26a515c2 ("spi: spi-fsl-qspi: Reduce devm_ioremap size to 4 times AHB buffer size") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20220505093954.1285615-1-yangyingliang@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-fsl-qspi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c index 9851551ebbe0..46ae46a944c5 100644 --- a/drivers/spi/spi-fsl-qspi.c +++ b/drivers/spi/spi-fsl-qspi.c @@ -876,6 +876,10 @@ static int fsl_qspi_probe(struct platform_device *pdev)
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "QuadSPI-memory"); + if (!res) { + ret = -EINVAL; + goto err_put_ctrl; + } q->memmap_phy = res->start; /* Since there are 4 cs, map size required is 4 times ahb_buf_size */ q->ahb_addr = devm_ioremap(dev, q->memmap_phy,
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 1e2666e029e5cc2b81dbd7c85af5bcc8c80524e0 ]
Prevent "classic" and light skeleton generation rules from stomping on each other's toes due to the use of the same <obj>.linked{1,2,3}.o naming pattern. There is no coordination and synchronizataion between .skel.h and .lskel.h rules, so they can easily overwrite each other's intermediate object files, leading to errors like:
/bin/sh: line 1: 170928 Bus error (core dumped) /data/users/andriin/linux/tools/testing/selftests/bpf/tools/sbin/bpftool gen skeleton /data/users/andriin/linux/tools/testing/selftests/bpf/test_ksyms_weak.linked3.o name test_ksyms_weak
/data/users/andriin/linux/tools/testing/selftests/bpf/test_ksyms_weak.skel.h
make: *** [Makefile:507: /data/users/andriin/linux/tools/testing/selftests/bpf/test_ksyms_weak.skel.h] Error 135 make: *** Deleting file '/data/users/andriin/linux/tools/testing/selftests/bpf/test_ksyms_weak.skel.h'
Fix by using different suffix for light skeleton rule.
Fixes: c48e51c8b07a ("bpf: selftests: Add selftests for module kfunc support") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20220509004148.1801791-2-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 3820608faf57..a15c47d2fa73 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -415,11 +415,11 @@ $(TRUNNER_BPF_SKELS): %.skel.h: %.o $(BPFTOOL) | $(TRUNNER_OUTPUT)
$(TRUNNER_BPF_LSKELS): %.lskel.h: %.o $(BPFTOOL) | $(TRUNNER_OUTPUT) $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) - $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked1.o) $$< - $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked2.o) $$(<:.o=.linked1.o) - $(Q)$$(BPFTOOL) gen object $$(<:.o=.linked3.o) $$(<:.o=.linked2.o) - $(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o) - $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.linked3.o) name $$(notdir $$(<:.o=_lskel)) > $$@ + $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked1.o) $$< + $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked2.o) $$(<:.o=.llinked1.o) + $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o) + $(Q)diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) + $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.llinked3.o) name $$(notdir $$(<:.o=_lskel)) > $$@
$(TRUNNER_BPF_SKELS_LINKED): $(TRUNNER_BPF_OBJS) $(BPFTOOL) | $(TRUNNER_OUTPUT) $$(call msg,LINK-BPF,$(TRUNNER_BINARY),$$(@:.skel.h=.o))
From: Viresh Kumar viresh.kumar@linaro.org
[ Upstream commit 85f0e42bd65d01b351d561efb38e584d4c596553 ]
This reverts commit f346e96267cd76175d6c201b40f770c0116a8a04.
The commit tried to fix a possible real bug but it made it even worse. The fix was simply buggy as now an error out to out_offline_policy or out_exit_policy will try to release a semaphore which was never taken in the first place. This works fine only if we failed late, i.e. via out_destroy_policy.
Fixes: f346e96267cd ("cpufreq: Fix possible race in cpufreq online error path") Signed-off-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/cpufreq.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 233e8af48848..fbaa8e6c7d23 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1534,6 +1534,8 @@ static int cpufreq_online(unsigned int cpu) for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j));
+ up_write(&policy->rwsem); + out_offline_policy: if (cpufreq_driver->offline) cpufreq_driver->offline(policy); @@ -1542,9 +1544,6 @@ static int cpufreq_online(unsigned int cpu) if (cpufreq_driver->exit) cpufreq_driver->exit(policy);
- cpumask_clear(policy->cpus); - up_write(&policy->rwsem); - out_free_policy: cpufreq_policy_free(policy); return ret;
From: Konrad Dybcio konrad.dybcio@somainline.org
[ Upstream commit b11b3d21a94d66bc05d1142e0b210bfa316c62be ]
Following changes have been made:
- S5, L4, L18, L20 and L21 were removed (S5 is managed by SPMI, whereas the rest seems not to exist [or at least it's blocked by Sony Loire /MSM8956/ RPM firmware])
- Supply maps have were adjusted to reflect regulator changes.
Fixes: e44adca5fa25 ("regulator: qcom_smd: Add PM8950 regulators") Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Link: https://lore.kernel.org/r/20220430163753.609909-1-konrad.dybcio@somainline.o... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/qcom_smd-regulator.c | 35 +++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 8490aa8eecb1..7dff94a2eb7e 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -944,32 +944,31 @@ static const struct rpm_regulator_data rpm_pm8950_regulators[] = { { "s2", QCOM_SMD_RPM_SMPA, 2, &pm8950_hfsmps, "vdd_s2" }, { "s3", QCOM_SMD_RPM_SMPA, 3, &pm8950_hfsmps, "vdd_s3" }, { "s4", QCOM_SMD_RPM_SMPA, 4, &pm8950_hfsmps, "vdd_s4" }, - { "s5", QCOM_SMD_RPM_SMPA, 5, &pm8950_ftsmps2p5, "vdd_s5" }, + /* S5 is managed via SPMI. */ { "s6", QCOM_SMD_RPM_SMPA, 6, &pm8950_hfsmps, "vdd_s6" },
{ "l1", QCOM_SMD_RPM_LDOA, 1, &pm8950_ult_nldo, "vdd_l1_l19" }, { "l2", QCOM_SMD_RPM_LDOA, 2, &pm8950_ult_nldo, "vdd_l2_l23" }, { "l3", QCOM_SMD_RPM_LDOA, 3, &pm8950_ult_nldo, "vdd_l3" }, - { "l4", QCOM_SMD_RPM_LDOA, 4, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16" }, - { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_pldo_lv, "vdd_l4_l5_l6_l7_l16" }, - { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_pldo_lv, "vdd_l4_l5_l6_l7_l16" }, - { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_pldo_lv, "vdd_l4_l5_l6_l7_l16" }, + /* L4 seems not to exist. */ + { "l5", QCOM_SMD_RPM_LDOA, 5, &pm8950_pldo_lv, "vdd_l5_l6_l7_l16" }, + { "l6", QCOM_SMD_RPM_LDOA, 6, &pm8950_pldo_lv, "vdd_l5_l6_l7_l16" }, + { "l7", QCOM_SMD_RPM_LDOA, 7, &pm8950_pldo_lv, "vdd_l5_l6_l7_l16" }, { "l8", QCOM_SMD_RPM_LDOA, 8, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" }, { "l9", QCOM_SMD_RPM_LDOA, 9, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" }, { "l10", QCOM_SMD_RPM_LDOA, 10, &pm8950_ult_nldo, "vdd_l9_l10_l13_l14_l15_l18"}, - { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22"}, - { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22"}, - { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, - { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, - { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, - { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l4_l5_l6_l7_l16"}, - { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22"}, - { "l18", QCOM_SMD_RPM_LDOA, 18, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18"}, - { "l19", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l1_l19"}, - { "l20", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l20"}, - { "l21", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l21"}, - { "l22", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l8_l11_l12_l17_l22"}, - { "l23", QCOM_SMD_RPM_LDOA, 18, &pm8950_pldo, "vdd_l2_l23"}, + { "l11", QCOM_SMD_RPM_LDOA, 11, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" }, + { "l12", QCOM_SMD_RPM_LDOA, 12, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" }, + { "l13", QCOM_SMD_RPM_LDOA, 13, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" }, + { "l14", QCOM_SMD_RPM_LDOA, 14, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" }, + { "l15", QCOM_SMD_RPM_LDOA, 15, &pm8950_ult_pldo, "vdd_l9_l10_l13_l14_l15_l18" }, + { "l16", QCOM_SMD_RPM_LDOA, 16, &pm8950_ult_pldo, "vdd_l5_l6_l7_l16" }, + { "l17", QCOM_SMD_RPM_LDOA, 17, &pm8950_ult_pldo, "vdd_l8_l11_l12_l17_l22" }, + /* L18 seems not to exist. */ + { "l19", QCOM_SMD_RPM_LDOA, 19, &pm8950_pldo, "vdd_l1_l19" }, + /* L20 & L21 seem not to exist. */ + { "l22", QCOM_SMD_RPM_LDOA, 22, &pm8950_pldo, "vdd_l8_l11_l12_l17_l22" }, + { "l23", QCOM_SMD_RPM_LDOA, 23, &pm8950_pldo, "vdd_l2_l23" }, {} };
From: Jerome Marchand jmarchan@redhat.com
[ Upstream commit ec24704492d8791a52a75a39e3ad762b6e017bc6 ]
samples/bpf build currently always fails if it can't generate vmlinux.h from vmlinux, even when vmlinux.h is directly provided by VMLINUX_H variable, which makes VMLINUX_H pointless. Only fails when neither method works.
Fixes: 384b6b3bbf0d ("samples: bpf: Add vmlinux.h generation support") Reported-by: CKI Project cki-project@redhat.com Reported-by: Veronika Kabatova vkabatov@redhat.com Signed-off-by: Jerome Marchand jmarchan@redhat.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20220507161635.2219052-1-jmarchan@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/Makefile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 38638845db9d..72bb85c18804 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -368,16 +368,15 @@ VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
$(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) ifeq ($(VMLINUX_H),) +ifeq ($(VMLINUX_BTF),) + $(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\ + build the kernel or set VMLINUX_BTF or VMLINUX_H variable) +endif $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ else $(Q)cp "$(VMLINUX_H)" $@ endif
-ifeq ($(VMLINUX_BTF),) - $(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\ - build the kernel or set VMLINUX_BTF variable) -endif - clean-files += vmlinux.h
# Get Clang's default includes on this system, as opposed to those seen by
From: Ravi Bangoria ravi.bangoria@amd.com
[ Upstream commit 3d47083b9ff46863e8374ad3bb5edb5e464c75f8 ]
IbsOpRip is recorded when IBS interrupt is triggered. But there is a skid from the time IBS interrupt gets triggered to the time the interrupt is presented to the core. Meanwhile processor would have moved ahead and thus IbsOpRip will be inconsistent with rsp and rbp recorded as part of the interrupt regs. This causes issues while unwinding stack using the ORC unwinder as it needs consistent rip, rsp and rbp. Fix this by using rip from interrupt regs instead of IbsOpRip for stack unwinding.
Fixes: ee9f8fce99640 ("x86/unwind: Add the ORC unwinder") Reported-by: Dmitry Monakhov dmtrmonakhov@yandex-team.ru Suggested-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Ravi Bangoria ravi.bangoria@amd.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20220429051441.14251-1-ravi.bangoria@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/amd/ibs.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 367ca899e6e8..2704ec1e42a3 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -304,6 +304,16 @@ static int perf_ibs_init(struct perf_event *event) hwc->config_base = perf_ibs->msr; hwc->config = config;
+ /* + * rip recorded by IbsOpRip will not be consistent with rsp and rbp + * recorded as part of interrupt regs. Thus we need to use rip from + * interrupt regs while unwinding call stack. Setting _EARLY flag + * makes sure we unwind call-stack before perf sample rip is set to + * IbsOpRip. + */ + if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) + event->attr.sample_type |= __PERF_SAMPLE_CALLCHAIN_EARLY; + return 0; }
@@ -687,6 +697,14 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) data.raw = &raw; }
+ /* + * rip recorded by IbsOpRip will not be consistent with rsp and rbp + * recorded as part of interrupt regs. Thus we need to use rip from + * interrupt regs while unwinding call stack. + */ + if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) + data.callchain = perf_callchain(event, iregs); + throttle = perf_event_overflow(event, &data, ®s); out: if (throttle) {
From: Baochen Qiang quic_bqiang@quicinc.com
[ Upstream commit 355333a217541916576351446b5832fec7930566 ]
Commit 66307ca04057 ("ath11k: fix mgmt_tx_wmi cmd sent to FW for deleted vdev") wants both of below two conditions are true before sending management frames:
1: ar->allocated_vdev_map & (1LL << arvif->vdev_id) 2: arvif->is_started
Actually the second one is not necessary because with the first one we can make sure the vdev is present.
Also use ar->conf_mutex to synchronize vdev delete and mgmt. TX.
This issue is found in case of Passpoint scenario where ath11k needs to send action frames before vdev is started.
Fix it by removing the second condition.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Fixes: 66307ca04057 ("ath11k: fix mgmt_tx_wmi cmd sent to FW for deleted vdev") Signed-off-by: Baochen Qiang quic_bqiang@quicinc.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220506013614.1580274-3-quic_bqiang@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/mac.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 2c8d5f2a0517..54d738bdee0e 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -5520,8 +5520,8 @@ static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work) }
arvif = ath11k_vif_to_arvif(skb_cb->vif); - if (ar->allocated_vdev_map & (1LL << arvif->vdev_id) && - arvif->is_started) { + mutex_lock(&ar->conf_mutex); + if (ar->allocated_vdev_map & (1LL << arvif->vdev_id)) { ret = ath11k_mac_mgmt_tx_wmi(ar, arvif, skb); if (ret) { ath11k_warn(ar->ab, "failed to tx mgmt frame, vdev_id %d :%d\n", @@ -5539,6 +5539,7 @@ static void ath11k_mgmt_over_wmi_tx_work(struct work_struct *work) arvif->is_started); ath11k_mgmt_over_wmi_tx_drop(ar, skb); } + mutex_unlock(&ar->conf_mutex); } }
From: James Smart jsmart2021@gmail.com
[ Upstream commit 84c6f99e39074d45f75986e42ca28e27c140fd0d ]
The prior commit that moved from iocb elements to explicit wqe elements missed a name change.
Correct __lpfc_sli_release_iocbq_s4() to reference wqe rather than iocb.
Link: https://lore.kernel.org/r/20220506035519.50908-2-jsmart2021@gmail.com Fixes: a680a9298e7b ("scsi: lpfc: SLI path split: Refactor lpfc_iocbq") 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_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 11f907278f09..c307f551d114 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1373,7 +1373,7 @@ static void __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) { struct lpfc_sglq *sglq; - size_t start_clean = offsetof(struct lpfc_iocbq, iocb); + size_t start_clean = offsetof(struct lpfc_iocbq, wqe); unsigned long iflag = 0; struct lpfc_sli_ring *pring;
From: James Smart jsmart2021@gmail.com
[ Upstream commit 596fc8adb171dce3751a359018e2ade612af8d97 ]
Upon driver receipt of a CT cmd for type = 0xFA (Management Server) and subtype = 0x11 (Fabric Device Management Interface), the driver is responding with garbage CT cmd data when it should send a properly formed RJT.
The __lpfc_prep_xmit_seq64_s4() routine was using the wrong buffer for the reject.
Fix by converting the routine to use the buffer specified in the bde within the wqe rather than the ill-set bmp element.
Link: https://lore.kernel.org/r/20220506035519.50908-6-jsmart2021@gmail.com Fixes: 61910d6a5243 ("scsi: lpfc: SLI path split: Refactor CT paths") 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_sli.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index c307f551d114..331241a71452 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -10800,24 +10800,15 @@ __lpfc_sli_prep_xmit_seq64_s4(struct lpfc_iocbq *cmdiocbq, { union lpfc_wqe128 *wqe; struct ulp_bde64 *bpl; - struct ulp_bde64_le *bde;
wqe = &cmdiocbq->wqe; memset(wqe, 0, sizeof(*wqe));
/* Words 0 - 2 */ bpl = (struct ulp_bde64 *)bmp->virt; - if (cmdiocbq->cmd_flag & (LPFC_IO_LIBDFC | LPFC_IO_LOOPBACK)) { - wqe->xmit_sequence.bde.addrHigh = bpl->addrHigh; - wqe->xmit_sequence.bde.addrLow = bpl->addrLow; - wqe->xmit_sequence.bde.tus.w = bpl->tus.w; - } else { - bde = (struct ulp_bde64_le *)&wqe->xmit_sequence.bde; - bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys)); - bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys)); - bde->type_size = cpu_to_le32(bpl->tus.f.bdeSize); - bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BDE_64); - } + wqe->xmit_sequence.bde.addrHigh = bpl->addrHigh; + wqe->xmit_sequence.bde.addrLow = bpl->addrLow; + wqe->xmit_sequence.bde.tus.w = bpl->tus.w;
/* Word 5 */ bf_set(wqe_ls, &wqe->xmit_sequence.wge_ctl, last_seq);
From: Ajay Singh ajay.kathat@microchip.com
[ Upstream commit 868f0e28290c7a33e8cb79bfe97ebdcbb756e048 ]
Monitor(mon.) interface is used for handling the AP mode and 'ieee80211_ptr' reference is not getting set for it. Like earlier implementation, use register_netdevice() instead of cfg80211_register_netdevice() which expects valid 'ieee80211_ptr' reference to avoid the possible crash.
Fixes: 2fe8ef106238 ("cfg80211: change netdev registration/unregistration semantics") Signed-off-by: Ajay Singh ajay.kathat@microchip.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220504161924.2146601-3-ajay.kathat@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/microchip/wilc1000/mon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c index 6bd63934c2d8..b5a1b65c087c 100644 --- a/drivers/net/wireless/microchip/wilc1000/mon.c +++ b/drivers/net/wireless/microchip/wilc1000/mon.c @@ -233,7 +233,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops; wl->monitor_dev->needs_free_netdev = true;
- if (cfg80211_register_netdevice(wl->monitor_dev)) { + if (register_netdevice(wl->monitor_dev)) { netdev_err(real_dev, "register_netdevice failed\n"); free_netdev(wl->monitor_dev); return NULL; @@ -251,7 +251,7 @@ void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked) return;
if (rtnl_locked) - cfg80211_unregister_netdevice(wl->monitor_dev); + unregister_netdevice(wl->monitor_dev); else unregister_netdev(wl->monitor_dev); wl->monitor_dev = NULL;
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit 206c3c2d85de8847fb732a5fb71443bacd287216 ]
Modifying the amd-sfh bus name to meaningful name.
Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)") Signed-off-by: Mario Limonciello mario.limonciello@amd.com 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 | 2 +- drivers/hid/amd-sfh-hid/amd_sfh_hid.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c index 2bf97b6ac973..6e487e41f4dd 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c @@ -141,7 +141,7 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data)
hid->driver_data = hid_data; cli_data->hid_sensor_hubs[cur_hid_dev] = hid; - hid->bus = BUS_AMD_AMDTP; + hid->bus = BUS_AMD_SFH; hid->vendor = AMD_SFH_HID_VENDOR; hid->product = AMD_SFH_HID_PRODUCT; snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp", diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h index c60abd38054c..cb04f47c8648 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.h @@ -12,7 +12,7 @@ #define AMDSFH_HID_H
#define MAX_HID_DEVICES 5 -#define BUS_AMD_AMDTP 0x20 +#define BUS_AMD_SFH 0x20 #define AMD_SFH_HID_VENDOR 0x1022 #define AMD_SFH_HID_PRODUCT 0x0001
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit 10f865cdcf37d26ae5e9595a7b4f9e06538e84e5 ]
Modifying the amd-sfh hid name to meaningful name.
Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)") Signed-off-by: Mario Limonciello mario.limonciello@amd.com 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c index 6e487e41f4dd..e2a9679e32be 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c @@ -144,7 +144,7 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data) hid->bus = BUS_AMD_SFH; hid->vendor = AMD_SFH_HID_VENDOR; hid->product = AMD_SFH_HID_PRODUCT; - snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdtp", + snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "hid-amdsfh", hid->vendor, hid->product);
rc = hid_add_device(hid);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 41cd312dfe980af869c3503b4d38e62ed20dd3b7 ]
of_find_i2c_device_by_node() takes a reference, In error paths, we should call put_device() to drop the reference to aviod refount leak.
Fixes: 81e8e4926167 ("ASoC: fsl: add sgtl5000 clock support for imx-sgtl5000") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Fabio Estevam festevam@gmail.com Link: https://lore.kernel.org/r/20220511065803.3957-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-sgtl5000.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c index 8daced42d55e..580a0d963f0e 100644 --- a/sound/soc/fsl/imx-sgtl5000.c +++ b/sound/soc/fsl/imx-sgtl5000.c @@ -120,19 +120,19 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; - goto fail; + goto put_device; }
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL); if (!comp) { ret = -ENOMEM; - goto fail; + goto put_device; }
data->codec_clk = clk_get(&codec_dev->dev, NULL); if (IS_ERR(data->codec_clk)) { ret = PTR_ERR(data->codec_clk); - goto fail; + goto put_device; }
data->clk_frequency = clk_get_rate(data->codec_clk); @@ -158,10 +158,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) data->card.dev = &pdev->dev; ret = snd_soc_of_parse_card_name(&data->card, "model"); if (ret) - goto fail; + goto put_device; ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); if (ret) - goto fail; + goto put_device; data->card.num_links = 1; data->card.owner = THIS_MODULE; data->card.dai_link = &data->dai; @@ -174,7 +174,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, &data->card); if (ret) { dev_err_probe(&pdev->dev, ret, "snd_soc_register_card failed\n"); - goto fail; + goto put_device; }
of_node_put(ssi_np); @@ -182,6 +182,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
return 0;
+put_device: + put_device(&codec_dev->dev); fail: if (data && !IS_ERR(data->codec_clk)) clk_put(data->codec_clk);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit ed46731d8e86c8d65f5fc717671e1f1f6c3146d2 ]
of_find_device_by_node() takes reference, we should use put_device() to release it. when devm_kzalloc() fails, it doesn't have a put_device(), it will cause refcount leak. Add missing put_device() to fix this.
Fixes: 6a5f850aa83a ("ASoC: fsl: Add imx-hdmi machine driver") Fixes: f670b274f7f6 ("ASoC: imx-hdmi: add put_device() after of_find_device_by_node()") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220511052740.46903-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/imx-hdmi.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c index 929f69b758af..ec149dc73938 100644 --- a/sound/soc/fsl/imx-hdmi.c +++ b/sound/soc/fsl/imx-hdmi.c @@ -126,6 +126,7 @@ static int imx_hdmi_probe(struct platform_device *pdev) data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) { ret = -ENOMEM; + put_device(&cpu_pdev->dev); goto fail; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 2be84f73785fa9ed6443e3c5b158730266f1c2ee ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when done.
Fixes: 08641c7c74dd ("ASoC: mxs: add device tree support for mxs-saif") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220511133725.39039-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/mxs/mxs-saif.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 879c1221a809..7afe1a1acc56 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -754,6 +754,7 @@ static int mxs_saif_probe(struct platform_device *pdev) saif->master_id = saif->id; } else { ret = of_alias_get_id(master, "saif"); + of_node_put(master); if (ret < 0) return ret; else
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit afaa7b933ef00a2d3262f4d1252087613fb5c06d ]
of_node_get() returns a node with refcount incremented. Calling of_node_put() to drop the reference when not needed anymore.
Fixes: 3784b6d64dc5 ("regulator: pfuze100: add pfuze100 regulator driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220511113506.45185-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/pfuze100-regulator.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index d60d7d1b7fa2..aa55cfca9e40 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -521,6 +521,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) parent = of_get_child_by_name(np, "regulators"); if (!parent) { dev_err(dev, "regulators node not found\n"); + of_node_put(np); return -EINVAL; }
@@ -550,6 +551,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) }
of_node_put(parent); + of_node_put(np); if (ret < 0) { dev_err(dev, "Error parsing regulator init data: %d\n", ret);
From: Pierre Gondois Pierre.Gondois@arm.com
[ Upstream commit c9d8923bfbcb63f15ea6cb2b5c8426fc3d96f643 ]
In commit e458716a92b57 ("PM: EM: Mark inefficiencies in CPUFreq"), cpufreq_cpu_get() is called without a cpufreq_cpu_put(), permanently increasing the reference counts of the policy struct.
Decrement the reference count once the policy struct is not used anymore.
Fixes: e458716a92b57 ("PM: EM: Mark inefficiencies in CPUFreq") Tested-by: Cristian Marussi cristian.marussi@arm.com Signed-off-by: Pierre Gondois pierre.gondois@arm.com Reviewed-by: Vincent Donnefort vincent.donnefort@arm.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/power/energy_model.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 0153b0ca7b23..6219aaa454b5 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -259,6 +259,8 @@ static void em_cpufreq_update_efficiencies(struct device *dev) found++; }
+ cpufreq_cpu_put(policy); + if (!found) return;
From: Christoph Hellwig hch@lst.de
[ Upstream commit 92826e967535db2eb117db227b1191aaf98e4bb3 ]
When dma_direct_alloc_pages encounters a highmem page it just gives up currently. But what we really should do is to try memory using the page allocator instead - without this platforms with a global highmem CMA pool will fail all dma_alloc_pages allocations.
Fixes: efa70f2fdc84 ("dma-mapping: add a new dma_alloc_pages API") Reported-by: Mark O'Neill mao@tumblingdice.co.uk Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/direct.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-)
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 9743c6ccce1a..3e7f4aab740e 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -115,7 +115,7 @@ static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size) }
static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, - gfp_t gfp) + gfp_t gfp, bool allow_highmem) { int node = dev_to_node(dev); struct page *page = NULL; @@ -129,9 +129,12 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size, gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask, &phys_limit); page = dma_alloc_contiguous(dev, size, gfp); - if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) { - dma_free_contiguous(dev, page, size); - page = NULL; + if (page) { + if (!dma_coherent_ok(dev, page_to_phys(page), size) || + (!allow_highmem && PageHighMem(page))) { + dma_free_contiguous(dev, page, size); + page = NULL; + } } again: if (!page) @@ -189,7 +192,7 @@ static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size, { struct page *page;
- page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO); + page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, true); if (!page) return NULL;
@@ -262,7 +265,7 @@ void *dma_direct_alloc(struct device *dev, size_t size, return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
/* we always manually zero the memory once we are done */ - page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO); + page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, true); if (!page) return NULL;
@@ -370,19 +373,9 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size, if (force_dma_unencrypted(dev) && dma_direct_use_pool(dev, gfp)) return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
- page = __dma_direct_alloc_pages(dev, size, gfp); + page = __dma_direct_alloc_pages(dev, size, gfp, false); if (!page) return NULL; - if (PageHighMem(page)) { - /* - * Depending on the cma= arguments and per-arch setup - * dma_alloc_contiguous could return highmem pages. - * Without remapping there is no way to return them here, - * so log an error and fail. - */ - dev_info(dev, "Rejecting highmem page from CMA.\n"); - goto out_free_pages; - }
ret = page_address(page); if (dma_set_decrypted(dev, ret, size))
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit bf4a9b2467b775717d0e9034ad916888e19713a3 ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. If extcon_find_edev_by_node() fails, it doesn't call of_node_put() Calling of_node_put() after extcon_find_edev_by_node() to fix this.
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/20220512043828.496-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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/samsung/aries_wm8994.c b/sound/soc/samsung/aries_wm8994.c index 5265e546b124..83acbe57b248 100644 --- a/sound/soc/samsung/aries_wm8994.c +++ b/sound/soc/samsung/aries_wm8994.c @@ -585,10 +585,10 @@ static int aries_audio_probe(struct platform_device *pdev)
extcon_np = of_parse_phandle(np, "extcon", 0); priv->usb_extcon = extcon_find_edev_by_node(extcon_np); + of_node_put(extcon_np); if (IS_ERR(priv->usb_extcon)) return dev_err_probe(dev, PTR_ERR(priv->usb_extcon), "Failed to get extcon device"); - of_node_put(extcon_np);
priv->adc = devm_iio_channel_get(dev, "headset-detect"); if (IS_ERR(priv->adc))
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 5d2ae14276e698c76fa0c8ce870103f343b38263 ]
Commit ef295ecf090d modified the Linux kernel such that the bottom bits of the bi_opf member contain the operation instead of the topmost bits. That commit did not update the comment next to bi_opf. Hence this patch.
From commit ef295ecf090d:
-#define bio_op(bio) ((bio)->bi_opf >> BIO_OP_SHIFT) +#define bio_op(bio) ((bio)->bi_opf & REQ_OP_MASK)
Cc: Christoph Hellwig hch@lst.de Cc: Ming Lei ming.lei@redhat.com Fixes: ef295ecf090d ("block: better op and flags encoding") Signed-off-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220511235152.1082246-1-bvanassche@acm.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/blk_types.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 1973ef9bd40f..4fa359c2c01f 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -246,9 +246,8 @@ typedef unsigned int blk_qc_t; struct bio { struct bio *bi_next; /* request queue link */ struct block_device *bi_bdev; - unsigned int bi_opf; /* bottom bits req flags, - * top bits REQ_OP. Use - * accessors. + unsigned int bi_opf; /* bottom bits REQ_OP, top bits + * req_flags. */ unsigned short bi_flags; /* BIO_* below */ unsigned short bi_ioprio;
From: Phil Auld pauld@redhat.com
[ Upstream commit 54de76c0123915e7533ce352de30a1f2d80fe81f ]
Running cgroup kselftest with O= fails to run the with_stress test due to hardcoded ./test_core. Find test_core binary using the OUTPUT directory.
Fixes: 1a99fcc035fb ("selftests: cgroup: Run test_core under interfering stress") Signed-off-by: Phil Auld pauld@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/cgroup/test_stress.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_stress.sh b/tools/testing/selftests/cgroup/test_stress.sh index 15d9d5896394..109c044f715f 100755 --- a/tools/testing/selftests/cgroup/test_stress.sh +++ b/tools/testing/selftests/cgroup/test_stress.sh @@ -1,4 +1,4 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0
-./with_stress.sh -s subsys -s fork ./test_core +./with_stress.sh -s subsys -s fork ${OUTPUT}/test_core
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 1d1a0e7c5100d332583e20b40aa8c0a8ed3d7849 ]
There have been some recent reports of faddr2line failures:
$ scripts/faddr2line sound/soundcore.ko sound_devnode+0x5/0x35 bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000
$ ./scripts/faddr2line vmlinux.o enter_from_user_mode+0x24 bad symbol size: base: 0x0000000000005fe0 end: 0x0000000000005fe0
The problem is that faddr2line is based on 'nm', which has a major limitation: it doesn't know how to distinguish between different text sections. So if an offset exists in multiple text sections in the object, it may fail.
Rewrite faddr2line to be section-aware, by basing it on readelf.
Fixes: 67326666e2d4 ("scripts: add script for translating stack dump function offsets") Reported-by: Kaiwan N Billimoria kaiwan.billimoria@gmail.com Reported-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Link: https://lore.kernel.org/r/29ff99f86e3da965b6e46c1cc2d72ce6528c17c3.165238232... Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/faddr2line | 150 +++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 53 deletions(-)
diff --git a/scripts/faddr2line b/scripts/faddr2line index 6c6439f69a72..0e6268d59883 100755 --- a/scripts/faddr2line +++ b/scripts/faddr2line @@ -44,17 +44,6 @@ set -o errexit set -o nounset
-READELF="${CROSS_COMPILE:-}readelf" -ADDR2LINE="${CROSS_COMPILE:-}addr2line" -SIZE="${CROSS_COMPILE:-}size" -NM="${CROSS_COMPILE:-}nm" - -command -v awk >/dev/null 2>&1 || die "awk isn't installed" -command -v ${READELF} >/dev/null 2>&1 || die "readelf isn't installed" -command -v ${ADDR2LINE} >/dev/null 2>&1 || die "addr2line isn't installed" -command -v ${SIZE} >/dev/null 2>&1 || die "size isn't installed" -command -v ${NM} >/dev/null 2>&1 || die "nm isn't installed" - usage() { echo "usage: faddr2line [--list] <object file> <func+offset> <func+offset>..." >&2 exit 1 @@ -69,6 +58,14 @@ die() { exit 1 }
+READELF="${CROSS_COMPILE:-}readelf" +ADDR2LINE="${CROSS_COMPILE:-}addr2line" +AWK="awk" + +command -v ${AWK} >/dev/null 2>&1 || die "${AWK} isn't installed" +command -v ${READELF} >/dev/null 2>&1 || die "${READELF} isn't installed" +command -v ${ADDR2LINE} >/dev/null 2>&1 || die "${ADDR2LINE} isn't installed" + # Try to figure out the source directory prefix so we can remove it from the # addr2line output. HACK ALERT: This assumes that start_kernel() is in # init/main.c! This only works for vmlinux. Otherwise it falls back to @@ -76,7 +73,7 @@ die() { find_dir_prefix() { local objfile=$1
- local start_kernel_addr=$(${READELF} -sW $objfile | awk '$8 == "start_kernel" {printf "0x%s", $2}') + local start_kernel_addr=$(${READELF} --symbols --wide $objfile | ${AWK} '$8 == "start_kernel" {printf "0x%s", $2}') [[ -z $start_kernel_addr ]] && return
local file_line=$(${ADDR2LINE} -e $objfile $start_kernel_addr) @@ -97,86 +94,133 @@ __faddr2line() { local dir_prefix=$3 local print_warnings=$4
- local func=${func_addr%+*} + local sym_name=${func_addr%+*} local offset=${func_addr#*+} offset=${offset%/*} - local size= - [[ $func_addr =~ "/" ]] && size=${func_addr#*/} + local user_size= + [[ $func_addr =~ "/" ]] && user_size=${func_addr#*/}
- if [[ -z $func ]] || [[ -z $offset ]] || [[ $func = $func_addr ]]; then + if [[ -z $sym_name ]] || [[ -z $offset ]] || [[ $sym_name = $func_addr ]]; then warn "bad func+offset $func_addr" DONE=1 return fi
# Go through each of the object's symbols which match the func name. - # In rare cases there might be duplicates. - file_end=$(${SIZE} -Ax $objfile | awk '$1 == ".text" {print $2}') - while read symbol; do - local fields=($symbol) - local sym_base=0x${fields[0]} - local sym_type=${fields[1]} - local sym_end=${fields[3]} - - # calculate the size - local sym_size=$(($sym_end - $sym_base)) + # In rare cases there might be duplicates, in which case we print all + # matches. + while read line; do + local fields=($line) + local sym_addr=0x${fields[1]} + local sym_elf_size=${fields[2]} + local sym_sec=${fields[6]} + + # Get the section size: + local sec_size=$(${READELF} --section-headers --wide $objfile | + sed 's/[ /[/' | + ${AWK} -v sec=$sym_sec '$1 == "[" sec "]" { print "0x" $6; exit }') + + if [[ -z $sec_size ]]; then + warn "bad section size: section: $sym_sec" + DONE=1 + return + fi + + # Calculate the symbol size. + # + # Unfortunately we can't use the ELF size, because kallsyms + # also includes the padding bytes in its size calculation. For + # kallsyms, the size calculation is the distance between the + # symbol and the next symbol in a sorted list. + local sym_size + local cur_sym_addr + local found=0 + while read line; do + local fields=($line) + cur_sym_addr=0x${fields[1]} + local cur_sym_elf_size=${fields[2]} + local cur_sym_name=${fields[7]:-} + + if [[ $cur_sym_addr = $sym_addr ]] && + [[ $cur_sym_elf_size = $sym_elf_size ]] && + [[ $cur_sym_name = $sym_name ]]; then + found=1 + continue + fi + + if [[ $found = 1 ]]; then + sym_size=$(($cur_sym_addr - $sym_addr)) + [[ $sym_size -lt $sym_elf_size ]] && continue; + found=2 + break + fi + done < <(${READELF} --symbols --wide $objfile | ${AWK} -v sec=$sym_sec '$7 == sec' | sort --key=2) + + if [[ $found = 0 ]]; then + warn "can't find symbol: sym_name: $sym_name sym_sec: $sym_sec sym_addr: $sym_addr sym_elf_size: $sym_elf_size" + DONE=1 + return + fi + + # If nothing was found after the symbol, assume it's the last + # symbol in the section. + [[ $found = 1 ]] && sym_size=$(($sec_size - $sym_addr)) + if [[ -z $sym_size ]] || [[ $sym_size -le 0 ]]; then - warn "bad symbol size: base: $sym_base end: $sym_end" + warn "bad symbol size: sym_addr: $sym_addr cur_sym_addr: $cur_sym_addr" DONE=1 return fi + sym_size=0x$(printf %x $sym_size)
- # calculate the address - local addr=$(($sym_base + $offset)) + # Calculate the section address from user-supplied offset: + local addr=$(($sym_addr + $offset)) if [[ -z $addr ]] || [[ $addr = 0 ]]; then - warn "bad address: $sym_base + $offset" + warn "bad address: $sym_addr + $offset" DONE=1 return fi addr=0x$(printf %x $addr)
- # weed out non-function symbols - if [[ $sym_type != t ]] && [[ $sym_type != T ]]; then - [[ $print_warnings = 1 ]] && - echo "skipping $func address at $addr due to non-function symbol of type '$sym_type'" - continue - fi - - # if the user provided a size, make sure it matches the symbol's size - if [[ -n $size ]] && [[ $size -ne $sym_size ]]; then + # If the user provided a size, make sure it matches the symbol's size: + if [[ -n $user_size ]] && [[ $user_size -ne $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $addr due to size mismatch ($size != $sym_size)" + echo "skipping $sym_name address at $addr due to size mismatch ($user_size != $sym_size)" continue; fi
- # make sure the provided offset is within the symbol's range + # Make sure the provided offset is within the symbol's range: if [[ $offset -gt $sym_size ]]; then [[ $print_warnings = 1 ]] && - echo "skipping $func address at $addr due to size mismatch ($offset > $sym_size)" + echo "skipping $sym_name address at $addr due to size mismatch ($offset > $sym_size)" continue fi
- # separate multiple entries with a blank line + # In case of duplicates or multiple addresses specified on the + # cmdline, separate multiple entries with a blank line: [[ $FIRST = 0 ]] && echo FIRST=0
- # pass real address to addr2line - echo "$func+$offset/$sym_size:" - local file_lines=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix(./)*; ;") - [[ -z $file_lines ]] && return + echo "$sym_name+$offset/$sym_size:"
+ # Pass section address to addr2line and strip absolute paths + # from the output: + local output=$(${ADDR2LINE} -fpie $objfile $addr | sed "s; $dir_prefix(./)*; ;") + [[ -z $output ]] && continue + + # Default output (non --list): if [[ $LIST = 0 ]]; then - echo "$file_lines" | while read -r line + echo "$output" | while read -r line do echo $line done DONE=1; - return + continue fi
- # show each line with context - echo "$file_lines" | while read -r line + # For --list, show each line with its corresponding source code: + echo "$output" | while read -r line do echo echo $line @@ -184,12 +228,12 @@ __faddr2line() { n1=$[$n-5] n2=$[$n+5] f=$(echo $line | sed 's/.*at (.+):.*/\1/g') - awk 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f + ${AWK} 'NR>=strtonum("'$n1'") && NR<=strtonum("'$n2'") { if (NR=='$n') printf(">%d<", NR); else printf(" %d ", NR); printf("\t%s\n", $0)}' $f done
DONE=1
- done < <(${NM} -n $objfile | awk -v fn=$func -v end=$file_end '$3 == fn { found=1; line=$0; start=$1; next } found == 1 { found=0; print line, "0x"$1 } END {if (found == 1) print line, end; }') + done < <(${READELF} --symbols --wide $objfile | ${AWK} -v fn=$sym_name '$4 == "FUNC" && $8 == fn') }
[[ $# -lt 2 ]] && usage
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 310fda622bbd38be17fb444f7f049b137af3bc0d ]
A dma_free_coherent() call is missing in the error handling path of the probe, as already done in the remove function.
In fact, this call is included in aspeed_video_free_buf(). So use the latter both in the error handling path of the probe and in the remove function. It is easier to see the relation with aspeed_video_alloc_buf() this way.
Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr 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/aspeed/aspeed-video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/aspeed/aspeed-video.c b/drivers/media/platform/aspeed/aspeed-video.c index b937dbcbe9e0..20f795ccc11b 100644 --- a/drivers/media/platform/aspeed/aspeed-video.c +++ b/drivers/media/platform/aspeed/aspeed-video.c @@ -1993,6 +1993,7 @@ static int aspeed_video_probe(struct platform_device *pdev)
rc = aspeed_video_setup_video(video); if (rc) { + aspeed_video_free_buf(video, &video->jpeg); clk_unprepare(video->vclk); clk_unprepare(video->eclk); return rc; @@ -2024,8 +2025,7 @@ static int aspeed_video_remove(struct platform_device *pdev)
v4l2_device_unregister(v4l2_dev);
- dma_free_coherent(video->dev, VE_JPEG_HEADER_SIZE, video->jpeg.virt, - video->jpeg.dma); + aspeed_video_free_buf(video, &video->jpeg);
of_reserved_mem_device_release(dev);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 5c0db68ce0faeb000c3540d095eb272d671a6e03 ]
If probe fails then we need to call pm_runtime_disable() to balance out the previous pm_runtime_enable() call.
Fixes: 9a761e436843 ("[media] exynos4-is: Add Exynos4x12 FIMC-IS driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Reviewed-by: Alim Akhtar alim.akhtar@samsung.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/samsung/exynos4-is/fimc-is.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c index e55e411038f4..81b290dace3a 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c @@ -830,7 +830,7 @@ static int fimc_is_probe(struct platform_device *pdev)
ret = pm_runtime_resume_and_get(dev); if (ret < 0) - goto err_irq; + goto err_pm_disable;
vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
@@ -864,6 +864,8 @@ static int fimc_is_probe(struct platform_device *pdev) pm_runtime_put_noidle(dev); if (!pm_runtime_enabled(dev)) fimc_is_runtime_suspend(dev); +err_pm_disable: + pm_runtime_disable(dev); err_irq: free_irq(is->irq, is); err_clk:
From: Felix Fietkau nbd@nbd.name
[ Upstream commit 96c777708bcac53f73a1c079e416495647f69553 ]
This code was accidentally dropped while adding 6 GHz support
Fixes: b4d093e321bd ("mt76: mt7915: add 6 GHz support") Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c index 5b133bcdab17..4b1a9811646f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c @@ -152,6 +152,8 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) phy->mt76->cap.has_2ghz = true; return; } + } else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) { + val = phy->band_idx ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ; }
switch (val) {
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 47eea8ad62a1203ce20b365f7feba23fef62a487 ]
Honor runtime-pm user configuration in mt7921_sniffer_interface_iter routine if we do not have a monitor interface.
Fixes: 1f12fa34e5dc5 ("mt76: mt7921: don't enable beacon filter when IEEE80211_CONF_CHANGE_MONITOR is set") 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/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index fdaf2451bc1d..11472aaf1440 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -489,8 +489,8 @@ mt7921_sniffer_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) bool monitor = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);
mt7921_mcu_set_sniffer(dev, vif, monitor); - pm->enable = !monitor; - pm->ds_enable = !monitor; + pm->enable = pm->enable_user && !monitor; + pm->ds_enable = pm->ds_enable_user && !monitor;
mt76_connac_mcu_set_deep_sleep(&dev->mt76, pm->ds_enable);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit aa796f12091aa4758366f5171fd9cba2ff574ba3 ]
Fix the following smatch static checker warning: drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:1872 mt7915_mcu_beacon_mbss() error: undefined (user controlled) shift '(((1))) << (data[2])'
Rely on mac80211 definitions for ieee80211_bssid_index subelement.
Fixes: 6b7f9aff7c67 ("mt76: mt7915: introduce 802.11ax multi-bss support") 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/mcu.c | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index e7a6f80e7755..736c9c342baa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -1854,7 +1854,8 @@ mt7915_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb, continue;
for_each_element(sub_elem, elem->data + 1, elem->datalen - 1) { - const u8 *data; + const struct ieee80211_bssid_index *idx; + const u8 *idx_ie;
if (sub_elem->id || sub_elem->datalen < 4) continue; /* not a valid BSS profile */ @@ -1862,14 +1863,19 @@ mt7915_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb, /* Find WLAN_EID_MULTI_BSSID_IDX * in the merged nontransmitted profile */ - data = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, - sub_elem->data, - sub_elem->datalen); - if (!data || data[1] < 1 || !data[2]) + idx_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, + sub_elem->data, + sub_elem->datalen); + if (!idx_ie || idx_ie[1] < sizeof(*idx)) continue;
- mbss->offset[data[2]] = cpu_to_le16(data - skb->data); - mbss->bitmap |= cpu_to_le32(BIT(data[2])); + idx = (void *)(idx_ie + 2); + if (!idx->bssid_index || idx->bssid_index > 31) + continue; + + mbss->offset[idx->bssid_index] = + cpu_to_le16(idx_ie - skb->data); + mbss->bitmap |= cpu_to_le32(BIT(idx->bssid_index)); } } }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 4e90db5e21eb3bb272fe47386dc3506755e209e9 ]
In case of error, some resources must be freed, as already done above and below the devm_kmemdup() and __mt7921e_mcu_drv_pmctrl() calls added in the commit in Fixes:.
Fixes: 602cc0c9618a ("mt76: mt7921e: fix possible probe failure after reboot") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 1a01d025bbe5..062e2b422478 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -302,8 +302,10 @@ static int mt7921_pci_probe(struct pci_dev *pdev, dev->bus_ops = dev->mt76.bus; bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), GFP_KERNEL); - if (!bus_ops) - return -ENOMEM; + if (!bus_ops) { + ret = -ENOMEM; + goto err_free_dev; + }
bus_ops->rr = mt7921_rr; bus_ops->wr = mt7921_wr; @@ -312,7 +314,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
ret = __mt7921e_mcu_drv_pmctrl(dev); if (ret) - return ret; + goto err_free_dev;
mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) | (mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 9bd6823f5a64b6465708b244eecc9b7dd4b01bfc ]
Add default case for type switch in mt7986_wmac_gpio_setup routine in order to avoid a possible uninitialized pointer dereference.
Fixes: 99ad32a4ca3a2 ("mt76: mt7915: add support for MT7986") 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/soc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c index 3028c02cb840..be448d471b03 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c @@ -210,6 +210,8 @@ static int mt7986_wmac_gpio_setup(struct mt7915_dev *dev) if (IS_ERR_OR_NULL(state)) return -EINVAL; break; + default: + return -EINVAL; }
ret = pinctrl_select_state(pinctrl, state);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 62fdc974894eec80d678523458cf99bbdb887e22 ]
Fix possible NULL pointer dereference in mt7915_mac_fill_rx_vector routine if the chip does not support dbdc and the hw reports band_idx set to 1.
Fixes: 78fc30a21cf11 ("mt76: mt7915: move testmode data from dev to phy") 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/mac.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index eaa31f5e0b00..fe2b63cf61d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -864,8 +864,11 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb) int i;
band_idx = le32_get_bits(rxv_hdr[1], MT_RXV_HDR_BAND_IDX); - if (band_idx && !phy->band_idx) + if (band_idx && !phy->band_idx) { phy = mt7915_ext_phy(dev); + if (!phy) + goto out; + }
rcpi = le32_to_cpu(rxv[6]); ib_rssi = le32_to_cpu(rxv[7]); @@ -890,8 +893,8 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
phy->test.last_freq_offset = foe; phy->test.last_snr = snr; +out: #endif - dev_kfree_skb(skb); }
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit badb6ffaa1439fce30fc6ef10571dcf45a622b44 ]
Fix typo in mt7915_muru_debug_set routine and pass muru_debug value to mt7915_mcu_muru_debug_set() instead of data pointer.
Fixes: 1966a5078f2d ("mt76: mt7915: add mu-mimo and ofdma debugfs knobs") 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 4e1ecaec8f4f..dece0a6e00b3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -95,7 +95,7 @@ mt7915_muru_debug_set(void *data, u64 val) struct mt7915_dev *dev = data;
dev->muru_debug = val; - mt7915_mcu_muru_debug_set(dev, data); + mt7915_mcu_muru_debug_set(dev, dev->muru_debug);
return 0; }
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 05268cf1789d99eda491c4a32f23a4c5b9bddeba ]
Report rx mode in mt7915_mac_fill_rx_rate routine in order to properly add he radiotap if mode is at least HE_SU.
Fixes: 1c9db0aa23fd1 ("mt76: mt7915: update rx rate reporting for mt7916") 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 | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index fe2b63cf61d8..45169a027fda 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -309,7 +309,7 @@ mt7915_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) }
static void -mt7915_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode) +mt7915_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u8 mode) { struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; static const struct ieee80211_radiotap_he known = { @@ -474,10 +474,10 @@ static int mt7915_mac_fill_rx_rate(struct mt7915_dev *dev, struct mt76_rx_status *status, struct ieee80211_supported_band *sband, - __le32 *rxv) + __le32 *rxv, u8 *mode) { u32 v0, v2; - u8 stbc, gi, bw, dcm, mode, nss; + u8 stbc, gi, bw, dcm, nss; int i, idx; bool cck = false;
@@ -490,18 +490,18 @@ mt7915_mac_fill_rx_rate(struct mt7915_dev *dev, if (!is_mt7915(&dev->mt76)) { stbc = FIELD_GET(MT_PRXV_HT_STBC, v0); gi = FIELD_GET(MT_PRXV_HT_SHORT_GI, v0); - mode = FIELD_GET(MT_PRXV_TX_MODE, v0); + *mode = FIELD_GET(MT_PRXV_TX_MODE, v0); dcm = FIELD_GET(MT_PRXV_DCM, v0); bw = FIELD_GET(MT_PRXV_FRAME_MODE, v0); } else { stbc = FIELD_GET(MT_CRXV_HT_STBC, v2); gi = FIELD_GET(MT_CRXV_HT_SHORT_GI, v2); - mode = FIELD_GET(MT_CRXV_TX_MODE, v2); + *mode = FIELD_GET(MT_CRXV_TX_MODE, v2); dcm = !!(idx & GENMASK(3, 0) & MT_PRXV_TX_DCM); bw = FIELD_GET(MT_CRXV_FRAME_MODE, v2); }
- switch (mode) { + switch (*mode) { case MT_PHY_TYPE_CCK: cck = true; fallthrough; @@ -546,7 +546,7 @@ mt7915_mac_fill_rx_rate(struct mt7915_dev *dev, case IEEE80211_STA_RX_BW_20: break; case IEEE80211_STA_RX_BW_40: - if (mode & MT_PHY_TYPE_HE_EXT_SU && + if (*mode & MT_PHY_TYPE_HE_EXT_SU && (idx & MT_PRXV_TX_ER_SU_106T)) { status->bw = RATE_INFO_BW_HE_RU; status->he_ru = @@ -566,7 +566,7 @@ mt7915_mac_fill_rx_rate(struct mt7915_dev *dev, }
status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc; - if (mode < MT_PHY_TYPE_HE_SU && gi) + if (*mode < MT_PHY_TYPE_HE_SU && gi) status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
return 0; @@ -581,7 +581,6 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) struct ieee80211_supported_band *sband; __le32 *rxd = (__le32 *)skb->data; __le32 *rxv = NULL; - u32 mode = 0; u32 rxd0 = le32_to_cpu(rxd[0]); u32 rxd1 = le32_to_cpu(rxd[1]); u32 rxd2 = le32_to_cpu(rxd[2]); @@ -590,10 +589,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM; bool unicast, insert_ccmp_hdr = false; u8 remove_pad, amsdu_info; + u8 mode = 0, qos_ctl = 0; bool hdr_trans; u16 hdr_gap; u16 seq_ctrl = 0; - u8 qos_ctl = 0; __le16 fc = 0; int idx;
@@ -766,7 +765,8 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) }
if (!is_mt7915(&dev->mt76) || (rxd1 & MT_RXD1_NORMAL_GROUP_5)) { - ret = mt7915_mac_fill_rx_rate(dev, status, sband, rxv); + ret = mt7915_mac_fill_rx_rate(dev, status, sband, rxv, + &mode); if (ret < 0) return ret; }
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit abba345311a740d9dca1b5eb293b3b1c296715dd ]
To make sure we have the proper antenna config in 6g cap, move IEEE80211_VHT_CAP_[T/R]X_ANTENNA_PATTERN to stream init.
Fixes: edf9dab8ba27 ("mt76: add 6GHz support") 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/mac80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 5b53d008eb66..917ea20c026b 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -248,6 +248,8 @@ static void mt76_init_stream_cap(struct mt76_phy *phy, vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; else vht_cap->cap &= ~IEEE80211_VHT_CAP_TXSTBC; + vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN | + IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
for (i = 0; i < 8; i++) { if (i < nstream) @@ -323,8 +325,6 @@ mt76_init_sband(struct mt76_phy *phy, struct mt76_sband *msband, vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC | IEEE80211_VHT_CAP_RXSTBC_1 | IEEE80211_VHT_CAP_SHORT_GI_80 | - IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | - IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN | (3 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
return 0;
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit ad483ed9dd5193a54293269c852a29051813b7bd ]
The crash log shown it is possible that mt7921_irq_handler is called while devm_free_irq is being handled so mt76_free_device need to be postponed until devm_free_irq is completed to solve the crash we free the mt76 device too early.
[ 9299.339655] BUG: kernel NULL pointer dereference, address: 0000000000000008 [ 9299.339705] #PF: supervisor read access in kernel mode [ 9299.339735] #PF: error_code(0x0000) - not-present page [ 9299.339768] PGD 0 P4D 0 [ 9299.339786] Oops: 0000 [#1] SMP PTI [ 9299.339812] CPU: 1 PID: 1624 Comm: prepare-suspend Not tainted 5.15.14-1.fc32.qubes.x86_64 #1 [ 9299.339863] Hardware name: Xen HVM domU, BIOS 4.14.3 01/20/2022 [ 9299.339901] RIP: 0010:mt7921_irq_handler+0x1e/0x70 [mt7921e] [ 9299.340048] RSP: 0018:ffffa81b80c27cb0 EFLAGS: 00010082 [ 9299.340081] RAX: 0000000000000000 RBX: ffff98a4cb752020 RCX: ffffffffa96211c5 [ 9299.340123] RDX: 0000000000000000 RSI: 00000000000d4204 RDI: ffff98a4cb752020 [ 9299.340165] RBP: ffff98a4c28a62a4 R08: ffff98a4c37a96c0 R09: 0000000080150011 [ 9299.340207] R10: 0000000040000000 R11: 0000000000000000 R12: ffff98a4c4eaa080 [ 9299.340249] R13: ffff98a4c28a6360 R14: ffff98a4cb752020 R15: ffff98a4c28a6228 [ 9299.340297] FS: 00007260840d3740(0000) GS:ffff98a4ef700000(0000) knlGS:0000000000000000 [ 9299.340345] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 9299.340383] CR2: 0000000000000008 CR3: 0000000004c56001 CR4: 0000000000770ee0 [ 9299.340432] PKRU: 55555554 [ 9299.340449] Call Trace: [ 9299.340467] <TASK> [ 9299.340485] __free_irq+0x221/0x350 [ 9299.340527] free_irq+0x30/0x70 [ 9299.340553] devm_free_irq+0x55/0x80 [ 9299.340579] mt7921_pci_remove+0x2f/0x40 [mt7921e] [ 9299.340616] pci_device_remove+0x3b/0xa0 [ 9299.340651] __device_release_driver+0x17a/0x240 [ 9299.340686] device_driver_detach+0x3c/0xa0 [ 9299.340714] unbind_store+0x113/0x130 [ 9299.340740] kernfs_fop_write_iter+0x124/0x1b0 [ 9299.340775] new_sync_write+0x15c/0x1f0 [ 9299.340806] vfs_write+0x1d2/0x270 [ 9299.340831] ksys_write+0x67/0xe0 [ 9299.340857] do_syscall_64+0x3b/0x90 [ 9299.340887] entry_SYSCALL_64_after_hwframe+0x44/0xae
Fixes: 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support") Reported-by: ThinerLogoer logoerthiner1@163.com Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 062e2b422478..b5fb22b8e086 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -119,7 +119,6 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) mt7921_mcu_exit(dev);
tasklet_disable(&dev->irq_tasklet); - mt76_free_device(&dev->mt76); }
static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) @@ -356,6 +355,7 @@ static void mt7921_pci_remove(struct pci_dev *pdev)
mt7921e_unregister_device(dev); devm_free_irq(&pdev->dev, pdev->irq, dev); + mt76_free_device(&dev->mt76); pci_free_irq_vectors(pdev); }
From: Felix Fietkau nbd@nbd.name
[ Upstream commit 3968a66475b40691c37b5e6c76975f699671e10e ]
Fixes potential latency / packet drop issues in cases where a BA session has not (yet) been established.
Fixes: e195dad14115 ("mt76: add support for 802.3 rx frames") Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/agg-rx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c index 72622220051b..6c8b44194579 100644 --- a/drivers/net/wireless/mediatek/mt76/agg-rx.c +++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c @@ -162,8 +162,9 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames) if (!sta) return;
- if (!status->aggr && !(status->flag & RX_FLAG_8023)) { - mt76_rx_aggr_check_ctl(skb, frames); + if (!status->aggr) { + if (!(status->flag & RX_FLAG_8023)) + mt76_rx_aggr_check_ctl(skb, frames); return; }
From: Felix Fietkau nbd@nbd.name
[ Upstream commit fcfe1b5e162bf473c1d47760962cec8523c00466 ]
There is a small race window where ongoing tx activity can lead to a skb getting added to the status tracking idr after that idr has already been cleaned up, which will keep the wcid linked in the status poll list. Fix this by only adding status skbs if the wcid pointer is still assigned in dev->wcid, which gets cleared early by mt76_sta_pre_rcu_remove
Fixes: bd1e3e7b693c ("mt76: introduce packet_id idr") Tested-by: Ben Greear greearb@candelatech.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 ++ drivers/net/wireless/mediatek/mt76/tx.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 917ea20c026b..ef11043d1a4a 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1381,7 +1381,9 @@ void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
mutex_lock(&dev->mutex); + spin_lock_bh(&dev->status_lock); rcu_assign_pointer(dev->wcid[wcid->idx], NULL); + spin_unlock_bh(&dev->status_lock); mutex_unlock(&dev->mutex); } EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove); diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 6b8c9dc80542..ccaf9a31fbc4 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -120,7 +120,7 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid,
memset(cb, 0, sizeof(*cb));
- if (!wcid) + if (!wcid || !rcu_access_pointer(dev->wcid[wcid->idx])) return MT_PACKET_ID_NO_ACK;
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
From: Peter Chiu chui-hao.chiu@mediatek.com
[ Upstream commit 3620c8821ae15902eb995a32918e34b7a0c773a3 ]
mt7915 can support 16 twt stations so modify table_mask to u16.
Fixes: 3782b69d03e7 ("mt76: mt7915: introduce mt7915_mac_add_twt_setup routine") Signed-off-by: Peter Chiu chui-hao.chiu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 6efa0a2e2345..4b6eda958ef3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -319,7 +319,7 @@ struct mt7915_dev { void *cal;
struct { - u8 table_mask; + u16 table_mask; u8 n_agrt; } twt;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 94e3dba710fe0afc772172305444250023fc2d30 ]
The pm_runtime_enable will decrease power disable depth. If the probe fails, we should use pm_runtime_disable() to balance pm_runtime_enable().
Fixes: f386509e4959 ("[media] st-delta: STiH4xx multi-format video decoder v4l2 driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Acked-by: Hugues Fruchet hugues.fruchet@foss.st.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/st/sti/delta/delta-v4l2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/st/sti/delta/delta-v4l2.c b/drivers/media/platform/st/sti/delta/delta-v4l2.c index c887a31ebb54..420ad4d8df5d 100644 --- a/drivers/media/platform/st/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/st/sti/delta/delta-v4l2.c @@ -1859,7 +1859,7 @@ static int delta_probe(struct platform_device *pdev) if (ret) { dev_err(delta->dev, "%s failed to initialize firmware ipc channel\n", DELTA_PREFIX); - goto err; + goto err_pm_disable; }
/* register all available decoders */ @@ -1873,7 +1873,7 @@ static int delta_probe(struct platform_device *pdev) if (ret) { dev_err(delta->dev, "%s failed to register V4L2 device\n", DELTA_PREFIX); - goto err; + goto err_pm_disable; }
delta->work_queue = create_workqueue(DELTA_NAME); @@ -1898,6 +1898,8 @@ static int delta_probe(struct platform_device *pdev) destroy_workqueue(delta->work_queue); err_v4l2: v4l2_device_unregister(&delta->v4l2_dev); +err_pm_disable: + pm_runtime_disable(dev); err: return ret; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 395829c61a196a0821a703a49c4db3ac51daff73 ]
The pm_runtime_enable will decrease power disable depth. If the probe fails, we should use pm_runtime_disable() to balance pm_runtime_enable().
Fixes: 0a0e265515db ("media: atmel: atmel-isc: split driver into driver base and isc") 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/platform/atmel/atmel-sama5d2-isc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index c5b9563e36cb..e9415495e738 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -562,7 +562,7 @@ static int atmel_isc_probe(struct platform_device *pdev) ret = clk_prepare_enable(isc->ispck); if (ret) { dev_err(dev, "failed to enable ispck: %d\n", ret); - goto cleanup_subdev; + goto disable_pm; }
/* ispck should be greater or equal to hclock */ @@ -580,6 +580,9 @@ static int atmel_isc_probe(struct platform_device *pdev) unprepare_clk: clk_disable_unprepare(isc->ispck);
+disable_pm: + pm_runtime_disable(dev); + cleanup_subdev: isc_subdev_cleanup(isc);
From: Laurentiu Palcu laurentiu.palcu@oss.nxp.com
[ Upstream commit d2facee67b4883bb3e7461a0a93fd70d0c7b7261 ]
The subdevice entity function was left unset, which produces a warning when probing the device:
mxc-md bus@58000000:camera: Entity type for entity rdacm20 19-0051 was not initialized!
This patch will set entity function to MEDIA_ENT_F_CAM_SENSOR and leave flags unset.
Fixes: 34009bffc1c6 ("media: i2c: Add RDACM20 driver") Fixes: a59f853b3b4b ("media: i2c: Add driver for RDACM21 camera module") Signed-off-by: Laurentiu Palcu laurentiu.palcu@oss.nxp.com Reviewed-by: Jacopo Mondi jacopo+renesas@jmondi.org Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/rdacm20.c | 2 +- drivers/media/i2c/rdacm21.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 025a610de893..9c6f66cab564 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -611,7 +611,7 @@ static int rdacm20_probe(struct i2c_client *client) goto error_free_ctrls;
dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; + dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); if (ret < 0) goto error_free_ctrls; diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 12ec5467ed1e..ef31cf5f23ca 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -583,7 +583,7 @@ static int rdacm21_probe(struct i2c_client *client) goto error_free_ctrls;
dev->pad.flags = MEDIA_PAD_FL_SOURCE; - dev->sd.entity.flags |= MEDIA_ENT_F_CAM_SENSOR; + dev->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&dev->sd.entity, 1, &dev->pad); if (ret < 0) goto error_free_ctrls;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 9fadab72a6916c7507d7fedcd644859eef995078 ]
The corresponding API for clk_prepare_enable is clk_disable_unprepare, other than clk_disable.
Fix this by changing clk_disable to clk_disable_unprepare.
Fixes: b4155d7d5b2c ("[media] exynos4-is: Ensure fimc-is clocks are not enabled until properly configured") 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/platform/samsung/exynos4-is/fimc-is.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is.c b/drivers/media/platform/samsung/exynos4-is/fimc-is.c index 81b290dace3a..e3072d69c49f 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-is.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-is.c @@ -140,7 +140,7 @@ static int fimc_is_enable_clocks(struct fimc_is *is) dev_err(&is->pdev->dev, "clock %s enable failed\n", fimc_is_clocks[i]); for (--i; i >= 0; i--) - clk_disable(is->clocks[i]); + clk_disable_unprepare(is->clocks[i]); return ret; } pr_debug("enabled clock: %s\n", fimc_is_clocks[i]);
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit 471bec68457aaf981add77b4f590d65dd7da1059 ]
Syzbot reported that -1 is used as array index. The problem was in missing validation check.
hdw->unit_number is initialized with -1 and then if init table walk fails this value remains unchanged. Since code blindly uses this member for array indexing adding sanity check is the easiest fix for that.
hdw->workpoll initialization moved upper to prevent warning in __flush_work.
Reported-and-tested-by: syzbot+1a247e36149ffd709a9b@syzkaller.appspotmail.com
Fixes: d855497edbfb ("V4L/DVB (4228a): pvrusb2 to kernel 2.6.18") Signed-off-by: Pavel Skripkin paskripkin@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/pvrusb2/pvrusb2-hdw.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index cd7b118d5929..a9666373af6b 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2569,6 +2569,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, } while (0); mutex_unlock(&pvr2_unit_mtx);
+ INIT_WORK(&hdw->workpoll, pvr2_hdw_worker_poll); + + if (hdw->unit_number == -1) + goto fail; + cnt1 = 0; cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); cnt1 += cnt2; @@ -2580,8 +2585,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; hdw->name[cnt1] = 0;
- INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); - pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", hdw->unit_number,hdw->name);
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 215d49a41709610b9e82a49b27269cfaff1ef0b6 ]
Fix build errors when RADIO_TEA575X=y, VIDEO_BT848=m, and VIDEO_DEV=m.
The build errors occur due to [in drivers/media/Makefile]: obj-$(CONFIG_VIDEO_DEV) += radio/ so the (would be) builtin tea575x.o is not being built.
This is also due to drivers/media/radio/Kconfig declaring a bool Kconfig symbol (RADIO_ADAPTERS) that depends on a tristate (VIDEO_DEV), so when VIDEO_DEV=m, RADIO_ADAPTERS becomes =y, and then the drivers that depend on RADIO_ADPATERS can be configured as builtin (=y) or as loadable modules (=m).
Fix this by converting RADIO_ADAPTERS to a tristate symbol instead of a bool symbol.
Fixes these build errors:
ERROR: modpost: "snd_tea575x_hw_init" [drivers/media/pci/bt8xx/bttv.ko] undefined! ERROR: modpost: "snd_tea575x_set_freq" [drivers/media/pci/bt8xx/bttv.ko] undefined! ERROR: modpost: "snd_tea575x_s_hw_freq_seek" [drivers/media/pci/bt8xx/bttv.ko] undefined! ERROR: modpost: "snd_tea575x_enum_freq_bands" [drivers/media/pci/bt8xx/bttv.ko] undefined! ERROR: modpost: "snd_tea575x_g_tuner" [drivers/media/pci/bt8xx/bttv.ko] undefined!
Link: lore.kernel.org/r/202204191711.IKJJFjgU-lkp@intel.com
Fixes: 9958d30f38b9 ("media: Kconfig: cleanup VIDEO_DEV dependencies") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.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/radio/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index cca03bd2cc42..616a38feb641 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -4,10 +4,10 @@ #
menuconfig RADIO_ADAPTERS - bool "Radio Adapters" + tristate "Radio Adapters" depends on VIDEO_DEV depends on MEDIA_RADIO_SUPPORT - default y + default VIDEO_DEV help Say Y here to enable selecting AM/FM radio adapters.
From: Michael Rodin mrodin@de.adit-jv.com
[ Upstream commit 5f25abec8f21b7527c1223a354d23c270befddb3 ]
The vertical subsampling factor is currently not considered in the offset calculation for plane cropping done in rpf_configure_partition. This causes a distortion (shift of the color plane) when formats with the vsub factor larger than 1 are used (e.g. NV12, see vsp1_video_formats in vsp1_pipe.c). This commit considers vsub factor for all planes except plane 0 (luminance).
Drop generalization of the offset calculation to reduce the binary size.
Fixes: e5ad37b64de9 ("[media] v4l: vsp1: Add cropping support") Signed-off-by: Michael Rodin mrodin@de.adit-jv.com Signed-off-by: LUU HOAI hoai.luu.ub@renesas.com Signed-off-by: Laurent Pinchart laurent.pinchart+renesas@ideasonboard.com Reviewed-by: Kieran Bingham kieran.bingham+renesas@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/renesas/vsp1/vsp1_rpf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c index 85587c1b6a37..75083cb234fe 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_rpf.c @@ -291,11 +291,11 @@ static void rpf_configure_partition(struct vsp1_entity *entity, + crop.left * fmtinfo->bpp[0] / 8;
if (format->num_planes > 1) { + unsigned int bpl = format->plane_fmt[1].bytesperline; unsigned int offset;
- offset = crop.top * format->plane_fmt[1].bytesperline - + crop.left / fmtinfo->hsub - * fmtinfo->bpp[1] / 8; + offset = crop.top / fmtinfo->vsub * bpl + + crop.left / fmtinfo->hsub * fmtinfo->bpp[1] / 8; mem.addr[1] += offset; mem.addr[2] += offset; }
From: Eugen Hristev eugen.hristev@microchip.com
[ Upstream commit 91f49b80983f7bffdea9498209b2b896231ac776 ]
While this does not happen in production, this check should be done versus the mask, as checking with the YCYC value may not include some bits that may be set. It is correct and safe to check the whole mask.
Fixes: 123aaf816b95 ("media: atmel: atmel-sama5d2-isc: fix YUYV format") Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Reviewed-by: Jacopo Mondi jacopo@jmondi.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/atmel/atmel-sama5d2-isc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index e9415495e738..c2d50b0c0e3d 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -291,7 +291,7 @@ static void isc_sama5d2_config_rlp(struct isc_device *isc) * Thus, if the YCYC mode is selected, replace it with the * sama5d2-compliant mode which is YYCC . */ - if ((rlp_mode & ISC_RLP_CFG_MODE_YCYC) == ISC_RLP_CFG_MODE_YCYC) { + if ((rlp_mode & ISC_RLP_CFG_MODE_MASK) == ISC_RLP_CFG_MODE_YCYC) { rlp_mode &= ~ISC_RLP_CFG_MODE_MASK; rlp_mode |= ISC_RLP_CFG_MODE_YYCC; }
From: Benjamin Gaignard benjamin.gaignard@collabora.com
[ Upstream commit d7f4149df818463c1d7094b35db6ebd79f46c7bd ]
Use pps->column_width_minus1[j] + 1 as value for the tile info buffer instead of pps->column_width_minus1[j + 1]. The patch fixes DBLK_E_VIXS_2, DBLK_F_VIXS_2, DBLK_G_VIXS_2, SAO_B_MediaTek_5, TILES_A_Cisco_2 and TILES_B_Cisco_1 tests in fluster.
Fixes: cb5dd5a0fa51 ("media: hantro: Introduce G2/HEVC decoder") 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_g2_hevc_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c index 2e7eec0372cd..5f3178bac9c8 100644 --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c @@ -60,7 +60,7 @@ static void prepare_tile_info_buffer(struct hantro_ctx *ctx) no_chroma = 1; for (j = 0, tmp_w = 0; j < num_tile_cols - 1; j++) { tmp_w += pps->column_width_minus1[j] + 1; - *p++ = pps->column_width_minus1[j + 1]; + *p++ = pps->column_width_minus1[j] + 1; *p++ = h; if (i == 0 && h == 1 && ctb_size == 16) no_chroma = 1;
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 789f6b8ac3b15bca09b69d5699cad0bf6e2103aa ]
Fix the incorrect pointer check on ven_data.
Fixes: f41b91fa1783 ("Bluetooth: mt7921s: Add .btmtk_get_codec_config_data") Co-developed-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btmtksdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index f3dc5881fff7..b6d77e04240c 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -961,7 +961,7 @@ static int btmtksdio_get_codec_config_data(struct hci_dev *hdev, }
*ven_data = kmalloc(sizeof(__u8), GFP_KERNEL); - if (!ven_data) { + if (!*ven_data) { err = -ENOMEM; goto error; }
From: Ying Hsu yinghsu@chromium.org
[ Upstream commit 7aa1e7d15f8a5b65f67bacb100d8fc033b21efa2 ]
Connecting the same socket twice consecutively in sco_sock_connect() could lead to a race condition where two sco_conn objects are created but only one is associated with the socket. If the socket is closed before the SCO connection is established, the timer associated with the dangling sco_conn object won't be canceled. As the sock object is being freed, the use-after-free problem happens when the timer callback function sco_sock_timeout() accesses the socket. Here's the call trace:
dump_stack+0x107/0x163 ? refcount_inc+0x1c/ print_address_description.constprop.0+0x1c/0x47e ? refcount_inc+0x1c/0x7b kasan_report+0x13a/0x173 ? refcount_inc+0x1c/0x7b check_memory_region+0x132/0x139 refcount_inc+0x1c/0x7b sco_sock_timeout+0xb2/0x1ba process_one_work+0x739/0xbd1 ? cancel_delayed_work+0x13f/0x13f ? __raw_spin_lock_init+0xf0/0xf0 ? to_kthread+0x59/0x85 worker_thread+0x593/0x70e kthread+0x346/0x35a ? drain_workqueue+0x31a/0x31a ? kthread_bind+0x4b/0x4b ret_from_fork+0x1f/0x30
Link: https://syzkaller.appspot.com/bug?extid=2bef95d3ab4daa10155b Reported-by: syzbot+2bef95d3ab4daa10155b@syzkaller.appspotmail.com Fixes: e1dee2c1de2b ("Bluetooth: fix repeated calls to sco_sock_kill") Signed-off-by: Ying Hsu yinghsu@chromium.org Reviewed-by: Joseph Hwang josephsih@chromium.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 2a58c7d88433..1111da4e2f2b 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -574,19 +574,24 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen addr->sa_family != AF_BLUETOOTH) return -EINVAL;
- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) - return -EBADFD; + lock_sock(sk); + if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) { + err = -EBADFD; + goto done; + }
- if (sk->sk_type != SOCK_SEQPACKET) - return -EINVAL; + if (sk->sk_type != SOCK_SEQPACKET) { + err = -EINVAL; + goto done; + }
hdev = hci_get_route(&sa->sco_bdaddr, &sco_pi(sk)->src, BDADDR_BREDR); - if (!hdev) - return -EHOSTUNREACH; + if (!hdev) { + err = -EHOSTUNREACH; + goto done; + } hci_dev_lock(hdev);
- lock_sock(sk); - /* Set destination address and psm */ bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr);
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 50a3633ae5e98cf1b80ef5b73c9e341aee9ad896 ]
hci_is_adv_monitoring's function documentation states that it must be called under the hdev lock. Paths that leads to an unlocked call are: discov_update => start_discovery => interleaved_discov => active_scan and: discov_update => start_discovery => active_scan
The solution is to take the lock in active_scan during the duration of the call to hci_is_adv_monitoring.
Fixes: c32d624640fd ("Bluetooth: disable filter dup when scan for adv monitor") Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_request.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 42c8047a9897..f4afe482e300 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -2260,6 +2260,7 @@ static int active_scan(struct hci_request *req, unsigned long opt) if (err < 0) own_addr_type = ADDR_LE_DEV_PUBLIC;
+ hci_dev_lock(hdev); if (hci_is_adv_monitoring(hdev)) { /* Duplicate filter should be disabled when some advertisement * monitor is activated, otherwise AdvMon can only receive one @@ -2276,6 +2277,7 @@ static int active_scan(struct hci_request *req, unsigned long opt) */ filter_dup = LE_SCAN_FILTER_DUP_DISABLE; } + hci_dev_unlock(hdev);
hci_req_start_scan(req, LE_SCAN_ACTIVE, interval, hdev->le_scan_window_discovery, own_addr_type,
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit fb048cae51bacdfbbda2954af3c213fdb1d484f4 ]
All accesses (both reads and modifications) to hdev->{accept,reject}_list are protected by hdev lock, except the ones in hci_conn_request_evt. This can cause a race condition in the form of a list corruption. The solution is to protect these lists in hci_conn_request_evt as well.
I was unable to find the exact commit that introduced the issue for the reject list, I was only able to find it for the accept list.
Fixes: a55bd29d5227 ("Bluetooth: Add white list lookup for incoming connection requests") Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_event.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 66451661283c..a835ce6f8430 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3225,10 +3225,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, return; }
+ hci_dev_lock(hdev); + if (hci_bdaddr_list_lookup(&hdev->reject_list, &ev->bdaddr, BDADDR_BREDR)) { hci_reject_conn(hdev, &ev->bdaddr); - return; + goto unlock; }
/* Require HCI_CONNECTABLE or an accept list entry to accept the @@ -3240,13 +3242,11 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, !hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr, BDADDR_BREDR)) { hci_reject_conn(hdev, &ev->bdaddr); - return; + goto unlock; }
/* Connection accepted */
- hci_dev_lock(hdev); - ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr); if (ie) memcpy(ie->data.dev_class, ev->dev_class, 3); @@ -3258,8 +3258,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, HCI_ROLE_SLAVE); if (!conn) { bt_dev_err(hdev, "no memory for new connection"); - hci_dev_unlock(hdev); - return; + goto unlock; } }
@@ -3299,6 +3298,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, conn->state = BT_CONNECT2; hci_connect_cfm(conn, 0); } + + return; +unlock: + hci_dev_unlock(hdev); }
static u8 hci_to_mgmt_reason(u8 err)
From: Niels Dossche dossche.niels@gmail.com
[ Upstream commit 5e2b6064cbc5fd582396768c5f9583f65085e368 ]
Concurrent operations from events on le_{accept,resolv}_list are currently unprotected by hdev->lock. Most existing code do already protect the lists with that lock. This can be observed in hci_debugfs and hci_sync. Add the protection for these events too.
Fixes: b950aa88638c ("Bluetooth: Add definitions and track LE resolve list modification") Fixes: 0f36b589e4ee ("Bluetooth: Track LE white list modification via HCI commands") Signed-off-by: Niels Dossche dossche.niels@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_event.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a835ce6f8430..0270e597c285 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1835,7 +1835,9 @@ static u8 hci_cc_le_clear_accept_list(struct hci_dev *hdev, void *data, if (rp->status) return rp->status;
+ hci_dev_lock(hdev); hci_bdaddr_list_clear(&hdev->le_accept_list); + hci_dev_unlock(hdev);
return rp->status; } @@ -1855,8 +1857,10 @@ static u8 hci_cc_le_add_to_accept_list(struct hci_dev *hdev, void *data, if (!sent) return rp->status;
+ hci_dev_lock(hdev); hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr, sent->bdaddr_type); + hci_dev_unlock(hdev);
return rp->status; } @@ -1876,8 +1880,10 @@ static u8 hci_cc_le_del_from_accept_list(struct hci_dev *hdev, void *data, if (!sent) return rp->status;
+ hci_dev_lock(hdev); hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr, sent->bdaddr_type); + hci_dev_unlock(hdev);
return rp->status; } @@ -1949,9 +1955,11 @@ static u8 hci_cc_le_add_to_resolv_list(struct hci_dev *hdev, void *data, if (!sent) return rp->status;
+ hci_dev_lock(hdev); hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr, sent->bdaddr_type, sent->peer_irk, sent->local_irk); + hci_dev_unlock(hdev);
return rp->status; } @@ -1971,8 +1979,10 @@ static u8 hci_cc_le_del_from_resolv_list(struct hci_dev *hdev, void *data, if (!sent) return rp->status;
+ hci_dev_lock(hdev); hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr, sent->bdaddr_type); + hci_dev_unlock(hdev);
return rp->status; } @@ -1987,7 +1997,9 @@ static u8 hci_cc_le_clear_resolv_list(struct hci_dev *hdev, void *data, if (rp->status) return rp->status;
+ hci_dev_lock(hdev); hci_bdaddr_list_clear(&hdev->le_resolv_list); + hci_dev_unlock(hdev);
return rp->status; }
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 0fab6361c4ba17d1b43a991bef4238a3c1754d35 ]
We should not access skb buffer data anymore after hci_recv_frame was called.
[ 39.634809] BUG: KASAN: use-after-free in btmtksdio_recv_event+0x1b0 [ 39.634855] Read of size 1 at addr ffffff80cf28a60d by task kworker [ 39.634962] Call trace: [ 39.634974] dump_backtrace+0x0/0x3b8 [ 39.634999] show_stack+0x20/0x2c [ 39.635016] dump_stack_lvl+0x60/0x78 [ 39.635040] print_address_description+0x70/0x2f0 [ 39.635062] kasan_report+0x154/0x194 [ 39.635079] __asan_report_load1_noabort+0x44/0x50 [ 39.635099] btmtksdio_recv_event+0x1b0/0x1c4 [ 39.635129] btmtksdio_txrx_work+0x6cc/0xac4 [ 39.635157] process_one_work+0x560/0xc5c [ 39.635177] worker_thread+0x7ec/0xcc0 [ 39.635195] kthread+0x2d0/0x3d0 [ 39.635215] ret_from_fork+0x10/0x20 [ 39.635247] Allocated by task 0: [ 39.635260] (stack is not available) [ 39.635281] Freed by task 2392: [ 39.635295] kasan_save_stack+0x38/0x68 [ 39.635319] kasan_set_track+0x28/0x3c [ 39.635338] kasan_set_free_info+0x28/0x4c [ 39.635357] ____kasan_slab_free+0x104/0x150 [ 39.635374] __kasan_slab_free+0x18/0x28 [ 39.635391] slab_free_freelist_hook+0x114/0x248 [ 39.635410] kfree+0xf8/0x2b4 [ 39.635427] skb_free_head+0x58/0x98 [ 39.635447] skb_release_data+0x2f4/0x410 [ 39.635464] skb_release_all+0x50/0x60 [ 39.635481] kfree_skb+0xc8/0x25c [ 39.635498] hci_event_packet+0x894/0xca4 [bluetooth] [ 39.635721] hci_rx_work+0x1c8/0x68c [bluetooth] [ 39.635925] process_one_work+0x560/0xc5c [ 39.635951] worker_thread+0x7ec/0xcc0 [ 39.635970] kthread+0x2d0/0x3d0 [ 39.635990] ret_from_fork+0x10/0x20 [ 39.636021] The buggy address belongs to the object at ffffff80cf28a600 which belongs to the cache kmalloc-512 of size 512 [ 39.636039] The buggy address is located 13 bytes inside of 512-byte region [ffffff80cf28a600, ffffff80cf28a800)
Fixes: 9aebfd4a2200 ("Bluetooth: mediatek: add support for MediaTek MT7663S and MT7668S SDIO devices") Co-developed-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btmtksdio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index b6d77e04240c..4ae6631a7c29 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -379,6 +379,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) { struct btmtksdio_dev *bdev = hci_get_drvdata(hdev); struct hci_event_hdr *hdr = (void *)skb->data; + u8 evt = hdr->evt; int err;
/* When someone waits for the WMT event, the skb is being cloned @@ -396,7 +397,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb) if (err < 0) goto err_free_skb;
- if (hdr->evt == HCI_EV_WMT) { + if (evt == HCI_EV_WMT) { if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT, &bdev->tx_state)) { /* Barrier to sync with other CPUs */
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 7469720563e01f479ec5afe06bd6f440f965d523 ]
According to FW advised sequence, mt7921s need to re-acquire privilege immediately after the firmware download is complete before normal running. Otherwise, it is still possible the bus may be stuck in an abnormal status that causes FW initialization failure in the current driver.
Fixes: 752aea58489f ("Bluetooth: mt7921s: fix bus hang with wrong privilege") Co-developed-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btmtksdio.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 4ae6631a7c29..5d13c1f61bd3 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -864,6 +864,14 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname) return err; }
+ err = btmtksdio_fw_pmctrl(bdev); + if (err < 0) + return err; + + err = btmtksdio_drv_pmctrl(bdev); + if (err < 0) + return err; + /* Enable Bluetooth protocol */ wmt_params.op = BTMTK_WMT_FUNC_CTRL; wmt_params.flag = 0; @@ -1109,14 +1117,6 @@ static int btmtksdio_setup(struct hci_dev *hdev) if (err < 0) return err;
- err = btmtksdio_fw_pmctrl(bdev); - if (err < 0) - return err; - - err = btmtksdio_drv_pmctrl(bdev); - if (err < 0) - return err; - /* Enable SCO over I2S/PCM */ err = btmtksdio_sco_setting(hdev); if (err < 0) {
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit baabb7f530e8a3f0085d12f4ea0bada4115515d3 ]
Sending WMT command during the reset in progress is invalid and would get no response from firmware until the reset is complete, so we ignore the WMT command here to resolve the issue which causes the whole reset process taking too long.
Fixes: 8fafe702253d ("Bluetooth: mt7921s: support bluetooth reset mechanism") Co-developed-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Yake Yang yake.yang@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btmtksdio.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c index 5d13c1f61bd3..d6700efcfe8c 100644 --- a/drivers/bluetooth/btmtksdio.c +++ b/drivers/bluetooth/btmtksdio.c @@ -1189,6 +1189,10 @@ static int btmtksdio_shutdown(struct hci_dev *hdev) */ pm_runtime_get_sync(bdev->dev);
+ /* wmt command only works until the reset is complete */ + if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state)) + goto ignore_wmt_cmd; + /* Disable the device */ wmt_params.op = BTMTK_WMT_FUNC_CTRL; wmt_params.flag = 0; @@ -1202,6 +1206,7 @@ static int btmtksdio_shutdown(struct hci_dev *hdev) return err; }
+ignore_wmt_cmd: pm_runtime_put_noidle(bdev->dev); pm_runtime_disable(bdev->dev);
From: Yunfei Dong yunfei.dong@mediatek.com
[ Upstream commit 08a83828825cbf3bc2c9f582a4cd4da9f40c77d6 ]
Will return -EINVAL using standard framework api when test stateless decoder with cmd VIDIOC_(TRY)DECODER_CMD. Disable them to adjust v4l2 compliance test for user driver(GStreamer/Chrome) won't use decoder cmd.
Fixes: 8cdc3794b2e3 ("media: mtk-vcodec: vdec: support stateless API") Signed-off-by: Yunfei Dong yunfei.dong@mediatek.com Reviewed-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 --- .../media/platform/mediatek/vcodec/mtk_vcodec_dec.c | 13 +------------ .../platform/mediatek/vcodec/mtk_vcodec_dec_drv.c | 3 +++ 2 files changed, 4 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 130ecef2e766..c8ee5e2b4f69 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -47,14 +47,7 @@ static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx, static int vidioc_try_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { - struct mtk_vcodec_ctx *ctx = fh_to_ctx(priv); - - /* Use M2M stateless helper if relevant */ - if (ctx->dev->vdec_pdata->uses_stateless_api) - return v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, - cmd); - else - return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd); + return v4l2_m2m_ioctl_try_decoder_cmd(file, priv, cmd); }
@@ -69,10 +62,6 @@ static int vidioc_decoder_cmd(struct file *file, void *priv, if (ret) return ret;
- /* Use M2M stateless helper if relevant */ - if (ctx->dev->vdec_pdata->uses_stateless_api) - return v4l2_m2m_ioctl_stateless_decoder_cmd(file, priv, cmd); - mtk_v4l2_debug(1, "decoder cmd=%u", cmd->cmd); dst_vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); 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 128edcf541e1..fe7b2f1739b1 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -400,6 +400,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev) }
if (dev->vdec_pdata->uses_stateless_api) { + v4l2_disable_ioctl(vfd_dec, VIDIOC_DECODER_CMD); + v4l2_disable_ioctl(vfd_dec, VIDIOC_TRY_DECODER_CMD); + dev->mdev_dec.dev = &pdev->dev; strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME, sizeof(dev->mdev_dec.model));
From: Pavel Begunkov asml.silence@gmail.com
[ Upstream commit e0deb6a025ae8c850dc8685be39fb27b06c88736 ]
If an opcode handler semi-reliably returns -EAGAIN, io_wq_submit_work() might continue busily hammer the same handler over and over again, which is not ideal. The -EAGAIN handling in question was put there only for IOPOLL, so restrict it to IOPOLL mode only where there is no other recourse than to retry as we cannot wait.
Fixes: def596e9557c9 ("io_uring: support for IO polling") Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/f168b4f24181942f3614dd8ff648221736f572e6.165243374... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/io_uring.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/io_uring.c b/fs/io_uring.c index e0823f58f795..7272e410d24a 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -7327,6 +7327,8 @@ static void io_wq_submit_work(struct io_wq_work *work) * wait for request slots on the block side. */ if (!needs_poll) { + if (!(req->ctx->flags & IORING_SETUP_IOPOLL)) + break; cond_resched(); continue; }
From: Dylan Yudaken dylany@fb.com
[ Upstream commit 1b1d7b4bf1d9948c8dba5ee550459ce7c65ac019 ]
The check for waking up a request compares the poll_t bits, however this will always contain some common flags so this always wakes up.
For files with single wait queues such as sockets this can cause the request to be sent to the async worker unnecesarily. Further if it is non-blocking will complete the request with EAGAIN which is not desired.
Here exclude these common events, making sure to not exclude POLLERR which might be important.
Fixes: d7718a9d25a6 ("io_uring: use poll driven retry for files that support it") Signed-off-by: Dylan Yudaken dylany@fb.com Link: https://lore.kernel.org/r/20220512091834.728610-3-dylany@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/io_uring.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/io_uring.c b/fs/io_uring.c index 7272e410d24a..9e247335e70d 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -5981,6 +5981,7 @@ static void io_poll_cancel_req(struct io_kiocb *req)
#define wqe_to_req(wait) ((void *)((unsigned long) (wait)->private & ~1)) #define wqe_is_double(wait) ((unsigned long) (wait)->private & 1) +#define IO_ASYNC_POLL_COMMON (EPOLLONESHOT | POLLPRI)
static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, void *key) @@ -6015,7 +6016,7 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, }
/* for instances that support it check for an event match first */ - if (mask && !(mask & poll->events)) + if (mask && !(mask & (poll->events & ~IO_ASYNC_POLL_COMMON))) return 0;
if (io_poll_get_ownership(req)) { @@ -6171,7 +6172,7 @@ static int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags) struct io_ring_ctx *ctx = req->ctx; struct async_poll *apoll; struct io_poll_table ipt; - __poll_t mask = EPOLLONESHOT | POLLERR | POLLPRI; + __poll_t mask = IO_ASYNC_POLL_COMMON | POLLERR; int ret;
if (!def->pollin && !def->pollout)
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit adf14453d2c037ab529040c1186ea32e277e783a ]
There are cases where a context synchronization event is necessary between an IRQ being raised and being handled, and there are races such that we cannot rely upon the exception entry being subsequent to the interrupt being raised.
We identified and fixes this for regular IRQs in commit:
39a06b67c2c1256b ("irqchip/gic: Ensure we have an ISB between ack and ->handle_irq")
Unfortunately, we forgot to do the same for psuedo-NMIs when support for those was added in commit:
f32c926651dcd168 ("irqchip/gic-v3: Handle pseudo-NMIs")
Which means that when pseudo-NMIs are used for PMU support, we'll hit the same problem.
Apply the same fix as for regular IRQs. Note that when EOI mode 1 is in use, the call to gic_write_eoir() will provide an ISB.
Fixes: f32c926651dcd168 ("irqchip/gic-v3: Handle pseudo-NMIs") Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Marc Zyngier maz@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220513133038.226182-2-mark.rutland@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-gic-v3.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index b252d5534547..7305d84f2df5 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -654,6 +654,9 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
if (static_branch_likely(&supports_deactivate_key)) gic_write_eoir(irqnr); + else + isb() + /* * Leave the PSR.I bit set to prevent other NMIs to be * received while handling this one.
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit 6efb50923771f392122f5ce69dfc43b08f16e449 ]
There are cases where a context synchronization event is necessary between an IRQ being raised and being handled, and there are races such that we cannot rely upon the exception entry being subsequent to the interrupt being raised. To fix this, we place an ISB between a read of IAR and the subsequent invocation of an IRQ handler.
When EOI mode 1 is in use, we need to EOI an interrupt prior to invoking its handler, and we have a write to EOIR for this. As this write to EOIR requires an ISB, and this is provided by the gic_write_eoir() helper, we omit the usual ISB in this case, with the logic being:
| if (static_branch_likely(&supports_deactivate_key)) | gic_write_eoir(irqnr); | else | isb();
This is somewhat opaque, and it would be a little clearer if there were an unconditional ISB, with only the write to EOIR being conditional, e.g.
| if (static_branch_likely(&supports_deactivate_key)) | write_gicreg(irqnr, ICC_EOIR1_EL1); | | isb();
This patch rewrites the code that way, with this logic factored into a new helper function with comments explaining what the ISB is for, as were originally laid out in commit:
39a06b67c2c1256b ("irqchip/gic: Ensure we have an ISB between ack and ->handle_irq")
Note that since then, we removed the IAR polling in commit:
342677d70ab92142 ("irqchip/gic-v3: Remove acknowledge loop")
... which removed one of the two race conditions.
For consistency, other portions of the driver are made to manipulate EOIR using write_gicreg() and explcit ISBs, and the gic_write_eoir() helper function is removed.
There should be no functional change as a result of this patch.
Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Marc Zyngier maz@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Will Deacon will.deacon@arm.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220513133038.226182-3-mark.rutland@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/include/asm/arch_gicv3.h | 7 +---- arch/arm64/include/asm/arch_gicv3.h | 6 ---- drivers/irqchip/irq-gic-v3.c | 43 ++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h index 413abfb42989..f82a819eb0db 100644 --- a/arch/arm/include/asm/arch_gicv3.h +++ b/arch/arm/include/asm/arch_gicv3.h @@ -48,6 +48,7 @@ static inline u32 read_ ## a64(void) \ return read_sysreg(a32); \ } \
+CPUIF_MAP(ICC_EOIR1, ICC_EOIR1_EL1) CPUIF_MAP(ICC_PMR, ICC_PMR_EL1) CPUIF_MAP(ICC_AP0R0, ICC_AP0R0_EL1) CPUIF_MAP(ICC_AP0R1, ICC_AP0R1_EL1) @@ -63,12 +64,6 @@ CPUIF_MAP(ICC_AP1R3, ICC_AP1R3_EL1)
/* Low-level accessors */
-static inline void gic_write_eoir(u32 irq) -{ - write_sysreg(irq, ICC_EOIR1); - isb(); -} - static inline void gic_write_dir(u32 val) { write_sysreg(val, ICC_DIR); diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 8bd5afc7b692..48d4473e8eee 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -26,12 +26,6 @@ * sets the GP register's most significant bits to 0 with an explicit cast. */
-static inline void gic_write_eoir(u32 irq) -{ - write_sysreg_s(irq, SYS_ICC_EOIR1_EL1); - isb(); -} - static __always_inline void gic_write_dir(u32 irq) { write_sysreg_s(irq, SYS_ICC_DIR_EL1); diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 7305d84f2df5..0cbc4e25c48d 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -556,7 +556,8 @@ static void gic_irq_nmi_teardown(struct irq_data *d)
static void gic_eoi_irq(struct irq_data *d) { - gic_write_eoir(gic_irq(d)); + write_gicreg(gic_irq(d), ICC_EOIR1_EL1); + isb(); }
static void gic_eoimode1_eoi_irq(struct irq_data *d) @@ -640,10 +641,38 @@ static void gic_deactivate_unhandled(u32 irqnr) if (irqnr < 8192) gic_write_dir(irqnr); } else { - gic_write_eoir(irqnr); + write_gicreg(irqnr, ICC_EOIR1_EL1); + isb(); } }
+/* + * Follow a read of the IAR with any HW maintenance that needs to happen prior + * to invoking the relevant IRQ handler. We must do two things: + * + * (1) Ensure instruction ordering between a read of IAR and subsequent + * instructions in the IRQ handler using an ISB. + * + * It is possible for the IAR to report an IRQ which was signalled *after* + * the CPU took an IRQ exception as multiple interrupts can race to be + * recognized by the GIC, earlier interrupts could be withdrawn, and/or + * later interrupts could be prioritized by the GIC. + * + * For devices which are tightly coupled to the CPU, such as PMUs, a + * context synchronization event is necessary to ensure that system + * register state is not stale, as these may have been indirectly written + * *after* exception entry. + * + * (2) Deactivate the interrupt when EOI mode 1 is in use. + */ +static inline void gic_complete_ack(u32 irqnr) +{ + if (static_branch_likely(&supports_deactivate_key)) + write_gicreg(irqnr, ICC_EOIR1_EL1); + + isb(); +} + static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) { bool irqs_enabled = interrupts_enabled(regs); @@ -652,10 +681,7 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) if (irqs_enabled) nmi_enter();
- if (static_branch_likely(&supports_deactivate_key)) - gic_write_eoir(irqnr); - else - isb() + gic_complete_ack(irqnr);
/* * Leave the PSR.I bit set to prevent other NMIs to be @@ -726,10 +752,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs gic_arch_enable_irqs(); }
- if (static_branch_likely(&supports_deactivate_key)) - gic_write_eoir(irqnr); - else - isb(); + gic_complete_ack(irqnr);
if (generic_handle_domain_irq(gic_data.domain, irqnr)) { WARN_ONCE(true, "Unexpected interrupt received!\n");
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit 614ab80c96474682157cabb14f8c8602b3422e90 ]
When a kernel is built with CONFIG_ARM64_PSEUDO_NMI=y and pseudo-NMIs are enabled at runtime, GICv3's gic_handle_irq() can leave DAIF and ICC_PMR_EL1 in an unexpected state in some cases, breaking subsequent usage of local_irq_enable() and resulting in softirqs being run with IRQs erroneously masked (possibly resulting in deadlocks).
This can happen when an IRQ exception is taken from a context where regular IRQs were unmasked, and either:
(1) ICC_IAR1_EL1 indicates a special INTID (e.g. as a result of an IRQ being withdrawn since the IRQ exception was taken).
(2) ICC_IAR1_EL1 and ICC_RPR_EL1 indicate an NMI was acknowledged.
When an NMI is taken from a context where regular IRQs were masked, there is no problem.
When CONFIG_ARM64_DEBUG_PRIORITY_MASKING=y, this can be detected with perf, e.g.
| # ./perf record -a -g -e cycles:k ls -alR / > /dev/null 2>&1 | ------------[ cut here ]------------ | WARNING: CPU: 0 PID: 14 at arch/arm64/include/asm/irqflags.h:32 arch_local_irq_enable+0x4c/0x6c | Modules linked in: | CPU: 0 PID: 14 Comm: ksoftirqd/0 Not tainted 5.18.0-rc5-00004-g876c38e3d20b #12 | Hardware name: linux,dummy-virt (DT) | pstate: 204000c5 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) | pc : arch_local_irq_enable+0x4c/0x6c | lr : __do_softirq+0x110/0x5d8 | sp : ffff8000080bbbc0 | pmr_save: 000000f0 | x29: ffff8000080bbbc0 x28: ffff316ac3a6ca40 x27: 0000000000000000 | x26: 0000000000000000 x25: ffffa04611c06008 x24: ffffa04611c06008 | x23: 0000000040400005 x22: 0000000000000200 x21: ffff8000080bbe20 | x20: ffffa0460fe10320 x19: 0000000000000009 x18: 0000000000000000 | x17: ffff91252dfa9000 x16: ffff800008004000 x15: 0000000000004000 | x14: 0000000000000028 x13: ffffa0460fe17578 x12: ffffa0460fed4294 | x11: ffffa0460fedc168 x10: ffffffffffffff80 x9 : ffffa0460fe10a70 | x8 : ffffa0460fedc168 x7 : 000000000000b762 x6 : 00000000057c3bdf | x5 : ffff8000080bbb18 x4 : 0000000000000000 x3 : 0000000000000001 | x2 : ffff91252dfa9000 x1 : 0000000000000060 x0 : 00000000000000f0 | Call trace: | arch_local_irq_enable+0x4c/0x6c | __irq_exit_rcu+0x180/0x1ac | irq_exit_rcu+0x1c/0x44 | el1_interrupt+0x4c/0xe4 | el1h_64_irq_handler+0x18/0x24 | el1h_64_irq+0x74/0x78 | smpboot_thread_fn+0x68/0x2c0 | kthread+0x124/0x130 | ret_from_fork+0x10/0x20 | irq event stamp: 193241 | hardirqs last enabled at (193240): [<ffffa0460fe10a9c>] __do_softirq+0x10c/0x5d8 | hardirqs last disabled at (193241): [<ffffa0461102ffe4>] el1_dbg+0x24/0x90 | softirqs last enabled at (193234): [<ffffa0460fe10e00>] __do_softirq+0x470/0x5d8 | softirqs last disabled at (193239): [<ffffa0460fea9944>] __irq_exit_rcu+0x180/0x1ac | ---[ end trace 0000000000000000 ]---
The necessary manipulation of DAIF and ICC_PMR_EL1 depends on the interrupted context, but the structure of gic_handle_irq() makes this also depend on whether the GIC reports an IRQ, NMI, or special INTID:
* When the interrupted context had regular IRQs masked (and hence the interrupt must be an NMI), the entry code performs the NMI entry/exit and gic_handle_irq() should return with DAIF and ICC_PMR_EL1 unchanged.
This is handled correctly today.
* When the interrupted context had regular IRQs unmasked, the entry code performs IRQ entry/exit, but expects gic_handle_irq() to always update ICC_PMR_EL1 and DAIF.IF to unmask NMIs (but not regular IRQs) prior to returning (which it must do prior to invoking any regular IRQ handler).
This unbalanced calling convention is necessary because we don't know whether an NMI has been taken until acknowledged by a read from ICC_IAR1_EL1, and so we need to perform the read with NMI masked in case an NMI has been taken (and needs to be handled with NMIs masked).
Unfortunately, this is not handled consistently:
- When ICC_IAR1_EL1 reports a special INTID, gic_handle_irq() returns immediately without manipulating ICC_PMR_EL1 and DAIF.
- When RPR_EL1 indicates an NMI, gic_handle_irq() calls gic_handle_nmi() to invoke the NMI handler, then returns without manipulating ICC_PMR_EL1 and DAIF.
- For regular IRQs, gic_handle_irq() manipulates ICC_PMR_EL1 and DAIF prior to invoking the IRQ handler.
There were related problems with special INTID handling in the past, where if an exception was taken from a context with regular IRQs masked and ICC_IAR_EL1 reported a special INTID, gic_handle_irq() would erroneously unmask NMIs in NMI context permitted an unexpected nested NMI. That case specifically was fixed by commit:
a97709f563a078e2 ("irqchip/gic-v3: Do not enable irqs when handling spurious interrups")
... but unfortunately that commit added an inverse problem, where if an exception was taken from a context with regular IRQs *unmasked* and ICC_IAR_EL1 reported a special INTID, gic_handle_irq() would erroneously fail to unmask NMIs (and consequently regular IRQs could not be unmasked during softirq processing). Before and after that commit, if an NMI was taken from a context with regular IRQs unmasked gic_handle_irq() would not unmask NMIs prior to returning, leading to the same problem with softirq handling.
This patch fixes this by restructuring gic_handle_irq(), splitting it into separate irqson/irqsoff helper functions which consistently perform the DAIF + ICC_PMR1_EL1 manipulation based upon the interrupted context, regardless of the event indicated by ICC_IAR1_EL1.
The special INTID handling is moved into the low-level IRQ/NMI handler invocation helper functions, so that early returns don't prevent the required manipulation of DAIF + ICC_PMR_EL1.
Fixes: f32c926651dcd168 ("irqchip/gic-v3: Handle pseudo-NMIs") Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Marc Zyngier maz@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220513133038.226182-4-mark.rutland@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-gic-v3.c | 147 +++++++++++++++++++++-------------- 1 file changed, 89 insertions(+), 58 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 0cbc4e25c48d..1af2b50f36f3 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -673,78 +673,69 @@ static inline void gic_complete_ack(u32 irqnr) isb(); }
-static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) +static bool gic_rpr_is_nmi_prio(void) { - bool irqs_enabled = interrupts_enabled(regs); - int err; + if (!gic_supports_nmi()) + return false;
- if (irqs_enabled) - nmi_enter(); + return unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI)); +} + +static bool gic_irqnr_is_special(u32 irqnr) +{ + return irqnr >= 1020 && irqnr <= 1023; +} + +static void __gic_handle_irq(u32 irqnr, struct pt_regs *regs) +{ + if (gic_irqnr_is_special(irqnr)) + return;
gic_complete_ack(irqnr);
- /* - * Leave the PSR.I bit set to prevent other NMIs to be - * received while handling this one. - * PSR.I will be restored when we ERET to the - * interrupted context. - */ - err = generic_handle_domain_nmi(gic_data.domain, irqnr); - if (err) + if (generic_handle_domain_irq(gic_data.domain, irqnr)) { + WARN_ONCE(true, "Unexpected interrupt (irqnr %u)\n", irqnr); gic_deactivate_unhandled(irqnr); - - if (irqs_enabled) - nmi_exit(); + } }
-static u32 do_read_iar(struct pt_regs *regs) +static void __gic_handle_nmi(u32 irqnr, struct pt_regs *regs) { - u32 iar; - - if (gic_supports_nmi() && unlikely(!interrupts_enabled(regs))) { - u64 pmr; - - /* - * We were in a context with IRQs disabled. However, the - * entry code has set PMR to a value that allows any - * interrupt to be acknowledged, and not just NMIs. This can - * lead to surprising effects if the NMI has been retired in - * the meantime, and that there is an IRQ pending. The IRQ - * would then be taken in NMI context, something that nobody - * wants to debug twice. - * - * Until we sort this, drop PMR again to a level that will - * actually only allow NMIs before reading IAR, and then - * restore it to what it was. - */ - pmr = gic_read_pmr(); - gic_pmr_mask_irqs(); - isb(); + if (gic_irqnr_is_special(irqnr)) + return;
- iar = gic_read_iar(); + gic_complete_ack(irqnr);
- gic_write_pmr(pmr); - } else { - iar = gic_read_iar(); + if (generic_handle_domain_nmi(gic_data.domain, irqnr)) { + WARN_ONCE(true, "Unexpected pseudo-NMI (irqnr %u)\n", irqnr); + gic_deactivate_unhandled(irqnr); } - - return iar; }
-static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) +/* + * An exception has been taken from a context with IRQs enabled, and this could + * be an IRQ or an NMI. + * + * The entry code called us with DAIF.IF set to keep NMIs masked. We must clear + * DAIF.IF (and update ICC_PMR_EL1 to mask regular IRQs) prior to returning, + * after handling any NMI but before handling any IRQ. + * + * The entry code has performed IRQ entry, and if an NMI is detected we must + * perform NMI entry/exit around invoking the handler. + */ +static void __gic_handle_irq_from_irqson(struct pt_regs *regs) { + bool is_nmi; u32 irqnr;
- irqnr = do_read_iar(regs); + irqnr = gic_read_iar();
- /* Check for special IDs first */ - if ((irqnr >= 1020 && irqnr <= 1023)) - return; + is_nmi = gic_rpr_is_nmi_prio();
- if (gic_supports_nmi() && - unlikely(gic_read_rpr() == GICD_INT_RPR_PRI(GICD_INT_NMI_PRI))) { - gic_handle_nmi(irqnr, regs); - return; + if (is_nmi) { + nmi_enter(); + __gic_handle_nmi(irqnr, regs); + nmi_exit(); }
if (gic_prio_masking_enabled()) { @@ -752,12 +743,52 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs gic_arch_enable_irqs(); }
- gic_complete_ack(irqnr); + if (!is_nmi) + __gic_handle_irq(irqnr, regs); +}
- if (generic_handle_domain_irq(gic_data.domain, irqnr)) { - WARN_ONCE(true, "Unexpected interrupt received!\n"); - gic_deactivate_unhandled(irqnr); - } +/* + * An exception has been taken from a context with IRQs disabled, which can only + * be an NMI. + * + * The entry code called us with DAIF.IF set to keep NMIs masked. We must leave + * DAIF.IF (and ICC_PMR_EL1) unchanged. + * + * The entry code has performed NMI entry. + */ +static void __gic_handle_irq_from_irqsoff(struct pt_regs *regs) +{ + u64 pmr; + u32 irqnr; + + /* + * We were in a context with IRQs disabled. However, the + * entry code has set PMR to a value that allows any + * interrupt to be acknowledged, and not just NMIs. This can + * lead to surprising effects if the NMI has been retired in + * the meantime, and that there is an IRQ pending. The IRQ + * would then be taken in NMI context, something that nobody + * wants to debug twice. + * + * Until we sort this, drop PMR again to a level that will + * actually only allow NMIs before reading IAR, and then + * restore it to what it was. + */ + pmr = gic_read_pmr(); + gic_pmr_mask_irqs(); + isb(); + irqnr = gic_read_iar(); + gic_write_pmr(pmr); + + __gic_handle_nmi(irqnr, regs); +} + +static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) +{ + if (unlikely(gic_supports_nmi() && !interrupts_enabled(regs))) + __gic_handle_irq_from_irqsoff(regs); + else + __gic_handle_irq_from_irqson(regs); }
static u32 gic_get_pribits(void)
From: Keith Busch kbusch@kernel.org
[ Upstream commit 52fde2c07da606f3f120af4f734eadcfb52b04be ]
The nvme specification only requires qword alignment for segment descriptors, and the driver already guarantees that. The spec has always allowed user data to be dword aligned, which is what the queue's attribute is for, so relax the alignment requirement to that value.
While we could allow byte alignment for some controllers when using SGLs, we still need to support PRP, and that only allows dword.
Fixes: 3b2a1ebceba3 ("nvme: set dma alignment to qword") Signed-off-by: Keith Busch kbusch@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ac32d1cd8477..2d6a01853109 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1771,7 +1771,7 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl, blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); } blk_queue_virt_boundary(q, NVME_CTRL_PAGE_SIZE - 1); - blk_queue_dma_alignment(q, 7); + blk_queue_dma_alignment(q, 3); blk_queue_write_cache(q, vwc, vwc); }
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit ed6bc6bf0a7d75e80eb1df883c09975ebb74e590 ]
If CONFIG_M54xx=y, CONFIG_MMU=y, and CONFIG_M68KFPU_EMU=y:
{standard input}:272: Error: invalid instruction for this architecture; needs 68000 or higher (68000 [68ec000, 68hc000, 68hc001, 68008, 68302, 68306, 68307, 68322, 68356], 68010, 68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060], cpu32 [68330, 68331, 68332, 68333, 68334, 68336, 68340, 68341, 68349, 68360], fidoa [fido]) -- statement `sub.b %d1,%d3' ignored {standard input}:609: Error: invalid instruction for this architecture; needs 68020 or higher (68020 [68k, 68ec020], 68030 [68ec030], 68040 [68ec040], 68060 [68ec060]) -- statement `bfextu 4(%a1){%d0,#8},%d0' ignored {standard input}:752: Error: operands mismatch -- statement `mulu.l 4(%a0),%d3:%d0' ignored {standard input}:1155: Error: operands mismatch -- statement `divu.l %d0,%d3:%d7' ignored
The math emulation support code is intended for 68020 and higher, and uses several instructions or instruction modes not available on coldfire or 68000.
Originally, the dependency of M68KFPU_EMU on MMU was fine, as MMU support was only available on 68020 or higher. But this assumption was broken by the introduction of MMU support for M547x and M548x.
Drop the dependency on MMU, as the code should work fine on 68020 and up without MMU (which are not yet supported by Linux, though). Add dependencies on M68KCLASSIC (to rule out Coldfire) and FPU (kernel has some type of floating-point support --- be it hardware or software emulated, to rule out anything below 68020).
Fixes: 1f7034b9616e6f14 ("m68k: allow ColdFire 547x and 548x CPUs to be built with MMU enabled") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Greg Ungerer gerg@linux-m68k.org Link: https://lore.kernel.org/r/18c34695b7c95107f60ccca82a4ff252f3edf477.165244611... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/m68k/Kconfig.cpu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 16ea9a67723c..3d5da25c73b5 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu @@ -327,7 +327,7 @@ comment "Processor Specific Options"
config M68KFPU_EMU bool "Math emulation support" - depends on MMU + depends on M68KCLASSIC && FPU help At some point in the future, this will cause floating-point math instructions to be emulated by the kernel on machines that lack a
From: Eric Dumazet edumazet@google.com
[ Upstream commit 4c971d2f3548e4f11b1460ac048f5307e4b39fdb ]
UDP sendmsg() is lockless, and reads sk->sk_bound_dev_if while this field can be changed by another thread.
Adds minimal annotations to avoid KCSAN splats for UDP. Following patches will add more annotations to potential lockless readers.
BUG: KCSAN: data-race in __ip6_datagram_connect / udpv6_sendmsg
write to 0xffff888136d47a94 of 4 bytes by task 7681 on cpu 0: __ip6_datagram_connect+0x6e2/0x930 net/ipv6/datagram.c:221 ip6_datagram_connect+0x2a/0x40 net/ipv6/datagram.c:272 inet_dgram_connect+0x107/0x190 net/ipv4/af_inet.c:576 __sys_connect_file net/socket.c:1900 [inline] __sys_connect+0x197/0x1b0 net/socket.c:1917 __do_sys_connect net/socket.c:1927 [inline] __se_sys_connect net/socket.c:1924 [inline] __x64_sys_connect+0x3d/0x50 net/socket.c:1924 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x2b/0x50 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
read to 0xffff888136d47a94 of 4 bytes by task 7670 on cpu 1: udpv6_sendmsg+0xc60/0x16e0 net/ipv6/udp.c:1436 inet6_sendmsg+0x5f/0x80 net/ipv6/af_inet6.c:652 sock_sendmsg_nosec net/socket.c:705 [inline] sock_sendmsg net/socket.c:725 [inline] ____sys_sendmsg+0x39a/0x510 net/socket.c:2413 ___sys_sendmsg net/socket.c:2467 [inline] __sys_sendmmsg+0x267/0x4c0 net/socket.c:2553 __do_sys_sendmmsg net/socket.c:2582 [inline] __se_sys_sendmmsg net/socket.c:2579 [inline] __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2579 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x2b/0x50 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
value changed: 0x00000000 -> 0xffffff9b
Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 7670 Comm: syz-executor.3 Tainted: G W 5.18.0-rc1-syzkaller-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
I chose to not add Fixes: tag because race has minor consequences and stable teams busy enough.
Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/ip.h | 2 +- include/net/sock.h | 5 +++-- net/ipv6/datagram.c | 6 +++--- net/ipv6/udp.c | 11 ++++++----- 4 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h index 0161137914cf..26fffda78cca 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -94,7 +94,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
ipcm->sockc.mark = inet->sk.sk_mark; ipcm->sockc.tsflags = inet->sk.sk_tsflags; - ipcm->oif = inet->sk.sk_bound_dev_if; + ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); ipcm->addr = inet->inet_saddr; }
diff --git a/include/net/sock.h b/include/net/sock.h index c4b91fc19b9c..3c4fb8f03fd9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2866,13 +2866,14 @@ static inline void sk_pacing_shift_update(struct sock *sk, int val) */ static inline bool sk_dev_equal_l3scope(struct sock *sk, int dif) { + int bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); int mdif;
- if (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif) + if (!bound_dev_if || bound_dev_if == dif) return true;
mdif = l3mdev_master_ifindex_by_index(sock_net(sk), dif); - if (mdif && mdif == sk->sk_bound_dev_if) + if (mdif && mdif == bound_dev_if) return true;
return false; diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 206f66310a88..0324e2685016 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -218,11 +218,11 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, err = -EINVAL; goto out; } - sk->sk_bound_dev_if = usin->sin6_scope_id; + WRITE_ONCE(sk->sk_bound_dev_if, usin->sin6_scope_id); }
if (!sk->sk_bound_dev_if && (addr_type & IPV6_ADDR_MULTICAST)) - sk->sk_bound_dev_if = np->mcast_oif; + WRITE_ONCE(sk->sk_bound_dev_if, np->mcast_oif);
/* Connect to link-local address requires an interface */ if (!sk->sk_bound_dev_if) { @@ -798,7 +798,7 @@ int ip6_datagram_send_ctl(struct net *net, struct sock *sk, if (src_idx) { if (fl6->flowi6_oif && src_idx != fl6->flowi6_oif && - (sk->sk_bound_dev_if != fl6->flowi6_oif || + (READ_ONCE(sk->sk_bound_dev_if) != fl6->flowi6_oif || !sk_dev_equal_l3scope(sk, src_idx))) return -EINVAL; fl6->flowi6_oif = src_idx; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 7f0fa9bd9ffe..a535c3f2e4af 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -105,7 +105,7 @@ static int compute_score(struct sock *sk, struct net *net, const struct in6_addr *daddr, unsigned short hnum, int dif, int sdif) { - int score; + int bound_dev_if, score; struct inet_sock *inet; bool dev_match;
@@ -132,10 +132,11 @@ static int compute_score(struct sock *sk, struct net *net, score++; }
- dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif); + bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + dev_match = udp_sk_bound_dev_eq(net, bound_dev_if, dif, sdif); if (!dev_match) return -1; - if (sk->sk_bound_dev_if) + if (bound_dev_if) score++;
if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) @@ -789,7 +790,7 @@ static bool __udp_v6_is_mcast_sock(struct net *net, struct sock *sk, (inet->inet_dport && inet->inet_dport != rmt_port) || (!ipv6_addr_any(&sk->sk_v6_daddr) && !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr)) || - !udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif) || + !udp_sk_bound_dev_eq(net, READ_ONCE(sk->sk_bound_dev_if), dif, sdif) || (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, loc_addr))) return false; @@ -1433,7 +1434,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) }
if (!fl6->flowi6_oif) - fl6->flowi6_oif = sk->sk_bound_dev_if; + fl6->flowi6_oif = READ_ONCE(sk->sk_bound_dev_if);
if (!fl6->flowi6_oif) fl6->flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
From: Eric Dumazet edumazet@google.com
[ Upstream commit a20ea298071f46effa3aaf965bf9bb34c901db3f ]
sctp_rcv() reads sk->sk_bound_dev_if twice while the socket is not locked. Another cpu could change this field under us.
Fixes: 0fd9a65a76e8 ("[SCTP] Support SO_BINDTODEVICE socket option on incoming packets.") Signed-off-by: Eric Dumazet edumazet@google.com Cc: Neil Horman nhorman@tuxdriver.com Cc: Vlad Yasevich vyasevich@gmail.com Cc: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Acked-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/sctp/input.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sctp/input.c b/net/sctp/input.c index 90e12bafdd48..4f43afa8678f 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -92,6 +92,7 @@ int sctp_rcv(struct sk_buff *skb) struct sctp_chunk *chunk; union sctp_addr src; union sctp_addr dest; + int bound_dev_if; int family; struct sctp_af *af; struct net *net = dev_net(skb->dev); @@ -169,7 +170,8 @@ int sctp_rcv(struct sk_buff *skb) * If a frame arrives on an interface and the receiving socket is * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB */ - if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) { + bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); + if (bound_dev_if && (bound_dev_if != af->skb_iif(skb))) { if (transport) { sctp_transport_put(transport); asoc = NULL;
From: Zheng Bin zhengbin13@huawei.com
[ Upstream commit 382d917bfc1e92339dae3c8a636b2730e8bb5132 ]
hinic_pf_to_mgmt_init misses destroy_workqueue in error path, this patch fixes that.
Fixes: 6dbb89014dc3 ("hinic: fix sending mailbox timeout in aeq event work") Signed-off-by: Zheng Bin zhengbin13@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c index ebc77771f5da..4aa1f433ed24 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c @@ -643,6 +643,7 @@ int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt, err = alloc_msg_buf(pf_to_mgmt); if (err) { dev_err(&pdev->dev, "Failed to allocate msg buffers\n"); + destroy_workqueue(pf_to_mgmt->workq); hinic_health_reporters_destroy(hwdev->devlink_dev); return err; } @@ -650,6 +651,7 @@ int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt, err = hinic_api_cmd_init(pf_to_mgmt->cmd_chain, hwif); if (err) { dev_err(&pdev->dev, "Failed to initialize cmd chains\n"); + destroy_workqueue(pf_to_mgmt->workq); hinic_health_reporters_destroy(hwdev->devlink_dev); return err; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit a34840c4eb3278a7c29c9c57a65ce7541c66f9f2 ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not needed anymore. Add missing of_node_put() to avoid refcount leak.
Fixes: 6748d0559059 ("ASoC: ti: Add custom machine driver for j721e EVM (CPB and IVI)") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220512111331.44774-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/ti/j721e-evm.c | 44 ++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/sound/soc/ti/j721e-evm.c b/sound/soc/ti/j721e-evm.c index 4077e15ec48b..6a969874c927 100644 --- a/sound/soc/ti/j721e-evm.c +++ b/sound/soc/ti/j721e-evm.c @@ -630,17 +630,18 @@ static int j721e_soc_probe_cpb(struct j721e_priv *priv, int *link_idx, codec_node = of_parse_phandle(node, "ti,cpb-codec", 0); if (!codec_node) { dev_err(priv->dev, "CPB codec node is not provided\n"); - return -EINVAL; + ret = -EINVAL; + goto put_dai_node; }
domain = &priv->audio_domains[J721E_AUDIO_DOMAIN_CPB]; ret = j721e_get_clocks(priv->dev, &domain->codec, "cpb-codec-scki"); if (ret) - return ret; + goto put_codec_node;
ret = j721e_get_clocks(priv->dev, &domain->mcasp, "cpb-mcasp-auxclk"); if (ret) - return ret; + goto put_codec_node;
/* * Common Processor Board, two links @@ -650,8 +651,10 @@ static int j721e_soc_probe_cpb(struct j721e_priv *priv, int *link_idx, comp_count = 6; compnent = devm_kzalloc(priv->dev, comp_count * sizeof(*compnent), GFP_KERNEL); - if (!compnent) - return -ENOMEM; + if (!compnent) { + ret = -ENOMEM; + goto put_codec_node; + }
comp_idx = 0; priv->dai_links[*link_idx].cpus = &compnent[comp_idx++]; @@ -702,6 +705,12 @@ static int j721e_soc_probe_cpb(struct j721e_priv *priv, int *link_idx, (*conf_idx)++;
return 0; + +put_codec_node: + of_node_put(codec_node); +put_dai_node: + of_node_put(dai_node); + return ret; }
static int j721e_soc_probe_ivi(struct j721e_priv *priv, int *link_idx, @@ -726,23 +735,25 @@ static int j721e_soc_probe_ivi(struct j721e_priv *priv, int *link_idx, codeca_node = of_parse_phandle(node, "ti,ivi-codec-a", 0); if (!codeca_node) { dev_err(priv->dev, "IVI codec-a node is not provided\n"); - return -EINVAL; + ret = -EINVAL; + goto put_dai_node; }
codecb_node = of_parse_phandle(node, "ti,ivi-codec-b", 0); if (!codecb_node) { dev_warn(priv->dev, "IVI codec-b node is not provided\n"); - return 0; + ret = 0; + goto put_codeca_node; }
domain = &priv->audio_domains[J721E_AUDIO_DOMAIN_IVI]; ret = j721e_get_clocks(priv->dev, &domain->codec, "ivi-codec-scki"); if (ret) - return ret; + goto put_codecb_node;
ret = j721e_get_clocks(priv->dev, &domain->mcasp, "ivi-mcasp-auxclk"); if (ret) - return ret; + goto put_codecb_node;
/* * IVI extension, two links @@ -754,8 +765,10 @@ static int j721e_soc_probe_ivi(struct j721e_priv *priv, int *link_idx, comp_count = 8; compnent = devm_kzalloc(priv->dev, comp_count * sizeof(*compnent), GFP_KERNEL); - if (!compnent) - return -ENOMEM; + if (!compnent) { + ret = -ENOMEM; + goto put_codecb_node; + }
comp_idx = 0; priv->dai_links[*link_idx].cpus = &compnent[comp_idx++]; @@ -816,6 +829,15 @@ static int j721e_soc_probe_ivi(struct j721e_priv *priv, int *link_idx, (*conf_idx)++;
return 0; + + +put_codecb_node: + of_node_put(codecb_node); +put_codeca_node: + of_node_put(codeca_node); +put_dai_node: + of_node_put(dai_node); + return ret; }
static int j721e_soc_probe(struct platform_device *pdev)
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit d7a49291d786b4400996afe3afcc3ef5eeb6f0ef ]
The "bti" selftests are built with -nostdlib, which apparently automatically creates a statically linked binary, which is what we want and need for BTI (to avoid interactions with the dynamic linker).
However this is not true when building a PIE binary, which some toolchains (Ubuntu) configure as the default. When compiling btitest with such a toolchain, it will create a dynamically linked binary, which will probably fail some tests, as the dynamic linker might not support BTI: =================== TAP version 13 1..18 not ok 1 nohint_func/call_using_br_x0 not ok 2 nohint_func/call_using_br_x16 not ok 3 nohint_func/call_using_blr .... ===================
To make sure we create static binaries, add an explicit -static on the linker command line. This forces static linking even if the toolchain defaults to PIE builds, and fixes btitest runs on BTI enabled machines.
Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Mark Brown broonie@kernel.org Fixes: 314bcbf09f14 ("kselftest: arm64: Add BTI tests") Link: https://lore.kernel.org/r/20220511172129.2078337-1-andre.przywara@arm.com Signed-off-by: Catalin Marinas catalin.marinas@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/arm64/bti/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/arm64/bti/Makefile b/tools/testing/selftests/arm64/bti/Makefile index 73e013c082a6..dafa1c2aa5c4 100644 --- a/tools/testing/selftests/arm64/bti/Makefile +++ b/tools/testing/selftests/arm64/bti/Makefile @@ -39,7 +39,7 @@ BTI_OBJS = \ teststubs-bti.o \ trampoline-bti.o gen/btitest: $(BTI_OBJS) - $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -o $@ $^ + $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -static -o $@ $^
NOBTI_OBJS = \ test-nobti.o \ @@ -50,7 +50,7 @@ NOBTI_OBJS = \ teststubs-nobti.o \ trampoline-nobti.o gen/nobtitest: $(NOBTI_OBJS) - $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -o $@ $^ + $(CC) $(CFLAGS_BTI) $(CFLAGS_COMMON) -nostdlib -static -o $@ $^
# Including KSFT lib.mk here will also mangle the TEST_GEN_PROGS list # to account for any OUTPUT target-dirs optionally provided by
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit 5bf19572e31375368f19edd2dbb2e0789518bb99 ]
In ov7670_probe, it always invokes ov7670_power_off() no matter the execution is successful or failed. So we cannot invoke it agiain in ov7670_remove().
Fix this by removing ov7670_power_off from ov7670_remove.
Fixes: 030f9f682e66 ("media: ov7670: control clock along with power") Signed-off-by: Dongliang Mu mudongliangabcd@gmail.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/ov7670.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 196746423116..1be2c0e5bdc1 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -2017,7 +2017,6 @@ static int ov7670_remove(struct i2c_client *client) v4l2_async_unregister_subdev(sd); v4l2_ctrl_handler_free(&info->hdl); media_entity_cleanup(&info->sd.entity); - ov7670_power_off(sd); return 0; }
From: Mike Pagano mpagano@gentoo.org
[ Upstream commit 8429b358975f11574f747ca8ef20d524d8247682 ]
Add V4L2_ASYNC as a dependency to match other drivers and prevent failures when compile testing.
Fixes: ff3cc65cadb5 ("media: v4l: async, fwnode: Improve module organisation") Signed-off-by: Mike Pagano mpagano@gentoo.org 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/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index fae2baabb773..2b20aa6c37b1 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -372,6 +372,7 @@ config VIDEO_OV13B10 config VIDEO_OV2640 tristate "OmniVision OV2640 sensor support" depends on VIDEO_DEV && I2C + select V4L2_ASYNC help This is a Video4Linux2 sensor driver for the OmniVision OV2640 camera.
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit a6dd5265c21c28d0a782befe41a97c347e78f22f ]
IS_ERR() and PTR_ERR() use wrong pointer, it should be sensor->dovdd, fix it.
Fixes: e43ccb0a045f ("media: i2c: Add support for the OV5648 image sensor") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.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/ov5648.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/ov5648.c b/drivers/media/i2c/ov5648.c index 930ff6897044..dfcd33e9ee13 100644 --- a/drivers/media/i2c/ov5648.c +++ b/drivers/media/i2c/ov5648.c @@ -2498,9 +2498,9 @@ static int ov5648_probe(struct i2c_client *client)
/* DOVDD: digital I/O */ sensor->dovdd = devm_regulator_get(dev, "dovdd"); - if (IS_ERR(sensor->dvdd)) { + if (IS_ERR(sensor->dovdd)) { dev_err(dev, "cannot get DOVDD (digital I/O) regulator\n"); - ret = PTR_ERR(sensor->dvdd); + ret = PTR_ERR(sensor->dovdd); goto error_endpoint; }
From: Nicolas Dufresne nicolas.dufresne@collabora.com
[ Upstream commit 9998943f6dfc5d5472bfab2e38527fb6ba5e9da7 ]
While this overclock hack seems to work on some implementations (some ChromeBooks, RockPi4) it also causes instability on other implementations (notably LibreComputer Renegade, but there were more reports in the LibreELEC project, where this has been removed). While performance is indeed affected (tested with GStreamer), 4K playback still works as long as you don't operate in lock step and keep at least 1 frame ahead of time in the decode queue.
After discussion with ChromeOS members, it would seem that their implementation indeed used to synchronously decode each frame, so this hack was simply compensating for their code being less efficient. In my opinion, this hack should not have been included upstream.
Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver") Signed-off-by: Nicolas Dufresne nicolas.dufresne@collabora.com Reviewed-by: Sebastian Fricke sebastian.fricke@collabora.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/rkvdec/rkvdec.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index c0cf3488f970..2df8cf4883e2 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -1027,12 +1027,6 @@ static int rkvdec_probe(struct platform_device *pdev) if (ret) return ret;
- /* - * Bump ACLK to max. possible freq. (500 MHz) to improve performance - * When 4k video playback. - */ - clk_set_rate(rkvdec->clocks[0].clk, 500 * 1000 * 1000); - rkvdec->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(rkvdec->regs)) return PTR_ERR(rkvdec->regs);
From: Nicolas Dufresne nicolas.dufresne@collabora.com
[ Upstream commit 7ab889f09dfa70e8097ec1b9186fd228124112cb ]
The ref builder only provided references that are marked as valid in the dpb. Thus the current implementation of dpb_valid would always set the flag to 1. This is not representing missing frames (this is called 'non-existing' pictures in the spec). In some context, these non-existing pictures still need to occupy a slot in the reference list according to the spec.
Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver") Signed-off-by: Nicolas Dufresne nicolas.dufresne@collabora.com Reviewed-by: Sebastian Fricke sebastian.fricke@collabora.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/rkvdec/rkvdec-h264.c | 33 ++++++++++++++++------ 1 file changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c index 951e19231da2..f5d8c6cb740b 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -112,6 +112,7 @@ struct rkvdec_h264_run { const struct v4l2_ctrl_h264_sps *sps; const struct v4l2_ctrl_h264_pps *pps; const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; + int ref_buf_idx[V4L2_H264_NUM_DPB_ENTRIES]; };
struct rkvdec_h264_ctx { @@ -725,6 +726,26 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx, } }
+static void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, + struct rkvdec_h264_run *run) +{ + const struct v4l2_ctrl_h264_decode_params *dec_params = run->decode_params; + u32 i; + + for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { + struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; + const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb; + struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; + int buf_idx = -1; + + if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) + buf_idx = vb2_find_timestamp(cap_q, + dpb[i].reference_ts, 0); + + run->ref_buf_idx[i] = buf_idx; + } +} + static void assemble_hw_rps(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run) { @@ -762,7 +783,7 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) { for (i = 0; i < h264_ctx->reflists.num_valid; i++) { - u8 dpb_valid = 0; + bool dpb_valid = run->ref_buf_idx[i] >= 0; u8 idx = 0;
switch (j) { @@ -779,8 +800,6 @@ static void assemble_hw_rps(struct rkvdec_ctx *ctx,
if (idx >= ARRAY_SIZE(dec_params->dpb)) continue; - dpb_valid = !!(dpb[idx].flags & - V4L2_H264_DPB_ENTRY_FLAG_ACTIVE);
set_ps_field(hw_rps, DPB_INFO(i, j), idx | dpb_valid << 4); @@ -859,13 +878,8 @@ get_ref_buf(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run, unsigned int dpb_idx) { struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; - const struct v4l2_h264_dpb_entry *dpb = run->decode_params->dpb; struct vb2_queue *cap_q = &m2m_ctx->cap_q_ctx.q; - int buf_idx = -1; - - if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) - buf_idx = vb2_find_timestamp(cap_q, - dpb[dpb_idx].reference_ts, 0); + int buf_idx = run->ref_buf_idx[dpb_idx];
/* * If a DPB entry is unused or invalid, address of current destination @@ -1102,6 +1116,7 @@ static int rkvdec_h264_run(struct rkvdec_ctx *ctx)
assemble_hw_scaling_list(ctx, &run); assemble_hw_pps(ctx, &run); + lookup_ref_buf_idx(ctx, &run); assemble_hw_rps(ctx, &run); config_registers(ctx, &run);
From: Jonas Karlman jonas@kwiboo.se
[ Upstream commit a074aa4760d1dad0bd565c0f66e7250f5f219ab0 ]
The luma and chroma bit depth fields in the pps packet are 3 bits wide. 8 is wrongly added to the bit depth values written to these 3 bit fields. Because only the 3 LSB are written, the hardware was configured correctly.
Correct this by not adding 8 to the luma and chroma bit depth value.
Fixes: cd33c830448ba ("media: rkvdec: Add the rkvdec driver") Signed-off-by: Jonas Karlman jonas@kwiboo.se Signed-off-by: Nicolas Dufresne nicolas.dufresne@collabora.com Reviewed-by: Ezequiel Garcia ezequiel@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/rkvdec/rkvdec-h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/rkvdec/rkvdec-h264.c b/drivers/staging/media/rkvdec/rkvdec-h264.c index f5d8c6cb740b..22b4bf9e9ef4 100644 --- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -662,8 +662,8 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx, WRITE_PPS(0xff, PROFILE_IDC); WRITE_PPS(1, CONSTRAINT_SET3_FLAG); WRITE_PPS(sps->chroma_format_idc, CHROMA_FORMAT_IDC); - WRITE_PPS(sps->bit_depth_luma_minus8 + 8, BIT_DEPTH_LUMA); - WRITE_PPS(sps->bit_depth_chroma_minus8 + 8, BIT_DEPTH_CHROMA); + WRITE_PPS(sps->bit_depth_luma_minus8, BIT_DEPTH_LUMA); + WRITE_PPS(sps->bit_depth_chroma_minus8, BIT_DEPTH_CHROMA); WRITE_PPS(0, QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG); WRITE_PPS(sps->log2_max_frame_num_minus4, LOG2_MAX_FRAME_NUM_MINUS4); WRITE_PPS(sps->max_num_ref_frames, MAX_NUM_REF_FRAMES);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 68d6c8476fd4f448e70e0ab31ff972838ac41dae ]
of_find_node_by_name() 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: 0fbeae70ee7c ("regulator: add SCMI driver") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220516074433.32433-1-linmq006@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/scmi-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c index 1f02f60ad136..41ae7ac27ff6 100644 --- a/drivers/regulator/scmi-regulator.c +++ b/drivers/regulator/scmi-regulator.c @@ -352,7 +352,7 @@ static int scmi_regulator_probe(struct scmi_device *sdev) return ret; } } - + of_node_put(np); /* * Register a regulator for each valid regulator-DT-entry that we * can successfully reach via SCMI and has a valid associated voltage
From: Wolfgang Bumiller w.bumiller@proxmox.com
[ Upstream commit 3607849df47822151b05df440759e2dc70160755 ]
With the removal of seq_get_buf in blkcg_print_one_stat, we cannot make adding the newline conditional on there being relevant stats because the name was already written out unconditionally. Otherwise we may end up with multiple device names in one line which is confusing and doesn't follow the nested-keyed file format.
Signed-off-by: Wolfgang Bumiller w.bumiller@proxmox.com Fixes: 252c651a4c85 ("blk-cgroup: stop using seq_get_buf") Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20220111083159.42340-1-w.bumiller@proxmox.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-cgroup.c | 9 ++------- block/blk-cgroup.h | 2 +- block/blk-iocost.c | 5 ++--- block/blk-iolatency.c | 8 +++----- 4 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 8dfe62786cd5..6f9aeb6a337d 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -905,7 +905,6 @@ static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s) { struct blkg_iostat_set *bis = &blkg->iostat; u64 rbytes, wbytes, rios, wios, dbytes, dios; - bool has_stats = false; const char *dname; unsigned seq; int i; @@ -931,14 +930,12 @@ static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s) } while (u64_stats_fetch_retry(&bis->sync, seq));
if (rbytes || wbytes || rios || wios) { - has_stats = true; seq_printf(s, "rbytes=%llu wbytes=%llu rios=%llu wios=%llu dbytes=%llu dios=%llu", rbytes, wbytes, rios, wios, dbytes, dios); }
if (blkcg_debug_stats && atomic_read(&blkg->use_delay)) { - has_stats = true; seq_printf(s, " use_delay=%d delay_nsec=%llu", atomic_read(&blkg->use_delay), atomic64_read(&blkg->delay_nsec)); @@ -950,12 +947,10 @@ static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s) if (!blkg->pd[i] || !pol->pd_stat_fn) continue;
- if (pol->pd_stat_fn(blkg->pd[i], s)) - has_stats = true; + pol->pd_stat_fn(blkg->pd[i], s); }
- if (has_stats) - seq_printf(s, "\n"); + seq_puts(s, "\n"); }
static int blkcg_print_stat(struct seq_file *sf, void *v) diff --git a/block/blk-cgroup.h b/block/blk-cgroup.h index 47e1e38390c9..b56ba16fb6c5 100644 --- a/block/blk-cgroup.h +++ b/block/blk-cgroup.h @@ -63,7 +63,7 @@ typedef void (blkcg_pol_online_pd_fn)(struct blkg_policy_data *pd); typedef void (blkcg_pol_offline_pd_fn)(struct blkg_policy_data *pd); typedef void (blkcg_pol_free_pd_fn)(struct blkg_policy_data *pd); typedef void (blkcg_pol_reset_pd_stats_fn)(struct blkg_policy_data *pd); -typedef bool (blkcg_pol_stat_pd_fn)(struct blkg_policy_data *pd, +typedef void (blkcg_pol_stat_pd_fn)(struct blkg_policy_data *pd, struct seq_file *s);
struct blkcg_policy { diff --git a/block/blk-iocost.c b/block/blk-iocost.c index 9bd670999d0a..16705fbd0699 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -3005,13 +3005,13 @@ static void ioc_pd_free(struct blkg_policy_data *pd) kfree(iocg); }
-static bool ioc_pd_stat(struct blkg_policy_data *pd, struct seq_file *s) +static void ioc_pd_stat(struct blkg_policy_data *pd, struct seq_file *s) { struct ioc_gq *iocg = pd_to_iocg(pd); struct ioc *ioc = iocg->ioc;
if (!ioc->enabled) - return false; + return;
if (iocg->level == 0) { unsigned vp10k = DIV64_U64_ROUND_CLOSEST( @@ -3027,7 +3027,6 @@ static bool ioc_pd_stat(struct blkg_policy_data *pd, struct seq_file *s) iocg->last_stat.wait_us, iocg->last_stat.indebt_us, iocg->last_stat.indelay_us); - return true; }
static u64 ioc_weight_prfill(struct seq_file *sf, struct blkg_policy_data *pd, diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index 2f33932e72e3..5b676c7cf2b6 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -891,7 +891,7 @@ static int iolatency_print_limit(struct seq_file *sf, void *v) return 0; }
-static bool iolatency_ssd_stat(struct iolatency_grp *iolat, struct seq_file *s) +static void iolatency_ssd_stat(struct iolatency_grp *iolat, struct seq_file *s) { struct latency_stat stat; int cpu; @@ -914,17 +914,16 @@ static bool iolatency_ssd_stat(struct iolatency_grp *iolat, struct seq_file *s) (unsigned long long)stat.ps.missed, (unsigned long long)stat.ps.total, iolat->rq_depth.max_depth); - return true; }
-static bool iolatency_pd_stat(struct blkg_policy_data *pd, struct seq_file *s) +static void iolatency_pd_stat(struct blkg_policy_data *pd, struct seq_file *s) { struct iolatency_grp *iolat = pd_to_lat(pd); unsigned long long avg_lat; unsigned long long cur_win;
if (!blkcg_debug_stats) - return false; + return;
if (iolat->ssd) return iolatency_ssd_stat(iolat, s); @@ -937,7 +936,6 @@ static bool iolatency_pd_stat(struct blkg_policy_data *pd, struct seq_file *s) else seq_printf(s, " depth=%u avg_lat=%llu win=%llu", iolat->rq_depth.max_depth, avg_lat, cur_win); - return true; }
static struct blkg_policy_data *iolatency_pd_alloc(gfp_t gfp,
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit dcbe6803fffd387f72b48c2373b5f5ed12a5804b ]
I got some KASAN report as below:
[ 46.959738] ================================================================== [ 46.960430] BUG: KASAN: use-after-free in z_erofs_shifted_transform+0x2bd/0x370 [ 46.960430] Read of size 4074 at addr ffff8880300c2f8e by task fssum/188 ... [ 46.960430] Call Trace: [ 46.960430] <TASK> [ 46.960430] dump_stack_lvl+0x41/0x5e [ 46.960430] print_report.cold+0xb2/0x6b7 [ 46.960430] ? z_erofs_shifted_transform+0x2bd/0x370 [ 46.960430] kasan_report+0x8a/0x140 [ 46.960430] ? z_erofs_shifted_transform+0x2bd/0x370 [ 46.960430] kasan_check_range+0x14d/0x1d0 [ 46.960430] memcpy+0x20/0x60 [ 46.960430] z_erofs_shifted_transform+0x2bd/0x370 [ 46.960430] z_erofs_decompress_pcluster+0xaae/0x1080
The root cause is that the tail pcluster won't be a complete filesystem block anymore. So if ztailpacking is used, the second part of an uncompressed tail pcluster may not be ``rq->pageofs_out``.
Fixes: ab749badf9f4 ("erofs: support unaligned data decompression") Fixes: cecf864d3d76 ("erofs: support inline data decompression") Reviewed-by: Yue Hu huyue2@coolpad.com Reviewed-by: Chao Yu chao@kernel.org Link: https://lore.kernel.org/r/20220512115833.24175-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 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index 3efa686c7644..0e0d1fc0f130 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -322,6 +322,7 @@ static int z_erofs_shifted_transform(struct z_erofs_decompress_req *rq, PAGE_ALIGN(rq->pageofs_out + rq->outputsize) >> PAGE_SHIFT; const unsigned int righthalf = min_t(unsigned int, rq->outputsize, PAGE_SIZE - rq->pageofs_out); + const unsigned int lefthalf = rq->outputsize - righthalf; unsigned char *src, *dst;
if (nrpages_out > 2) { @@ -344,10 +345,10 @@ static int z_erofs_shifted_transform(struct z_erofs_decompress_req *rq, if (nrpages_out == 2) { DBG_BUGON(!rq->out[1]); if (rq->out[1] == *rq->in) { - memmove(src, src + righthalf, rq->pageofs_out); + memmove(src, src + righthalf, lefthalf); } else { dst = kmap_atomic(rq->out[1]); - memcpy(dst, src + righthalf, rq->pageofs_out); + memcpy(dst, src + righthalf, lefthalf); kunmap_atomic(dst); } }
From: Moshe Tal moshet@nvidia.com
[ Upstream commit 6d0ba49321a40a8dada22c223bbe91c063b08db4 ]
Correct the calculation of maximum channels of rep to better utilize the hardware resources and allow a larger scale of reps.
This will allow creation of all virtual ports configured.
Fixes: 473baf2e9e8c ("net/mlx5e: Allow profile-specific limitation on max num of channels") Signed-off-by: Moshe Tal moshet@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 | 1 + drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 9 +++++++++ drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 10 ++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index 8653ac0fd865..ee34e861d3af 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -1221,6 +1221,7 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) MLX5_CAP_ETH(mdev, enhanced_multi_pkt_send_wqe); }
+int mlx5e_get_pf_num_tirs(struct mlx5_core_dev *mdev); int mlx5e_priv_init(struct mlx5e_priv *priv, const struct mlx5e_profile *profile, struct net_device *netdev, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index fa229998606c..72867a8ff48b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -5251,6 +5251,15 @@ mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev, return max_nch; }
+int mlx5e_get_pf_num_tirs(struct mlx5_core_dev *mdev) +{ + /* Indirect TIRS: 2 sets of TTCs (inner + outer steering) + * and 1 set of direct TIRS + */ + return 2 * MLX5E_NUM_INDIR_TIRS + + mlx5e_profile_max_num_channels(mdev, &mlx5e_nic_profile); +} + /* mlx5e generic netdev management API (move to en_common.c) */ int mlx5e_priv_init(struct mlx5e_priv *priv, const struct mlx5e_profile *profile, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 6b7e7ea6ded2..a464461f1418 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -604,10 +604,16 @@ bool mlx5e_eswitch_vf_rep(const struct net_device *netdev) return netdev->netdev_ops == &mlx5e_netdev_ops_rep; }
+/* One indirect TIR set for outer. Inner not supported in reps. */ +#define REP_NUM_INDIR_TIRS MLX5E_NUM_INDIR_TIRS + static int mlx5e_rep_max_nch_limit(struct mlx5_core_dev *mdev) { - return (1 << MLX5_CAP_GEN(mdev, log_max_tir)) / - mlx5_eswitch_get_total_vports(mdev); + int max_tir_num = 1 << MLX5_CAP_GEN(mdev, log_max_tir); + int num_vports = mlx5_eswitch_get_total_vports(mdev); + + return (max_tir_num - mlx5e_get_pf_num_tirs(mdev) + - (num_vports * REP_NUM_INDIR_TIRS)) / num_vports; }
static void mlx5e_build_rep_params(struct net_device *netdev)
From: Eric Biggers ebiggers@google.com
[ Upstream commit cb8435dc8ba33bcafa41cf2aa253794320a3b8df ]
The 'commit' option is only applicable for ext3 and ext4 filesystems, and has never been accepted by the ext2 filesystem driver, so the ext4 driver shouldn't allow it on ext2 filesystems.
This fixes a failure in xfstest ext4/053.
Fixes: 8dc0aa8cf0f7 ("ext4: check incompatible mount options while mounting ext2/3") Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Ritesh Harjani ritesh.list@gmail.com Reviewed-by: Lukas Czerner lczerner@redhat.com Link: https://lore.kernel.org/r/20220510183232.172615-1-ebiggers@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/super.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 1466fbdbc8e3..f1987c0690a4 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1913,6 +1913,7 @@ static const struct mount_opts { MOPT_EXT4_ONLY | MOPT_CLEAR}, {Opt_warn_on_error, EXT4_MOUNT_WARN_ON_ERROR, MOPT_SET}, {Opt_nowarn_on_error, EXT4_MOUNT_WARN_ON_ERROR, MOPT_CLEAR}, + {Opt_commit, 0, MOPT_NO_EXT2}, {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_EXT4_ONLY | MOPT_CLEAR}, {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM,
From: Douglas Anderson dianders@chromium.org
[ Upstream commit ec7981e6c614254937b37ce0af9eac09901c05c5 ]
Commit 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset time") caused sc7180 Chromebooks that use the parade-ps8640 bridge chip to fail to turn the display back on after it turns off.
Unfortunately, it doesn't look easy to fix the parade-ps8640 driver to handle the new power sequence. The Linux driver has almost nothing in it and most of the logic for this bridge chip is in black-box firmware that the bridge chip uses.
Also unfortunately, reverting the patch will break "tc358762".
The long term solution here is probably Dave Stevenson's series [1] that would give more flexibility. However, that is likely not a quick fix.
For the short term, we'll look at the compatible of the next bridge in the chain and go back to the old way for the Parade PS8640 bridge chip. If it's found that other bridge chips also need this workaround then we can add them to the list or consider inverting the condition. However, the hope is that the framework will not take too much longer to land and we won't have to add anything other than ps8640 here.
[1] https://lore.kernel.org/r/cover.1646406653.git.dave.stevenson@raspberrypi.co...
Fixes: 7d8e9a90509f ("drm/msm/dsi: move DSI host powerup to modeset time") Suggested-by: Rob Clark robdclark@gmail.com Signed-off-by: Douglas Anderson dianders@chromium.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Link: https://lore.kernel.org/r/20220513131504.v5.1.Ia196e35ad985059e77b038a41662f... Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/dsi_manager.c | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 1db93e562fe6..84f3b2ebf1b8 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -34,6 +34,32 @@ static struct msm_dsi_manager msm_dsim_glb; #define IS_SYNC_NEEDED() (msm_dsim_glb.is_sync_needed) #define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id)
+#ifdef CONFIG_OF +static bool dsi_mgr_power_on_early(struct drm_bridge *bridge) +{ + struct drm_bridge *next_bridge = drm_bridge_get_next_bridge(bridge); + + /* + * If the next bridge in the chain is the Parade ps8640 bridge chip + * then don't power on early since it seems to violate the expectations + * of the firmware that the bridge chip is running. + * + * NOTE: this is expected to be a temporary special case. It's expected + * that we'll eventually have a framework that allows the next level + * bridge to indicate whether it needs us to power on before it or + * after it. When that framework is in place then we'll use it and + * remove this special case. + */ + return !(next_bridge && next_bridge->of_node && + of_device_is_compatible(next_bridge->of_node, "parade,ps8640")); +} +#else +static inline bool dsi_mgr_power_on_early(struct drm_bridge *bridge) +{ + return true; +} +#endif + static inline struct msm_dsi *dsi_mgr_get_dsi(int id) { return msm_dsim_glb.dsi[id]; @@ -389,6 +415,9 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) return;
+ if (!dsi_mgr_power_on_early(bridge)) + dsi_mgr_bridge_power_on(bridge); + /* Always call panel functions once, because even for dual panels, * there is only one drm_panel instance. */ @@ -570,7 +599,8 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, if (is_bonded_dsi && other_dsi) msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
- dsi_mgr_bridge_power_on(bridge); + if (dsi_mgr_power_on_early(bridge)) + dsi_mgr_bridge_power_on(bridge); }
static const struct drm_connector_funcs dsi_mgr_connector_funcs = {
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit c56de483093d7ad0782327f95dda7da97bc4c315 ]
of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not need anymore.
a6xx_gmu_init() passes the node to of_find_device_by_node() and of_dma_configure(), of_find_device_by_node() will takes its reference, of_dma_configure() doesn't need the node after usage.
Add missing of_node_put() to avoid refcount leak.
Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Akhil P Oommen quic_akhilpo@quicinc.com Link: https://lore.kernel.org/r/20220512121955.56937-1-linmq006@gmail.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index ccc4fcf7a630..a8f6d73197b1 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1919,6 +1919,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) BUG_ON(!node);
ret = a6xx_gmu_init(a6xx_gpu, node); + of_node_put(node); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret);
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit 947a844bb3ebff0f4736d244d792ce129f6700d7 ]
drm_gem_object_lookup will call drm_gem_object_get inside. So cursor_bo needs to be put when msm_gem_get_and_pin_iova fails.
Fixes: e172d10a9c4a ("drm/msm/mdp5: Add hardware cursor support") Signed-off-by: Hangyu Hua hbh25y@gmail.com Link: https://lore.kernel.org/r/20220509061125.18585-1-hbh25y@gmail.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index fe2922c8d21b..31447da0af25 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -997,8 +997,10 @@ static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &mdp5_crtc->cursor.iova); - if (ret) + if (ret) { + drm_gem_object_put(cursor_bo); return -EINVAL; + }
pm_runtime_get_sync(&pdev->dev);
From: Lai Jiangshan jiangshan.ljs@antgroup.com
[ Upstream commit c42b145181aafd59ed31ccd879493389e3ea5a08 ]
In idtentry_vc(), vc_switch_off_ist() determines a safe stack to switch to, off of the IST stack. Annotate the new stack switch with ENCODE_FRAME_POINTER in case UNWINDER_FRAME_POINTER is used.
A stack walk before looks like this:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc7+ #2 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 Call Trace: <TASK> dump_stack_lvl dump_stack kernel_exc_vmm_communication asm_exc_vmm_communication ? native_read_msr ? __x2apic_disable.part.0 ? x2apic_setup ? cpu_init ? trap_init ? start_kernel ? x86_64_start_reservations ? x86_64_start_kernel ? secondary_startup_64_no_verify </TASK>
and with the fix, the stack dump is exact:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc7+ #3 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 Call Trace: <TASK> dump_stack_lvl dump_stack kernel_exc_vmm_communication asm_exc_vmm_communication RIP: 0010:native_read_msr Code: ... < snipped regs > ? __x2apic_disable.part.0 x2apic_setup cpu_init trap_init start_kernel x86_64_start_reservations x86_64_start_kernel secondary_startup_64_no_verify </TASK>
[ bp: Test in a SEV-ES guest and rewrite the commit message to explain what exactly this does. ]
Fixes: a13644f3a53d ("x86/entry/64: Add entry code for #VC handler") Signed-off-by: Lai Jiangshan jiangshan.ljs@antgroup.com Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Josh Poimboeuf jpoimboe@redhat.com Link: https://lore.kernel.org/r/20220316041612.71357-1-jiangshanlai@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/entry/entry_64.S | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 73d958522b6a..d8376e5fe1af 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -508,6 +508,7 @@ SYM_CODE_START(\asmsym) call vc_switch_off_ist movq %rax, %rsp /* Switch to new stack */
+ ENCODE_FRAME_POINTER UNWIND_HINT_REGS
/* Update pt_regs */
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 577e2a9dfc8fba7938aaf75db63fae7e328cc3cb ]
As msm_drm_uninit() is called from the msm_drm_init() error path, additional care should be necessary as not to call the free_irq() for the IRQ that was not requested before (because an error occured earlier than the request_irq() call).
This fixed the issue reported with the following backtrace:
[ 8.571329] Trying to free already-free IRQ 187 [ 8.571339] WARNING: CPU: 0 PID: 76 at kernel/irq/manage.c:1895 free_irq+0x1e0/0x35c [ 8.588746] Modules linked in: pmic_glink pdr_interface fastrpc qrtr_smd snd_soc_hdmi_codec msm fsa4480 gpu_sched drm_dp_aux_bus qrtr i2c_qcom_geni crct10dif_ce qcom_stats qcom_q6v5_pas drm_display_helper gpi qcom_pil_info drm_kms_helper qcom_q6v5 qcom_sysmon qcom_common qcom_glink_smem qcom_rng mdt_loader qmi_helpers phy_qcom_qmp ufs_qcom typec qnoc_sm8350 socinfo rmtfs_mem fuse drm ipv6 [ 8.624154] CPU: 0 PID: 76 Comm: kworker/u16:2 Not tainted 5.18.0-rc5-next-20220506-00033-g6cee8cab6089-dirty #419 [ 8.624161] Hardware name: Qualcomm Technologies, Inc. SM8350 HDK (DT) [ 8.641496] Workqueue: events_unbound deferred_probe_work_func [ 8.647510] pstate: 604000c5 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 8.654681] pc : free_irq+0x1e0/0x35c [ 8.658454] lr : free_irq+0x1e0/0x35c [ 8.662228] sp : ffff800008ab3950 [ 8.665642] x29: ffff800008ab3950 x28: 0000000000000000 x27: ffff16350f56a700 [ 8.672994] x26: ffff1635025df080 x25: ffff16350251badc x24: ffff16350251bb90 [ 8.680343] x23: 0000000000000000 x22: 00000000000000bb x21: ffff16350e8f9800 [ 8.687690] x20: ffff16350251ba00 x19: ffff16350cbd5880 x18: ffffffffffffffff [ 8.695039] x17: 0000000000000000 x16: ffffa2dd12179434 x15: ffffa2dd1431d02d [ 8.702391] x14: 0000000000000000 x13: ffffa2dd1431d028 x12: 662d79646165726c [ 8.709740] x11: ffffa2dd13fd2438 x10: 000000000000000a x9 : 00000000000000bb [ 8.717111] x8 : ffffa2dd13fd23f0 x7 : ffff800008ab3750 x6 : 00000000fffff202 [ 8.724487] x5 : ffff16377e870a18 x4 : 00000000fffff202 x3 : ffff735a6ae1b000 [ 8.731851] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff1635015f8000 [ 8.739217] Call trace: [ 8.741755] free_irq+0x1e0/0x35c [ 8.745198] msm_drm_uninit.isra.0+0x14c/0x294 [msm] [ 8.750548] msm_drm_bind+0x28c/0x5d0 [msm] [ 8.755081] try_to_bring_up_aggregate_device+0x164/0x1d0 [ 8.760657] __component_add+0xa0/0x170 [ 8.764626] component_add+0x14/0x20 [ 8.768337] dp_display_probe+0x2a4/0x464 [msm] [ 8.773242] platform_probe+0x68/0xe0 [ 8.777043] really_probe.part.0+0x9c/0x28c [ 8.781368] __driver_probe_device+0x98/0x144 [ 8.785871] driver_probe_device+0x40/0x140 [ 8.790191] __device_attach_driver+0xb4/0x120 [ 8.794788] bus_for_each_drv+0x78/0xd0 [ 8.798751] __device_attach+0xdc/0x184 [ 8.802713] device_initial_probe+0x14/0x20 [ 8.807031] bus_probe_device+0x9c/0xa4 [ 8.810991] deferred_probe_work_func+0x88/0xc0 [ 8.815667] process_one_work+0x1d0/0x320 [ 8.819809] worker_thread+0x14c/0x444 [ 8.823688] kthread+0x10c/0x110 [ 8.827036] ret_from_fork+0x10/0x20
Reported-by: Bjorn Andersson bjorn.andersson@linaro.org Fixes: f026e431cf86 ("drm/msm: Convert to Linux IRQ interfaces") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/485422/ Link: https://lore.kernel.org/r/20220507010021.1667700-1-dmitry.baryshkov@linaro.o... Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_drv.c | 7 ++++++- drivers/gpu/drm/msm/msm_kms.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index e3d83963ad54..f2c46116df55 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -113,6 +113,8 @@ static int msm_irq_postinstall(struct drm_device *dev)
static int msm_irq_install(struct drm_device *dev, unsigned int irq) { + struct msm_drm_private *priv = dev->dev_private; + struct msm_kms *kms = priv->kms; int ret;
if (irq == IRQ_NOTCONNECTED) @@ -124,6 +126,8 @@ static int msm_irq_install(struct drm_device *dev, unsigned int irq) if (ret) return ret;
+ kms->irq_requested = true; + ret = msm_irq_postinstall(dev); if (ret) { free_irq(irq, dev); @@ -139,7 +143,8 @@ static void msm_irq_uninstall(struct drm_device *dev) struct msm_kms *kms = priv->kms;
kms->funcs->irq_uninstall(kms); - free_irq(kms->irq, dev); + if (kms->irq_requested) + free_irq(kms->irq, dev); }
struct msm_vblank_work { diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 2a4f0526cb98..401d7e19811f 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h @@ -148,6 +148,7 @@ struct msm_kms {
/* irq number to be passed on to msm_irq_install */ int irq; + bool irq_requested;
/* mapper-id used to request GEM buffer mapped for scanout: */ struct msm_gem_address_space *aspace;
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 70a1b25326dd77e145157ccf1a31c1948032eec4 ]
When build bpf test and install it to another folder, e.g.
make -j10 install -C tools/testing/selftests/ TARGETS="bpf" \ SKIP_TARGETS="" INSTALL_PATH=/tmp/kselftests
The ima_setup.sh is missed in target folder, which makes test_ima failed.
Fix it by adding ima_setup.sh to TEST_PROGS_EXTENDED.
Fixes: 34b82d3ac105 ("bpf: Add a selftest for bpf_ima_inode_hash") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20220516040020.653291-1-liuhangbin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index a15c47d2fa73..6e2383701ce0 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -75,7 +75,7 @@ TEST_PROGS := test_kmod.sh \ test_xsk.sh
TEST_PROGS_EXTENDED := with_addr.sh \ - with_tunnels.sh \ + with_tunnels.sh ima_setup.sh \ test_xdp_vlan.sh test_bpftool.py
# Compile but not part of 'make run_tests'
From: Abhinav Kumar quic_abhinavk@quicinc.com
[ Upstream commit 64b22a0da12adb571c01edd671ee43634ebd7e41 ]
If there are errors while trying to enable the pm in the bind path, it will lead to unclocked access of hw revision register thereby crashing the device.
This will not address why the pm_runtime_get_sync() fails but at the very least we should be able to prevent the crash by handling the error and bailing out earlier.
changes in v2: - use pm_runtime_resume_and_get() instead of pm_runtime_get_sync()
Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Reviewed-by: Rob Clark robdclark@gmail.com Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/486721/ Link: https://lore.kernel.org/r/20220518223407.26147-1-quic_abhinavk@quicinc.com Signed-off-by: Abhinav Kumar quic_abhinavk@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ad13a9423601..c8089678f733 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1058,7 +1058,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
dpu_kms_parse_data_bus_icc_path(dpu_kms);
- pm_runtime_get_sync(&dpu_kms->pdev->dev); + rc = pm_runtime_resume_and_get(&dpu_kms->pdev->dev); + if (rc < 0) + goto error;
dpu_kms->core_rev = readl_relaxed(dpu_kms->mmio + 0x0);
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 58606220a2f1407a7516c547f09a1ba7b4350a73 ]
When an attribute group is created with sysfs_create_group(), the ->sysfs_ops() callback is set to kobj_sysfs_ops, which sets the ->show() callback to kobj_attr_show(). kobj_attr_show() uses container_of() to get the ->show() callback from the attribute it was passed, meaning the ->show() callback needs to be the same type as the ->show() callback in 'struct kobj_attribute'.
However, show_dynamic_id() has the type of the ->show() callback in 'struct device_attribute', which causes a CFI violation when opening the 'id' sysfs node under drm/card0/metrics. This happens to work because the layout of 'struct kobj_attribute' and 'struct device_attribute' are the same, so the container_of() cast happens to allow the ->show() callback to still work.
Change the type of show_dynamic_id() to match the ->show() callback in 'struct kobj_attributes' and update the type of sysfs_metric_id to match, which resolves the CFI violation.
Fixes: f89823c21224 ("drm/i915/perf: Implement I915_PERF_ADD/REMOVE_CONFIG interface") Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Kees Cook keescook@chromium.org Reviewed-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20220513075136.1027007-1-tvrtk... (cherry picked from commit 18fb42db05a0b93ab5dd5eab5315e50eaa3ca620) Signed-off-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/i915_perf.c | 4 ++-- drivers/gpu/drm/i915/i915_perf_types.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 0a9c3fcc09b1..1577ab6754db 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -4050,8 +4050,8 @@ static struct i915_oa_reg *alloc_oa_regs(struct i915_perf *perf, return ERR_PTR(err); }
-static ssize_t show_dynamic_id(struct device *dev, - struct device_attribute *attr, +static ssize_t show_dynamic_id(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) { struct i915_oa_config *oa_config = diff --git a/drivers/gpu/drm/i915/i915_perf_types.h b/drivers/gpu/drm/i915/i915_perf_types.h index 473a3c0544bb..05cb9a335a97 100644 --- a/drivers/gpu/drm/i915/i915_perf_types.h +++ b/drivers/gpu/drm/i915/i915_perf_types.h @@ -55,7 +55,7 @@ struct i915_oa_config {
struct attribute_group sysfs_metric; struct attribute *attrs[2]; - struct device_attribute sysfs_metric_id; + struct kobj_attribute sysfs_metric_id;
struct kref ref; struct rcu_head rcu;
From: Stefan Wahren stefan.wahren@i2se.com
[ Upstream commit 106e0121e243de4da7d634338089a68a8da2abe9 ]
The thermal sensor on BCM2711 is capable of negative temperatures, so don't clamp the measurements at zero. Since this was the only use for variable t, drop it.
This change based on a patch by Dom Cobley, who also tested the fix.
Fixes: 59b781352dc4 ("thermal: Add BCM2711 thermal driver") Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Acked-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/20220412195423.104511-1-stefan.wahren@i2se.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/broadcom/bcm2711_thermal.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/thermal/broadcom/bcm2711_thermal.c b/drivers/thermal/broadcom/bcm2711_thermal.c index 1ec57d9ecf53..e9bef5c3414b 100644 --- a/drivers/thermal/broadcom/bcm2711_thermal.c +++ b/drivers/thermal/broadcom/bcm2711_thermal.c @@ -38,7 +38,6 @@ static int bcm2711_get_temp(void *data, int *temp) int offset = thermal_zone_get_offset(priv->thermal); u32 val; int ret; - long t;
ret = regmap_read(priv->regmap, AVS_RO_TEMP_STATUS, &val); if (ret) @@ -50,9 +49,7 @@ static int bcm2711_get_temp(void *data, int *temp) val &= AVS_RO_TEMP_STATUS_DATA_MSK;
/* Convert a HW code to a temperature reading (millidegree celsius) */ - t = slope * val + offset; - - *temp = t < 0 ? 0 : t; + *temp = slope * val + offset;
return 0; }
From: Zheng Yongjun zhengyongjun3@huawei.com
[ Upstream commit e20d136ec7d6f309989c447638365840d3424c8e ]
platform_get_resource() may return NULL, add proper check to avoid potential NULL dereferencing.
Fixes: 250e211057c72 ("thermal: broadcom: Add Stingray thermal driver") Signed-off-by: Zheng Yongjun zhengyongjun3@huawei.com Link: https://lore.kernel.org/r/20220425092929.90412-1-zhengyongjun3@huawei.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/broadcom/sr-thermal.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/thermal/broadcom/sr-thermal.c b/drivers/thermal/broadcom/sr-thermal.c index 475ce2900771..85ab9edd580c 100644 --- a/drivers/thermal/broadcom/sr-thermal.c +++ b/drivers/thermal/broadcom/sr-thermal.c @@ -60,6 +60,9 @@ static int sr_thermal_probe(struct platform_device *pdev) return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + sr_thermal->regs = (void __iomem *)devm_memremap(&pdev->dev, res->start, resource_size(res), MEMREMAP_WB);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 98a160e898c0f4a979af9de3ab48b4b1d42d1dbb ]
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff888010080000 (size 264312): comm "182", pid 102533, jiffies 4296434960 (age 10.100s) hex dump (first 32 bytes): 00 00 00 00 ad 4e ad de ff ff ff ff 00 00 00 00 .....N.......... ff ff ff ff ff ff ff ff 40 7f 1f b9 ff ff ff ff ........@....... backtrace: [<0000000038b2f4fc>] kmalloc_order_trace+0x1d/0x110 mm/slab_common.c:969 [<00000000ebcb8da5>] __kmalloc+0x373/0x420 include/linux/slab.h:510 [<0000000084137f13>] thermal_cooling_device_setup_sysfs+0x15d/0x2d0 include/linux/slab.h:586 [<00000000352b8755>] __thermal_cooling_device_register+0x332/0xa60 drivers/thermal/thermal_core.c:927 [<00000000fb9f331b>] devm_thermal_of_cooling_device_register+0x6b/0xf0 drivers/thermal/thermal_core.c:1041 [<000000009b8012d2>] max6650_probe.cold+0x557/0x6aa drivers/hwmon/max6650.c:211 [<00000000da0b7e04>] i2c_device_probe+0x472/0xac0 drivers/i2c/i2c-core-base.c:561
If device_register() fails, thermal_cooling_device_destroy_sysfs() need be called to free the memory allocated in thermal_cooling_device_setup_sysfs().
Fixes: 8ea229511e06 ("thermal: Add cooling device's statistics in sysfs") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20220511020605.3096734-1-yangyingliang@huawei.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/thermal_core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 82654dc8382b..cdc0552e8c42 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -947,6 +947,7 @@ __thermal_cooling_device_register(struct device_node *np, return cdev;
out_kfree_type: + thermal_cooling_device_destroy_sysfs(cdev); kfree(cdev->type); put_device(&cdev->device); cdev = NULL;
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 09700c504d8e63faffd2a2235074e8c5d130cb8f ]
of_find_node_by_name() 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: e20db70dba1c ("thermal: imx_sc: add i.MX system controller thermal support") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220517055121.18092-1-linmq006@gmail.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/imx_sc_thermal.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/imx_sc_thermal.c b/drivers/thermal/imx_sc_thermal.c index 8d76dbfde6a9..331a241eb0ef 100644 --- a/drivers/thermal/imx_sc_thermal.c +++ b/drivers/thermal/imx_sc_thermal.c @@ -94,8 +94,8 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL); if (!sensor) { of_node_put(child); - of_node_put(sensor_np); - return -ENOMEM; + ret = -ENOMEM; + goto put_node; }
ret = thermal_zone_of_get_sensor_id(child, @@ -124,7 +124,9 @@ static int imx_sc_thermal_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "failed to add hwmon sysfs attributes\n"); }
+put_node: of_node_put(sensor_np); + of_node_put(np);
return ret; }
From: Jan Kara jack@suse.cz
[ Upstream commit f950667356ce90a41b446b726d4595a10cb65415 ]
Currently we look for waker only if current queue has no requests. This makes sense for bfq queues with a single process however for shared queues when there is a larger number of processes the condition that queue has no requests is difficult to meet because often at least one process has some request in flight although all the others are waiting for the waker to do the work and this harms throughput. Relax the "no queued request for bfq queue" condition to "the current task has no queued requests yet". For this, we also need to start tracking number of requests in flight for each task.
This patch (together with the following one) restores the performance for dbench with 128 clients that regressed with commit c65e6fd460b4 ("bfq: Do not let waker requests skip proper accounting") because this commit makes requests of wakers properly enter BFQ queues and thus these queues become ineligible for the old waker detection logic. Dbench results:
Vanilla 5.18-rc3 5.18-rc3 + revert 5.18-rc3 patched Mean 1237.36 ( 0.00%) 950.16 * 23.21%* 988.35 * 20.12%*
Numbers are time to complete workload so lower is better.
Fixes: c65e6fd460b4 ("bfq: Do not let waker requests skip proper accounting") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220519105235.31397-1-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bfq-iosched.c | 5 +++-- block/bfq-iosched.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 1f62dbdc521f..e1c86f66400e 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2133,7 +2133,6 @@ static void bfq_check_waker(struct bfq_data *bfqd, struct bfq_queue *bfqq, if (!bfqd->last_completed_rq_bfqq || bfqd->last_completed_rq_bfqq == bfqq || bfq_bfqq_has_short_ttime(bfqq) || - bfqq->dispatched > 0 || now_ns - bfqd->last_completion >= 4 * NSEC_PER_MSEC || bfqd->last_completed_rq_bfqq == bfqq->waker_bfqq) return; @@ -2210,7 +2209,7 @@ static void bfq_add_request(struct request *rq) bfqq->queued[rq_is_sync(rq)]++; bfqd->queued++;
- if (RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_sync(bfqq)) { + if (bfq_bfqq_sync(bfqq) && RQ_BIC(rq)->requests <= 1) { bfq_check_waker(bfqd, bfqq, now_ns);
/* @@ -6563,6 +6562,7 @@ static void bfq_finish_requeue_request(struct request *rq) bfq_completed_request(bfqq, bfqd); } bfq_finish_requeue_request_body(bfqq); + RQ_BIC(rq)->requests--; spin_unlock_irqrestore(&bfqd->lock, flags);
/* @@ -6796,6 +6796,7 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
bfqq_request_allocated(bfqq); bfqq->ref++; + bic->requests++; bfq_log_bfqq(bfqd, bfqq, "get_request %p: bfqq %p, %d", rq, bfqq, bfqq->ref);
diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h index 3b83e3d1c2e5..25fada961bc9 100644 --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -468,6 +468,7 @@ struct bfq_io_cq { struct bfq_queue *stable_merge_bfqq;
bool stably_merged; /* non splittable if true */ + unsigned int requests; /* Number of requests this process has in flight */ };
/**
From: Jan Kara jack@suse.cz
[ Upstream commit c5ac56bb6110e42e79d3106866658376b2e48ab9 ]
The code in bfq_check_waker() ignores wake up events from the current waker. This makes it more likely we select a new tentative waker although the current one is generating more wake up events. Treat current waker the same way as any other process and allow it to reset the waker detection logic.
Fixes: 71217df39dc6 ("block, bfq: make waker-queue detection more robust") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220519105235.31397-2-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bfq-iosched.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index e1c86f66400e..269ff82091cc 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2133,8 +2133,7 @@ static void bfq_check_waker(struct bfq_data *bfqd, struct bfq_queue *bfqq, if (!bfqd->last_completed_rq_bfqq || bfqd->last_completed_rq_bfqq == bfqq || bfq_bfqq_has_short_ttime(bfqq) || - now_ns - bfqd->last_completion >= 4 * NSEC_PER_MSEC || - bfqd->last_completed_rq_bfqq == bfqq->waker_bfqq) + now_ns - bfqd->last_completion >= 4 * NSEC_PER_MSEC) return;
/*
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 81e7b165c45e94188ae8f1134b57f27d1f35452f ]
sound/soc/codecs/lpass-macro-common.c:28 lpass_macro_pds_init() warn: passing zero to 'PTR_ERR' sound/soc/codecs/lpass-macro-common.c:38 lpass_macro_pds_init() warn: passing zero to 'PTR_ERR' sound/soc/codecs/lpass-macro-common.c:54 lpass_macro_pds_init() warn: passing zero to 'ERR_PTR'
dev_pm_domain_attach_by_name() may return NULL, set 'ret' as -ENODATA to fix this warning.
Fixes: 1a8ee4cf8418 ("ASoC: codecs: Fix error handling in power domain init and exit handlers") Signed-off-by: YueHaibing yuehaibing@huawei.com Link: https://lore.kernel.org/r/20220516120909.36356-1-yuehaibing@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/lpass-macro-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/lpass-macro-common.c b/sound/soc/codecs/lpass-macro-common.c index 3c661fd61173..1b9082d237c1 100644 --- a/sound/soc/codecs/lpass-macro-common.c +++ b/sound/soc/codecs/lpass-macro-common.c @@ -25,7 +25,7 @@ struct lpass_macro *lpass_macro_pds_init(struct device *dev)
l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro"); if (IS_ERR_OR_NULL(l_pds->macro_pd)) { - ret = PTR_ERR(l_pds->macro_pd); + ret = l_pds->macro_pd ? PTR_ERR(l_pds->macro_pd) : -ENODATA; goto macro_err; }
@@ -35,7 +35,7 @@ struct lpass_macro *lpass_macro_pds_init(struct device *dev)
l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec"); if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) { - ret = PTR_ERR(l_pds->dcodec_pd); + ret = l_pds->dcodec_pd ? PTR_ERR(l_pds->dcodec_pd) : -ENODATA; goto dcodec_err; }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit be2af740e2a9c7134f2d8ab4f104006e110b13de ]
Fix the missing clk_disable_unprepare() before return from wm2000_anc_transition() in the error handling case.
Fixes: 514cfd6dd725 ("ASoC: wm2000: Integrate with clock API") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Acked-by: Charles Keepax ckeepax@opensource.cirrus.com Link: https://lore.kernel.org/r/20220514091053.686416-1-yangyingliang@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wm2000.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 72e165cc6443..97ece3114b3d 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -536,7 +536,7 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, { struct i2c_client *i2c = wm2000->i2c; int i, j; - int ret; + int ret = 0;
if (wm2000->anc_mode == mode) return 0; @@ -566,13 +566,13 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000, ret = anc_transitions[i].step[j](i2c, anc_transitions[i].analogue); if (ret != 0) - return ret; + break; }
if (anc_transitions[i].dest == ANC_OFF) clk_disable_unprepare(wm2000->mclk);
- return 0; + return ret; }
static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
From: Ulf Hansson ulf.hansson@linaro.org
[ Upstream commit 34be27517cb763ea367da21e3cdee5d1bc40f47f ]
While factoring out the PM domain related code from PSCI domain driver into a set of library functions, a regression when initializing the genpds got introduced. More precisely, we fail to assign a genpd governor, so let's fix this.
Fixes: 9d976d6721df ("cpuidle: Factor-out power domain related code from PSCI domain driver") Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Reviewed-by: Anup Patel anup@brainfault.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle-psci-domain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index 755bbdfc5b82..3db4fca1172b 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c @@ -52,7 +52,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi) struct generic_pm_domain *pd; struct psci_pd_provider *pd_provider; struct dev_power_governor *pd_gov; - int ret = -ENOMEM, state_count = 0; + int ret = -ENOMEM;
pd = dt_idle_pd_alloc(np, psci_dt_parse_state_node); if (!pd) @@ -71,7 +71,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi) pd->flags |= GENPD_FLAG_ALWAYS_ON;
/* Use governor for CPU PM domains if it has some states to manage. */ - pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL; + pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
ret = pm_genpd_init(pd, pd_gov, false); if (ret)
From: Ulf Hansson ulf.hansson@linaro.org
[ Upstream commit a6653fb584b5f6ac60ddd5d86ddd49a1f3945a04 ]
The intent is to use a genpd governor when there are some states that needs to be managed. Although, the current code ends up to never assign a governor, let's fix this.
Fixes: 6abf32f1d9c50 ("cpuidle: Add RISC-V SBI CPU idle driver") Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Reviewed-by: Anup Patel anup@brainfault.org Tested-by: Anup Patel anup@brainfault.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle-riscv-sbi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c index 5c852e671992..1151e5e2ba82 100644 --- a/drivers/cpuidle/cpuidle-riscv-sbi.c +++ b/drivers/cpuidle/cpuidle-riscv-sbi.c @@ -414,7 +414,7 @@ static int sbi_pd_init(struct device_node *np) struct generic_pm_domain *pd; struct sbi_pd_provider *pd_provider; struct dev_power_governor *pd_gov; - int ret = -ENOMEM, state_count = 0; + int ret = -ENOMEM;
pd = dt_idle_pd_alloc(np, sbi_dt_parse_state_node); if (!pd) @@ -433,7 +433,7 @@ static int sbi_pd_init(struct device_node *np) pd->flags |= GENPD_FLAG_ALWAYS_ON;
/* Use governor for CPU PM domains if it has some states to manage. */ - pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL; + pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
ret = pm_genpd_init(pd, pd_gov, false); if (ret)
From: Heikki Krogerus heikki.krogerus@linux.intel.com
[ Upstream commit 3ce827bf9cfecaf2cbfd9a9d44f0db9f40882780 ]
Module removal fails because cht_int33fe_typec_remove() tries to access driver data that does not exist. Fixing by assigning the data at the end of probe.
Fixes: 915623a80b5a ("platform/x86: intel_cht_int33fe: Switch to DMI modalias based loading") Signed-off-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20220519122103.78546-1-heikki.krogerus@linux.intel... Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/intel/chtwc_int33fe.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/platform/x86/intel/chtwc_int33fe.c b/drivers/platform/x86/intel/chtwc_int33fe.c index 0de509fbf020..c52ac23e2331 100644 --- a/drivers/platform/x86/intel/chtwc_int33fe.c +++ b/drivers/platform/x86/intel/chtwc_int33fe.c @@ -389,6 +389,8 @@ static int cht_int33fe_typec_probe(struct platform_device *pdev) goto out_unregister_fusb302; }
+ platform_set_drvdata(pdev, data); + return 0;
out_unregister_fusb302:
From: Ulf Hansson ulf.hansson@linaro.org
[ Upstream commit 622d9b5577f19a6472db21df042fea8f5fefe244 ]
In the genpd governor we walk the list of child-domains to take into account their next_wakeup. If the child-domain itself, doesn't have a governor assigned to it, we can end up using the next_wakeup value before it has been properly initialized. To prevent a possible incorrect behaviour in the governor, let's initialize next_wakeup to KTIME_MAX.
Fixes: c79aa080fb0f ("PM: domains: use device's next wakeup to determine domain idle state") Signed-off-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 | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 1ee878d126fd..f0e4b0ea93e8 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1997,6 +1997,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, genpd->device_count = 0; genpd->max_off_time_ns = -1; genpd->max_off_time_changed = true; + genpd->next_wakeup = KTIME_MAX; genpd->provider = NULL; genpd->has_provider = false; genpd->accounting_time = ktime_get();
From: Harini Katakam harini.katakam@xilinx.com
[ Upstream commit 5cebb40bc9554aafcc492431181f43c6231b0459 ]
PTP one step sync packets cannot have CSUM padding and insertion in SW since time stamp is inserted on the fly by HW. In addition, ptp4l version 3.0 and above report an error when skb timestamps are reported for packets that not processed for TX TS after transmission. Add a helper to identify PTP one step sync and fix the above two errors. Add a common mask for PTP header flag field "twoStepflag". Also reset ptp OSS bit when one step is not selected.
Fixes: ab91f0a9b5f4 ("net: macb: Add hardware PTP support") Fixes: 653e92a9175e ("net: macb: add support for padding and fcs computation") Signed-off-by: Harini Katakam harini.katakam@xilinx.com Reviewed-by: Radhey Shyam Pandey radhey.shyam.pandey@xilinx.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20220518170756.7752-1-harini.katakam@xilinx.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/cadence/macb_main.c | 40 +++++++++++++++++++++--- drivers/net/ethernet/cadence/macb_ptp.c | 4 ++- include/linux/ptp_classify.h | 3 ++ 3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index ed7c2c2c4401..e9e5c3f6027c 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -36,6 +36,7 @@ #include <linux/iopoll.h> #include <linux/phy/phy.h> #include <linux/pm_runtime.h> +#include <linux/ptp_classify.h> #include <linux/reset.h> #include "macb.h"
@@ -1124,6 +1125,36 @@ static void macb_tx_error_task(struct work_struct *work) spin_unlock_irqrestore(&bp->lock, flags); }
+static bool ptp_one_step_sync(struct sk_buff *skb) +{ + struct ptp_header *hdr; + unsigned int ptp_class; + u8 msgtype; + + /* No need to parse packet if PTP TS is not involved */ + if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) + goto not_oss; + + /* Identify and return whether PTP one step sync is being processed */ + ptp_class = ptp_classify_raw(skb); + if (ptp_class == PTP_CLASS_NONE) + goto not_oss; + + hdr = ptp_parse_header(skb, ptp_class); + if (!hdr) + goto not_oss; + + if (hdr->flag_field[0] & PTP_FLAG_TWOSTEP) + goto not_oss; + + msgtype = ptp_get_msgtype(hdr, ptp_class); + if (msgtype == PTP_MSGTYPE_SYNC) + return true; + +not_oss: + return false; +} + static void macb_tx_interrupt(struct macb_queue *queue) { unsigned int tail; @@ -1168,8 +1199,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)
/* First, update TX stats if needed */ if (skb) { - if (unlikely(skb_shinfo(skb)->tx_flags & - SKBTX_HW_TSTAMP) && + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && + !ptp_one_step_sync(skb) && gem_ptp_do_txstamp(queue, skb, desc) == 0) { /* skb now belongs to timestamp buffer * and will be removed later @@ -1999,7 +2030,8 @@ static unsigned int macb_tx_map(struct macb *bp, ctrl |= MACB_BF(TX_LSO, lso_ctrl); ctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl); if ((bp->dev->features & NETIF_F_HW_CSUM) && - skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl) + skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl && + !ptp_one_step_sync(skb)) ctrl |= MACB_BIT(TX_NOCRC); } else /* Only set MSS/MFS on payload descriptors @@ -2097,7 +2129,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
if (!(ndev->features & NETIF_F_HW_CSUM) || !((*skb)->ip_summed != CHECKSUM_PARTIAL) || - skb_shinfo(*skb)->gso_size) /* Not available for GSO */ + skb_shinfo(*skb)->gso_size || ptp_one_step_sync(*skb)) return 0;
if (padlen <= 0) { diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c index fb6b27f46b15..9559c16078f9 100644 --- a/drivers/net/ethernet/cadence/macb_ptp.c +++ b/drivers/net/ethernet/cadence/macb_ptp.c @@ -470,8 +470,10 @@ int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd) case HWTSTAMP_TX_ONESTEP_SYNC: if (gem_ptp_set_one_step_sync(bp, 1) != 0) return -ERANGE; - fallthrough; + tx_bd_control = TSTAMP_ALL_FRAMES; + break; case HWTSTAMP_TX_ON: + gem_ptp_set_one_step_sync(bp, 0); tx_bd_control = TSTAMP_ALL_FRAMES; break; default: diff --git a/include/linux/ptp_classify.h b/include/linux/ptp_classify.h index fefa7790dc46..2b6ea36ad162 100644 --- a/include/linux/ptp_classify.h +++ b/include/linux/ptp_classify.h @@ -43,6 +43,9 @@ #define OFF_PTP_SOURCE_UUID 22 /* PTPv1 only */ #define OFF_PTP_SEQUENCE_ID 30
+/* PTP header flag fields */ +#define PTP_FLAG_TWOSTEP BIT(1) + /* Below defines should actually be removed at some point in time. */ #define IP6_HLEN 40 #define UDP_HLEN 8
From: John Garry john.garry@huawei.com
[ Upstream commit e9dedc13bb11bc553754abecb322e5e41d1b4fef ]
Removing an ATA device via sysfs means that the device may not be found through re-scanning:
root@ubuntu:/home/john# lsscsi [0:0:0:0] disk SanDisk LT0200MO P404 /dev/sda [0:0:1:0] disk ATA HGST HUS724040AL A8B0 /dev/sdb [0:0:8:0] enclosu 12G SAS Expander RevB - root@ubuntu:/home/john# echo 1 > /sys/block/sdb/device/delete root@ubuntu:/home/john# echo "- - -" > /sys/class/scsi_host/host0/scan root@ubuntu:/home/john# lsscsi [0:0:0:0] disk SanDisk LT0200MO P404 /dev/sda [0:0:8:0] enclosu 12G SAS Expander RevB - root@ubuntu:/home/john#
The problem is that the rescan of the device may conflict with the device in being re-initialized, as follows:
- In the rescan we call hisi_sas_slave_alloc() in store_scan() -> sas_user_scan() -> [__]scsi_scan_target() -> scsi_probe_and_add_lunc() -> scsi_alloc_sdev() -> hisi_sas_slave_alloc() -> hisi_sas_init_device() In hisi_sas_init_device() we issue an IT nexus reset for ATA devices
- That IT nexus causes the remote PHY to go down and this triggers a bcast event
- In parallel libsas processes the bcast event, finds that the phy is down and marks the device as gone
The hard reset issued in hisi_sas_init_device() is unncessary - as described in the code comment - so remove it. Also set dev status as HISI_SAS_DEV_NORMAL as the hisi_sas_init_device() call.
Link: https://lore.kernel.org/r/1652354134-171343-4-git-send-email-john.garry@huaw... Fixes: 36c6b7613ef1 ("scsi: hisi_sas: Initialise devices in .slave_alloc callback") Tested-by: Yihang Li liyihang6@hisilicon.com Reviewed-by: Xiang Chen chenxiang66@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_main.c | 47 ++++++++++----------------- 1 file changed, 18 insertions(+), 29 deletions(-)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4bda2f6cb352..86cbfab78dfe 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -709,8 +709,6 @@ static int hisi_sas_init_device(struct domain_device *device) struct scsi_lun lun; int retry = HISI_SAS_DISK_RECOVER_CNT; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); - struct device *dev = hisi_hba->dev; - struct sas_phy *local_phy;
switch (device->dev_type) { case SAS_END_DEVICE: @@ -729,30 +727,18 @@ static int hisi_sas_init_device(struct domain_device *device) case SAS_SATA_PM_PORT: case SAS_SATA_PENDING: /* - * send HARD RESET to clear previous affiliation of - * STP target port + * If an expander is swapped when a SATA disk is attached then + * we should issue a hard reset to clear previous affiliation + * of STP target port, see SPL (chapter 6.19.4). + * + * However we don't need to issue a hard reset here for these + * reasons: + * a. When probing the device, libsas/libata already issues a + * hard reset in sas_probe_sata() -> ata_sas_async_probe(). + * Note that in hisi_sas_debug_I_T_nexus_reset() we take care + * to issue a hard reset by checking the dev status (== INIT). + * b. When resetting the controller, this is simply unnecessary. */ - local_phy = sas_get_local_phy(device); - if (!scsi_is_sas_phy_local(local_phy) && - !test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { - unsigned long deadline = ata_deadline(jiffies, 20000); - struct sata_device *sata_dev = &device->sata_dev; - struct ata_host *ata_host = sata_dev->ata_host; - struct ata_port_operations *ops = ata_host->ops; - struct ata_port *ap = sata_dev->ap; - struct ata_link *link; - unsigned int classes; - - ata_for_each_link(link, ap, EDGE) - rc = ops->hardreset(link, &classes, - deadline); - } - sas_put_local_phy(local_phy); - if (rc) { - dev_warn(dev, "SATA disk hardreset fail: %d\n", rc); - return rc; - } - while (retry-- > 0) { rc = hisi_sas_softreset_ata_disk(device); if (!rc) @@ -768,15 +754,19 @@ static int hisi_sas_init_device(struct domain_device *device)
int hisi_sas_slave_alloc(struct scsi_device *sdev) { - struct domain_device *ddev; + struct domain_device *ddev = sdev_to_domain_dev(sdev); + struct hisi_sas_device *sas_dev = ddev->lldd_dev; int rc;
rc = sas_slave_alloc(sdev); if (rc) return rc; - ddev = sdev_to_domain_dev(sdev);
- return hisi_sas_init_device(ddev); + rc = hisi_sas_init_device(ddev); + if (rc) + return rc; + sas_dev->dev_status = HISI_SAS_DEV_NORMAL; + return 0; } EXPORT_SYMBOL_GPL(hisi_sas_slave_alloc);
@@ -826,7 +816,6 @@ static int hisi_sas_dev_found(struct domain_device *device) dev_info(dev, "dev[%d:%x] found\n", sas_dev->device_id, sas_dev->dev_type);
- sas_dev->dev_status = HISI_SAS_DEV_NORMAL; return 0;
err_out:
From: John Garry john.garry@huawei.com
[ Upstream commit 6c6ac8b7773f05f93dc4e4044686e059d1f78dea ]
The memories for the slot should be observed to be written prior to observing the slot as ready.
Prior to commit 26fc0ea74fcb ("scsi: libsas: Drop SAS_TASK_AT_INITIATOR"), we had a spin_lock() + spin_unlock() immediately before marking the slot as ready. The spin_unlock() - with release semantics - caused the slot memory to be observed to be written.
Now that the spin_lock() + spin_unlock() is gone, use a smp_wmb().
Link: https://lore.kernel.org/r/1652774661-12935-1-git-send-email-john.garry@huawe... Fixes: 26fc0ea74fcb ("scsi: libsas: Drop SAS_TASK_AT_INITIATOR") Reported-by: Yihang Li liyihang6@hisilicon.com Tested-by: Yihang Li liyihang6@hisilicon.com Signed-off-by: John Garry john.garry@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_main.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 86cbfab78dfe..849cc5fc86af 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -446,6 +446,8 @@ void hisi_sas_task_deliver(struct hisi_hba *hisi_hba, return; }
+ /* Make slot memories observable before marking as ready */ + smp_wmb(); WRITE_ONCE(slot->ready, 1);
spin_lock(&dq->lock);
From: Duoming Zhou duoming@zju.edu.cn
[ Upstream commit b413b0cb008646e9f24ce5253cb3cf7ee217aff6 ]
There are sleep in atomic context bugs when the request to secure element of st21nfca is timeout. The root cause is that kzalloc and alloc_skb with GFP_KERNEL parameter and mutex_lock are called in st21nfca_se_wt_timeout which is a timer handler. The call tree shows the execution paths that could lead to bugs:
(Interrupt context) st21nfca_se_wt_timeout nfc_hci_send_event nfc_hci_hcp_message_tx kzalloc(..., GFP_KERNEL) //may sleep alloc_skb(..., GFP_KERNEL) //may sleep mutex_lock() //may sleep
This patch moves the operations that may sleep into a work item. The work item will run in another kernel thread which is in process context to execute the bottom half of the interrupt. So it could prevent atomic context from sleeping.
Fixes: 2130fb97fecf ("NFC: st21nfca: Adding support for secure element") Signed-off-by: Duoming Zhou duoming@zju.edu.cn Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220518115733.62111-1-duoming@zju.edu.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nfc/st21nfca/se.c | 17 ++++++++++++++--- drivers/nfc/st21nfca/st21nfca.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/nfc/st21nfca/se.c b/drivers/nfc/st21nfca/se.c index c922f10d0d7b..7e213f8ddc98 100644 --- a/drivers/nfc/st21nfca/se.c +++ b/drivers/nfc/st21nfca/se.c @@ -241,7 +241,7 @@ int st21nfca_hci_se_io(struct nfc_hci_dev *hdev, u32 se_idx, } EXPORT_SYMBOL(st21nfca_hci_se_io);
-static void st21nfca_se_wt_timeout(struct timer_list *t) +static void st21nfca_se_wt_work(struct work_struct *work) { /* * No answer from the secure element @@ -254,8 +254,9 @@ static void st21nfca_se_wt_timeout(struct timer_list *t) */ /* hardware reset managed through VCC_UICC_OUT power supply */ u8 param = 0x01; - struct st21nfca_hci_info *info = from_timer(info, t, - se_info.bwi_timer); + struct st21nfca_hci_info *info = container_of(work, + struct st21nfca_hci_info, + se_info.timeout_work);
info->se_info.bwi_active = false;
@@ -271,6 +272,13 @@ static void st21nfca_se_wt_timeout(struct timer_list *t) info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); }
+static void st21nfca_se_wt_timeout(struct timer_list *t) +{ + struct st21nfca_hci_info *info = from_timer(info, t, se_info.bwi_timer); + + schedule_work(&info->se_info.timeout_work); +} + static void st21nfca_se_activation_timeout(struct timer_list *t) { struct st21nfca_hci_info *info = from_timer(info, t, @@ -360,6 +368,7 @@ int st21nfca_apdu_reader_event_received(struct nfc_hci_dev *hdev, switch (event) { case ST21NFCA_EVT_TRANSMIT_DATA: del_timer_sync(&info->se_info.bwi_timer); + cancel_work_sync(&info->se_info.timeout_work); info->se_info.bwi_active = false; r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); @@ -389,6 +398,7 @@ void st21nfca_se_init(struct nfc_hci_dev *hdev) struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev);
init_completion(&info->se_info.req_completion); + INIT_WORK(&info->se_info.timeout_work, st21nfca_se_wt_work); /* initialize timers */ timer_setup(&info->se_info.bwi_timer, st21nfca_se_wt_timeout, 0); info->se_info.bwi_active = false; @@ -416,6 +426,7 @@ void st21nfca_se_deinit(struct nfc_hci_dev *hdev) if (info->se_info.se_active) del_timer_sync(&info->se_info.se_active_timer);
+ cancel_work_sync(&info->se_info.timeout_work); info->se_info.bwi_active = false; info->se_info.se_active = false; } diff --git a/drivers/nfc/st21nfca/st21nfca.h b/drivers/nfc/st21nfca/st21nfca.h index cb6ad916be91..ae6771cc9894 100644 --- a/drivers/nfc/st21nfca/st21nfca.h +++ b/drivers/nfc/st21nfca/st21nfca.h @@ -141,6 +141,7 @@ struct st21nfca_se_info {
se_io_cb_t cb; void *cb_context; + struct work_struct timeout_work; };
struct st21nfca_hci_info {
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 9b80ccda233fa6c59de411bf889cc4d0e028f2c7 ]
When removing the rcu_read_lock in bond_ethtool_get_ts_info() as discussed [1], I didn't notice it could be called via setsockopt, which doesn't hold rcu lock, as syzbot pointed:
stack backtrace: CPU: 0 PID: 3599 Comm: syz-executor317 Not tainted 5.18.0-rc5-syzkaller-01392-g01f4685797a5 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 bond_option_active_slave_get_rcu include/net/bonding.h:353 [inline] bond_ethtool_get_ts_info+0x32c/0x3a0 drivers/net/bonding/bond_main.c:5595 __ethtool_get_ts_info+0x173/0x240 net/ethtool/common.c:554 ethtool_get_phc_vclocks+0x99/0x110 net/ethtool/common.c:568 sock_timestamping_bind_phc net/core/sock.c:869 [inline] sock_set_timestamping+0x3a3/0x7e0 net/core/sock.c:916 sock_setsockopt+0x543/0x2ec0 net/core/sock.c:1221 __sys_setsockopt+0x55e/0x6a0 net/socket.c:2223 __do_sys_setsockopt net/socket.c:2238 [inline] __se_sys_setsockopt net/socket.c:2235 [inline] __x64_sys_setsockopt+0xba/0x150 net/socket.c:2235 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f8902c8eb39
Fix it by adding rcu_read_lock and take a ref on the real_dev. Since dev_hold() and dev_put() can take NULL these days, we can skip checking if real_dev exist.
[1] https://lore.kernel.org/netdev/27565.1642742439@famine/
Reported-by: syzbot+92beb3d46aab498710fa@syzkaller.appspotmail.com Fixes: aa6034678e87 ("bonding: use rcu_dereference_rtnl when get bonding active slave") Suggested-by: Vladimir Oltean vladimir.oltean@nxp.com Suggested-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Hangbin Liu liuhangbin@gmail.com Reviewed-by: Vladimir Oltean vladimir.oltean@nxp.com Link: https://lore.kernel.org/r/20220519020148.1058344-1-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/bonding/bond_main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 38e152548126..b5c5196e03ee 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -5591,16 +5591,23 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev, const struct ethtool_ops *ops; struct net_device *real_dev; struct phy_device *phydev; + int ret = 0;
+ rcu_read_lock(); real_dev = bond_option_active_slave_get_rcu(bond); + dev_hold(real_dev); + rcu_read_unlock(); + if (real_dev) { ops = real_dev->ethtool_ops; phydev = real_dev->phydev;
if (phy_has_tsinfo(phydev)) { - return phy_ts_info(phydev, info); + ret = phy_ts_info(phydev, info); + goto out; } else if (ops->get_ts_info) { - return ops->get_ts_info(real_dev, info); + ret = ops->get_ts_info(real_dev, info); + goto out; } }
@@ -5608,7 +5615,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev, SOF_TIMESTAMPING_SOFTWARE; info->phc_index = -1;
- return 0; +out: + dev_put(real_dev); + return ret; }
static const struct ethtool_ops bond_ethtool_ops = {
From: Alexey Khoroshilov khoroshilov@ispras.ru
[ Upstream commit f7a344468105ef8c54086dfdc800e6f5a8417d3e ]
Validation of signed input should be done before casting to unsigned int.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Suggested-by: Mark Brown broonie@kernel.org Fixes: 2fbe467bcbfc ("ASoC: max98090: Reject invalid values in custom control put()") Link: https://lore.kernel.org/r/1652999486-29653-1-git-send-email-khoroshilov@ispr... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/max98090.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index 62b41ca050a2..5513acd360b8 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -393,7 +393,8 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int sel = ucontrol->value.integer.value[0]; + int sel_unchecked = ucontrol->value.integer.value[0]; + unsigned int sel; unsigned int val = snd_soc_component_read(component, mc->reg); unsigned int *select;
@@ -413,8 +414,9 @@ static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol,
val = (val >> mc->shift) & mask;
- if (sel < 0 || sel > mc->max) + if (sel_unchecked < 0 || sel_unchecked > mc->max) return -EINVAL; + sel = sel_unchecked;
*select = sel;
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit e7d1374ed5cb346efd9b3df03814dbc0767adb4e ]
The evsel->name may have a different format for a topdown event, a pure topdown name (e.g., topdown-fe-bound), or a PMU name + a topdown name (e.g., cpu/topdown-fe-bound/). The cpu/topdown-fe-bound/ kind format isn't supported by the arch_evlist__leader(). This format is a very common format for a hybrid platform, which requires specifying the PMU name for each event.
Without the patch,
$ perf stat -e '{instructions,slots,cpu/topdown-fe-bound/}' -a sleep 1
Performance counter stats for 'system wide':
<not counted> instructions <not counted> slots <not supported> cpu/topdown-fe-bound/
1.003482041 seconds time elapsed
Some events weren't counted. Try disabling the NMI watchdog: echo 0 > /proc/sys/kernel/nmi_watchdog perf stat ... echo 1 > /proc/sys/kernel/nmi_watchdog The events in group usually have to be from the same PMU. Try reorganizing the group.
With the patch,
$ perf stat -e '{instructions,slots,cpu/topdown-fe-bound/}' -a sleep 1
Performance counter stats for 'system wide':
157,383,996 slots 25,011,711 instructions 27,441,686 cpu/topdown-fe-bound/
1.003530890 seconds time elapsed
Fixes: bc355822f0d9623b ("perf parse-events: Move slots only with topdown") Reviewed-by: Ian Rogers irogers@google.com Signed-off-by: Kan Liang kan.liang@linux.intel.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Ian Rogers irogers@google.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Stephane Eranian eranian@google.com Cc: Xing Zhengjun zhengjun.xing@linux.intel.com Link: https://lore.kernel.org/r/20220518143900.1493980-4-kan.liang@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/arch/x86/util/evlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/arch/x86/util/evlist.c b/tools/perf/arch/x86/util/evlist.c index cfc208d71f00..75564a7df15b 100644 --- a/tools/perf/arch/x86/util/evlist.c +++ b/tools/perf/arch/x86/util/evlist.c @@ -36,7 +36,7 @@ struct evsel *arch_evlist__leader(struct list_head *list) if (slots == first) return first; } - if (!strncasecmp(evsel->name, "topdown", 7)) + if (strcasestr(evsel->name, "topdown")) has_topdown = true; if (slots && has_topdown) return slots;
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit fe5c5fc145edcf98a759b895f52b646730eeb7be ]
GCC 12 points out that struct tc_action is smaller than struct tcf_action:
drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c: In function ‘stmmac_test_rxp’: drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c:1132:21: warning: array subscript ‘struct tcf_gact[0]’ is partly outside array bounds of ‘unsigned char[272]’ [-Warray-bounds] 1132 | gact->tcf_action = TC_ACT_SHOT; | ^~
Fixes: ccfc639a94f2 ("net: stmmac: selftests: Add a selftest for Flexible RX Parser") Link: https://lore.kernel.org/r/20220519004305.2109708-1-kuba@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/stmicro/stmmac/stmmac_selftests.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c index 9f1759593b94..2fc51dc5eb0b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c @@ -1084,8 +1084,9 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) unsigned char addr[ETH_ALEN] = {0xde, 0xad, 0xbe, 0xef, 0x00, 0x00}; struct tc_cls_u32_offload cls_u32 = { }; struct stmmac_packet_attrs attr = { }; - struct tc_action **actions, *act; + struct tc_action **actions; struct tc_u32_sel *sel; + struct tcf_gact *gact; struct tcf_exts *exts; int ret, i, nk = 1;
@@ -1110,8 +1111,8 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) goto cleanup_exts; }
- act = kcalloc(nk, sizeof(*act), GFP_KERNEL); - if (!act) { + gact = kcalloc(nk, sizeof(*gact), GFP_KERNEL); + if (!gact) { ret = -ENOMEM; goto cleanup_actions; } @@ -1126,9 +1127,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) exts->nr_actions = nk; exts->actions = actions; for (i = 0; i < nk; i++) { - struct tcf_gact *gact = to_gact(&act[i]); - - actions[i] = &act[i]; + actions[i] = (struct tc_action *)&gact[i]; gact->tcf_action = TC_ACT_SHOT; }
@@ -1152,7 +1151,7 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) stmmac_tc_setup_cls_u32(priv, priv, &cls_u32);
cleanup_act: - kfree(act); + kfree(gact); cleanup_actions: kfree(actions); cleanup_exts:
From: Taehee Yoo ap420073@gmail.com
[ Upstream commit 937956ba404e70a765ca5aa39d3d7564d86a8872 ]
If a gateway can not receive any response to requests from a relay, gateway resets status from SENT_REQUEST to INIT and variable about a relay as well. And then it should start the full establish step from sending a discovery message and receiving advertisement message. But, after failure in amt_req_work() it continues sending a request message step with flushed(invalid) relay information and sets SENT_REQUEST. So, a gateway can't be established with a relay. In order to avoid this situation, it stops sending the request message step if it fails.
Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface") Signed-off-by: Taehee Yoo ap420073@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/amt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c index 10455c9b9da0..2b4ce3869f08 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -943,7 +943,7 @@ static void amt_req_work(struct work_struct *work) if (amt->status < AMT_STATUS_RECEIVED_ADVERTISEMENT) goto out;
- if (amt->req_cnt++ > AMT_MAX_REQ_COUNT) { + if (amt->req_cnt > AMT_MAX_REQ_COUNT) { netdev_dbg(amt->dev, "Gateway is not ready"); amt->qi = AMT_INIT_REQ_TIMEOUT; amt->ready4 = false; @@ -951,13 +951,15 @@ static void amt_req_work(struct work_struct *work) amt->remote_ip = 0; __amt_update_gw_status(amt, AMT_STATUS_INIT, false); amt->req_cnt = 0; + goto out; } spin_unlock_bh(&amt->lock);
amt_send_request(amt, false); amt_send_request(amt, true); - amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true); spin_lock_bh(&amt->lock); + __amt_update_gw_status(amt, AMT_STATUS_SENT_REQUEST, true); + amt->req_cnt++; out: exp = min_t(u32, (1 * (1 << amt->req_cnt)), AMT_MAX_REQ_TIMEOUT); mod_delayed_work(amt_wq, &amt->req_wq, msecs_to_jiffies(exp * 1000));
From: Taehee Yoo ap420073@gmail.com
[ Upstream commit fe29794c3585d039fefebaa2b5a4932a627ad4fd ]
When a gateway receives an advertisement message, it extracts relay information and then it should be freed. But the advertisement handler doesn't free it. So, memory leak would occur.
Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface") Signed-off-by: Taehee Yoo ap420073@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/amt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c index 2b4ce3869f08..de4ea518c793 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -2698,9 +2698,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb) err = true; goto drop; } - if (amt_advertisement_handler(amt, skb)) - amt->dev->stats.rx_dropped++; - goto out; + err = amt_advertisement_handler(amt, skb); + break; case AMT_MSG_MULTICAST_DATA: if (iph->saddr != amt->remote_ip) { netdev_dbg(amt->dev, "Invalid Relay IP\n");
From: Yongzhi Liu lyz_cs@pku.edu.cn
[ Upstream commit eb4c0788964730d12e8dd520bd8f5217ca48321c ]
The return value of netvsc_devinfo_get() needs to be checked to avoid use of NULL pointer in case of an allocation failure.
Fixes: 0efeea5fb153 ("hv_netvsc: Add the support of hibernation") Signed-off-by: Yongzhi Liu lyz_cs@pku.edu.cn Reviewed-by: Haiyang Zhang haiyangz@microsoft.com Link: https://lore.kernel.org/r/1652962188-129281-1-git-send-email-lyz_cs@pku.edu.... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/hyperv/netvsc_drv.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index fde1c492ca02..b1dece6b9698 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2671,7 +2671,10 @@ static int netvsc_suspend(struct hv_device *dev)
/* Save the current config info */ ndev_ctx->saved_netvsc_dev_info = netvsc_devinfo_get(nvdev); - + if (!ndev_ctx->saved_netvsc_dev_info) { + ret = -ENOMEM; + goto out; + } ret = netvsc_detach(net, nvdev); out: rtnl_unlock();
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit 9baabde04de64137e86b39112c6259f3da512bd6 ]
Building arm:allmodconfig may fail with the following error.
In function 'fortify_memcpy_chk', inlined from 'bitmap_copy' at include/linux/bitmap.h:261:2, inlined from 'bitmap_copy_clear_tail' at include/linux/bitmap.h:270:2, inlined from 'bitmap_from_u64' at include/linux/bitmap.h:622:2, inlined from 'check_populated_dimms' at drivers/hwmon/peci/dimmtemp.c:284:2: include/linux/fortify-string.h:344:25: error: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter)
The problematic code is bitmap_from_u64(priv->dimm_mask, dimm_mask);
dimm_mask is declared as u64, but the bitmap in priv->dimm_mask is only 24 bit wide. On 32-bit systems, this results in writes over the end of the bitmap.
Fix the problem by using u32 instead of u64 for dimm_mask. This is currently sufficient, and a compile time check to ensure that the number of dimms does not exceed the bit map size is already in place.
Fixes: 73bc1b885dae ("hwmon: peci: Add dimmtemp driver") Cc: Iwona Winiarska iwona.winiarska@intel.com Reviewed-by: Iwona Winiarska iwona.winiarska@intel.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/peci/dimmtemp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c index c8222354c005..53e58a9c28ea 100644 --- a/drivers/hwmon/peci/dimmtemp.c +++ b/drivers/hwmon/peci/dimmtemp.c @@ -219,7 +219,7 @@ static int check_populated_dimms(struct peci_dimmtemp *priv) int chan_rank_max = priv->gen_info->chan_rank_max; int dimm_idx_max = priv->gen_info->dimm_idx_max; u32 chan_rank_empty = 0; - u64 dimm_mask = 0; + u32 dimm_mask = 0; int chan_rank, dimm_idx, ret; u32 pcs;
@@ -278,9 +278,9 @@ static int check_populated_dimms(struct peci_dimmtemp *priv) return -EAGAIN; }
- dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask); + dev_dbg(priv->dev, "Scanned populated DIMMs: %#x\n", dimm_mask);
- bitmap_from_u64(priv->dimm_mask, dimm_mask); + bitmap_from_arr32(priv->dimm_mask, &dimm_mask, DIMM_NUMS_MAX);
return 0; }
From: Adam Wujek dev_public@wujek.eu
[ Upstream commit d1baf7a3a3177d46a7149858beddb88a9eca7a54 ]
Make sure that the support of PEC is determined before the read of other registers. Otherwise the validation of PEC can trigger an error on the read of STATUS_BYTE or STATUS_WORD registers.
The problematic scenario is the following. A device with enabled PEC support is up and running and a kernel driver is loaded. Then the driver is unloaded (or device unbound), the HW device is reconfigured externally (e.g. by i2cset) to advertise itself as not supporting PEC. Without the move of the code, at the second load of the driver (or bind) the STATUS_BYTE or STATUS_WORD register is always read with PEC enabled, which is likely to cause a read error resulting with fail of a driver load (or bind).
Signed-off-by: Adam Wujek dev_public@wujek.eu Link: https://lore.kernel.org/r/20220519233334.438621-1-dev_public@wujek.eu Fixes: 75d2b2b06bd84 ("hwmon: (pmbus) disable PEC if not enabled") Fixes: 4e5418f787ec5 ("hwmon: (pmbus_core) Check adapter PEC support") [groeck: Added Fixes: tags, dropped continuation line] Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/pmbus_core.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 5a1796650f5b..86429bfa4847 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2308,6 +2308,21 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, struct device *dev = &client->dev; int page, ret;
+ /* + * Figure out if PEC is enabled before accessing any other register. + * Make sure PEC is disabled, will be enabled later if needed. + */ + client->flags &= ~I2C_CLIENT_PEC; + + /* Enable PEC if the controller and bus supports it */ + if (!(data->flags & PMBUS_NO_CAPABILITY)) { + ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); + if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) { + if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC)) + client->flags |= I2C_CLIENT_PEC; + } + } + /* * Some PMBus chips don't support PMBUS_STATUS_WORD, so try * to use PMBUS_STATUS_BYTE instead if that is the case. @@ -2326,19 +2341,6 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, data->has_status_word = true; }
- /* Make sure PEC is disabled, will be enabled later if needed */ - client->flags &= ~I2C_CLIENT_PEC; - - /* Enable PEC if the controller and bus supports it */ - if (!(data->flags & PMBUS_NO_CAPABILITY)) { - ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); - if (ret >= 0 && (ret & PB_CAPABILITY_ERROR_CHECK)) { - if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC)) { - client->flags |= I2C_CLIENT_PEC; - } - } - } - /* * Check if the chip is write protected. If it is, we can not clear * faults, and we should not try it. Also, in that case, writes into
From: David Howells dhowells@redhat.com
[ Upstream commit ad25f5cb39872ca14bcbe00816ae65c22fe04b89 ]
There's a locking issue with the per-netns list of calls in rxrpc. The pieces of code that add and remove a call from the list use write_lock() and the calls procfile uses read_lock() to access it. However, the timer callback function may trigger a removal by trying to queue a call for processing and finding that it's already queued - at which point it has a spare refcount that it has to do something with. Unfortunately, if it puts the call and this reduces the refcount to 0, the call will be removed from the list. Unfortunately, since the _bh variants of the locking functions aren't used, this can deadlock.
================================ WARNING: inconsistent lock state 5.18.0-rc3-build4+ #10 Not tainted -------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. ksoftirqd/2/25 [HC0[0]:SC1[1]:HE1:SE0] takes: ffff888107ac4038 (&rxnet->call_lock){+.?.}-{2:2}, at: rxrpc_put_call+0x103/0x14b {SOFTIRQ-ON-W} state was registered at: ... Possible unsafe locking scenario:
CPU0 ---- lock(&rxnet->call_lock); <Interrupt> lock(&rxnet->call_lock);
*** DEADLOCK ***
1 lock held by ksoftirqd/2/25: #0: ffff8881008ffdb0 ((&call->timer)){+.-.}-{0:0}, at: call_timer_fn+0x5/0x23d
Changes ======= ver #2) - Changed to using list_next_rcu() rather than rcu_dereference() directly.
Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both") Signed-off-by: David Howells dhowells@redhat.com cc: Marc Dionne marc.dionne@auristor.com cc: linux-afs@lists.infradead.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- fs/seq_file.c | 32 ++++++++++++++++++++++++++++++++ include/linux/list.h | 10 ++++++++++ include/linux/seq_file.h | 4 ++++ net/rxrpc/ar-internal.h | 2 +- net/rxrpc/call_accept.c | 6 +++--- net/rxrpc/call_object.c | 18 +++++++++--------- net/rxrpc/net_ns.c | 2 +- net/rxrpc/proc.c | 10 ++-------- 8 files changed, 62 insertions(+), 22 deletions(-)
diff --git a/fs/seq_file.c b/fs/seq_file.c index 7ab8a58c29b6..9456a2032224 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -931,6 +931,38 @@ struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) } EXPORT_SYMBOL(seq_list_next);
+struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos) +{ + struct list_head *lh; + + list_for_each_rcu(lh, head) + if (pos-- == 0) + return lh; + + return NULL; +} +EXPORT_SYMBOL(seq_list_start_rcu); + +struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos) +{ + if (!pos) + return head; + + return seq_list_start_rcu(head, pos - 1); +} +EXPORT_SYMBOL(seq_list_start_head_rcu); + +struct list_head *seq_list_next_rcu(void *v, struct list_head *head, + loff_t *ppos) +{ + struct list_head *lh; + + lh = list_next_rcu((struct list_head *)v); + ++*ppos; + return lh == head ? NULL : lh; +} +EXPORT_SYMBOL(seq_list_next_rcu); + /** * seq_hlist_start - start an iteration of a hlist * @head: the head of the hlist diff --git a/include/linux/list.h b/include/linux/list.h index dd6c2041d09c..0f7d8ec5b4ed 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -579,6 +579,16 @@ static inline void list_splice_tail_init(struct list_head *list, #define list_for_each(pos, head) \ for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)
+/** + * list_for_each_rcu - Iterate over a list in an RCU-safe fashion + * @pos: the &struct list_head to use as a loop cursor. + * @head: the head for your list. + */ +#define list_for_each_rcu(pos, head) \ + for (pos = rcu_dereference((head)->next); \ + !list_is_head(pos, (head)); \ + pos = rcu_dereference(pos->next)) + /** * list_for_each_continue - continue iteration over a list * @pos: the &struct list_head to use as a loop cursor. diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 60820ab511d2..bd023dd38ae6 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -277,6 +277,10 @@ extern struct list_head *seq_list_start_head(struct list_head *head, extern struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos);
+extern struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos); +extern struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos); +extern struct list_head *seq_list_next_rcu(void *v, struct list_head *head, loff_t *ppos); + /* * Helpers for iteration over hlist_head-s in seq_files */ diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 969e532f77a9..422558d50571 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -68,7 +68,7 @@ struct rxrpc_net { struct proc_dir_entry *proc_net; /* Subdir in /proc/net */ u32 epoch; /* Local epoch for detecting local-end reset */ struct list_head calls; /* List of calls active in this namespace */ - rwlock_t call_lock; /* Lock for ->calls */ + spinlock_t call_lock; /* Lock for ->calls */ atomic_t nr_calls; /* Count of allocated calls */
atomic_t nr_conns; diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index 1ae90fb97936..8b24ffbc72ef 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -140,9 +140,9 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx, write_unlock(&rx->call_lock);
rxnet = call->rxnet; - write_lock(&rxnet->call_lock); - list_add_tail(&call->link, &rxnet->calls); - write_unlock(&rxnet->call_lock); + spin_lock_bh(&rxnet->call_lock); + list_add_tail_rcu(&call->link, &rxnet->calls); + spin_unlock_bh(&rxnet->call_lock);
b->call_backlog[call_head] = call; smp_store_release(&b->call_backlog_head, (call_head + 1) & (size - 1)); diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 043508fd8d8a..25c9a2cbf048 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -337,9 +337,9 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, write_unlock(&rx->call_lock);
rxnet = call->rxnet; - write_lock(&rxnet->call_lock); - list_add_tail(&call->link, &rxnet->calls); - write_unlock(&rxnet->call_lock); + spin_lock_bh(&rxnet->call_lock); + list_add_tail_rcu(&call->link, &rxnet->calls); + spin_unlock_bh(&rxnet->call_lock);
/* From this point on, the call is protected by its own lock. */ release_sock(&rx->sk); @@ -631,9 +631,9 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op) ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
if (!list_empty(&call->link)) { - write_lock(&rxnet->call_lock); + spin_lock_bh(&rxnet->call_lock); list_del_init(&call->link); - write_unlock(&rxnet->call_lock); + spin_unlock_bh(&rxnet->call_lock); }
rxrpc_cleanup_call(call); @@ -705,7 +705,7 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet) _enter("");
if (!list_empty(&rxnet->calls)) { - write_lock(&rxnet->call_lock); + spin_lock_bh(&rxnet->call_lock);
while (!list_empty(&rxnet->calls)) { call = list_entry(rxnet->calls.next, @@ -720,12 +720,12 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet) rxrpc_call_states[call->state], call->flags, call->events);
- write_unlock(&rxnet->call_lock); + spin_unlock_bh(&rxnet->call_lock); cond_resched(); - write_lock(&rxnet->call_lock); + spin_lock_bh(&rxnet->call_lock); }
- write_unlock(&rxnet->call_lock); + spin_unlock_bh(&rxnet->call_lock); }
atomic_dec(&rxnet->nr_calls); diff --git a/net/rxrpc/net_ns.c b/net/rxrpc/net_ns.c index cc7e30733feb..e4d6d432515b 100644 --- a/net/rxrpc/net_ns.c +++ b/net/rxrpc/net_ns.c @@ -50,7 +50,7 @@ static __net_init int rxrpc_init_net(struct net *net) rxnet->epoch |= RXRPC_RANDOM_EPOCH;
INIT_LIST_HEAD(&rxnet->calls); - rwlock_init(&rxnet->call_lock); + spin_lock_init(&rxnet->call_lock); atomic_set(&rxnet->nr_calls, 1);
atomic_set(&rxnet->nr_conns, 1); diff --git a/net/rxrpc/proc.c b/net/rxrpc/proc.c index e2f990754f88..5a67955cc00f 100644 --- a/net/rxrpc/proc.c +++ b/net/rxrpc/proc.c @@ -26,29 +26,23 @@ static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = { */ static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos) __acquires(rcu) - __acquires(rxnet->call_lock) { struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
rcu_read_lock(); - read_lock(&rxnet->call_lock); - return seq_list_start_head(&rxnet->calls, *_pos); + return seq_list_start_head_rcu(&rxnet->calls, *_pos); }
static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
- return seq_list_next(v, &rxnet->calls, pos); + return seq_list_next_rcu(v, &rxnet->calls, pos); }
static void rxrpc_call_seq_stop(struct seq_file *seq, void *v) - __releases(rxnet->call_lock) __releases(rcu) { - struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq)); - - read_unlock(&rxnet->call_lock); rcu_read_unlock(); }
From: David Howells dhowells@redhat.com
[ Upstream commit 88e22159750b0d55793302eeed8ee603f5c1a95c ]
AF_RXRPC's listen() handler lets you set the backlog up to 32 (if you bump up the sysctl), but whilst the preallocation circular buffers have 32 slots in them, one of them has to be a dead slot because we're using CIRC_CNT().
This means that listen(rxrpc_sock, 32) will cause an oops when the socket is closed because rxrpc_service_prealloc_one() allocated one too many calls and rxrpc_discard_prealloc() won't then be able to get rid of them because it'll think the ring is empty. rxrpc_release_calls_on_socket() then tries to abort them, but oopses because call->peer isn't yet set.
Fix this by setting the maximum backlog to RXRPC_BACKLOG_MAX - 1 to match the ring capacity.
BUG: kernel NULL pointer dereference, address: 0000000000000086 ... RIP: 0010:rxrpc_send_abort_packet+0x73/0x240 [rxrpc] Call Trace: <TASK> ? __wake_up_common_lock+0x7a/0x90 ? rxrpc_notify_socket+0x8e/0x140 [rxrpc] ? rxrpc_abort_call+0x4c/0x60 [rxrpc] rxrpc_release_calls_on_socket+0x107/0x1a0 [rxrpc] rxrpc_release+0xc9/0x1c0 [rxrpc] __sock_release+0x37/0xa0 sock_close+0x11/0x20 __fput+0x89/0x240 task_work_run+0x59/0x90 do_exit+0x319/0xaa0
Fixes: 00e907127e6f ("rxrpc: Preallocate peers, conns and calls for incoming service requests") Reported-by: Marc Dionne marc.dionne@auristor.com Signed-off-by: David Howells dhowells@redhat.com cc: linux-afs@lists.infradead.org Link: https://lists.infradead.org/pipermail/linux-afs/2022-March/005079.html Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/sysctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c index 540351d6a5f4..555e0910786b 100644 --- a/net/rxrpc/sysctl.c +++ b/net/rxrpc/sysctl.c @@ -12,7 +12,7 @@
static struct ctl_table_header *rxrpc_sysctl_reg_table; static const unsigned int four = 4; -static const unsigned int thirtytwo = 32; +static const unsigned int max_backlog = RXRPC_BACKLOG_MAX - 1; static const unsigned int n_65535 = 65535; static const unsigned int n_max_acks = RXRPC_RXTX_BUFF_SIZE - 1; static const unsigned long one_jiffy = 1; @@ -89,7 +89,7 @@ static struct ctl_table rxrpc_sysctl_table[] = { .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = (void *)&four, - .extra2 = (void *)&thirtytwo, + .extra2 = (void *)&max_backlog, }, { .procname = "rx_window_size",
From: David Howells dhowells@redhat.com
[ Upstream commit 114af61f88fbe34d641b13922d098ffec4c1be1b ]
rxrpc has a timer to trigger resending of unacked data packets in a call. This is not cancelled when a client call switches to the receive phase on the basis that most calls don't last long enough for it to ever expire. However, if it *does* expire after we've started to receive the reply, we shouldn't then go into trying to retransmit or pinging the server to find out if an ack got lost.
Fix this by skipping the resend code if we're into receiving the reply to a client call.
Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both") Signed-off-by: David Howells dhowells@redhat.com cc: linux-afs@lists.infradead.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/call_event.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/rxrpc/call_event.c b/net/rxrpc/call_event.c index e426f6831aab..f8ecad2b730e 100644 --- a/net/rxrpc/call_event.c +++ b/net/rxrpc/call_event.c @@ -406,7 +406,8 @@ void rxrpc_process_call(struct work_struct *work) goto recheck_state; }
- if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events)) { + if (test_and_clear_bit(RXRPC_CALL_EV_RESEND, &call->events) && + call->state != RXRPC_CALL_CLIENT_RECV_REPLY) { rxrpc_resend(call, now); goto recheck_state; }
From: David Howells dhowells@redhat.com
[ Upstream commit 8940ba3cfe4841928777fd45eaa92051522c7f0c ]
Fix accidental overlapping of Rx-phase ACK accounting with Tx-phase ACK accounting through variables shared between the two. call->acks_* members refer to ACKs received in the Tx phase and call->ackr_* members to ACKs sent/to be sent during the Rx phase.
Fixes: 1a2391c30c0b ("rxrpc: Fix detection of out of order acks") Signed-off-by: David Howells dhowells@redhat.com cc: Jeffrey Altman jaltman@auristor.com cc: Marc Dionne marc.dionne@auristor.com cc: linux-afs@lists.infradead.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/ar-internal.h | 7 ++++--- net/rxrpc/input.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 422558d50571..cc1fe6d00eca 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -676,10 +676,9 @@ struct rxrpc_call {
spinlock_t input_lock; /* Lock for packet input to this call */
- /* receive-phase ACK management */ + /* Receive-phase ACK management (ACKs we send). */ u8 ackr_reason; /* reason to ACK */ rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ - rxrpc_serial_t ackr_first_seq; /* first sequence number received */ rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ @@ -692,8 +691,10 @@ struct rxrpc_call { #define RXRPC_CALL_RTT_AVAIL_MASK 0xf #define RXRPC_CALL_RTT_PEND_SHIFT 8
- /* transmission-phase ACK management */ + /* Transmission-phase ACK management (ACKs we've received). */ ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ + rxrpc_seq_t acks_first_seq; /* first sequence number received */ + rxrpc_seq_t acks_prev_seq; /* previous sequence number received */ rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */ rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */ diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 67d3eba60dc7..3da33b5c13b2 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c @@ -812,7 +812,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks, static bool rxrpc_is_ack_valid(struct rxrpc_call *call, rxrpc_seq_t first_pkt, rxrpc_seq_t prev_pkt) { - rxrpc_seq_t base = READ_ONCE(call->ackr_first_seq); + rxrpc_seq_t base = READ_ONCE(call->acks_first_seq);
if (after(first_pkt, base)) return true; /* The window advanced */ @@ -820,7 +820,7 @@ static bool rxrpc_is_ack_valid(struct rxrpc_call *call, if (before(first_pkt, base)) return false; /* firstPacket regressed */
- if (after_eq(prev_pkt, call->ackr_prev_seq)) + if (after_eq(prev_pkt, call->acks_prev_seq)) return true; /* previousPacket hasn't regressed. */
/* Some rx implementations put a serial number in previousPacket. */ @@ -933,8 +933,8 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) /* Discard any out-of-order or duplicate ACKs (outside lock). */ if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial, - first_soft_ack, call->ackr_first_seq, - prev_pkt, call->ackr_prev_seq); + first_soft_ack, call->acks_first_seq, + prev_pkt, call->acks_prev_seq); return; }
@@ -949,14 +949,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb) /* Discard any out-of-order or duplicate ACKs (inside lock). */ if (!rxrpc_is_ack_valid(call, first_soft_ack, prev_pkt)) { trace_rxrpc_rx_discard_ack(call->debug_id, ack_serial, - first_soft_ack, call->ackr_first_seq, - prev_pkt, call->ackr_prev_seq); + first_soft_ack, call->acks_first_seq, + prev_pkt, call->acks_prev_seq); goto out; } call->acks_latest_ts = skb->tstamp;
- call->ackr_first_seq = first_soft_ack; - call->ackr_prev_seq = prev_pkt; + call->acks_first_seq = first_soft_ack; + call->acks_prev_seq = prev_pkt;
/* Parse rwind and mtu sizes if provided. */ if (buf.info.rxMTU)
From: David Howells dhowells@redhat.com
[ Upstream commit 81524b6312535897707f2942695da1d359a5e56b ]
The previousPacket field in the rx ACK packet should never go backwards - it's now the highest DATA sequence number received, not the last on received (it used to be used for out of sequence detection).
Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code") Signed-off-by: David Howells dhowells@redhat.com cc: Marc Dionne marc.dionne@auristor.com cc: linux-afs@lists.infradead.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/ar-internal.h | 4 ++-- net/rxrpc/input.c | 4 +++- net/rxrpc/output.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index cc1fe6d00eca..4ba51e6d3d85 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -679,7 +679,7 @@ struct rxrpc_call { /* Receive-phase ACK management (ACKs we send). */ u8 ackr_reason; /* reason to ACK */ rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ - rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ + rxrpc_seq_t ackr_highest_seq; /* Higest sequence number received */ rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ rxrpc_seq_t ackr_seen; /* Highest packet shown seen */
@@ -694,7 +694,7 @@ struct rxrpc_call { /* Transmission-phase ACK management (ACKs we've received). */ ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ rxrpc_seq_t acks_first_seq; /* first sequence number received */ - rxrpc_seq_t acks_prev_seq; /* previous sequence number received */ + rxrpc_seq_t acks_prev_seq; /* Highest previousPacket received */ rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */ rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */ diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 3da33b5c13b2..680b984ef87f 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c @@ -453,7 +453,6 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) !rxrpc_receiving_reply(call)) goto unlock;
- call->ackr_prev_seq = seq0; hard_ack = READ_ONCE(call->rx_hard_ack);
nr_subpackets = sp->nr_subpackets; @@ -534,6 +533,9 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) ack_serial = serial; }
+ if (after(seq0, call->ackr_highest_seq)) + call->ackr_highest_seq = seq0; + /* Queue the packet. We use a couple of memory barriers here as need * to make sure that rx_top is perceived to be set after the buffer * pointer and that the buffer pointer is set after the annotation and diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index a45c83f22236..46aae9b7006f 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c @@ -89,7 +89,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn, pkt->ack.bufferSpace = htons(8); pkt->ack.maxSkew = htons(0); pkt->ack.firstPacket = htonl(hard_ack + 1); - pkt->ack.previousPacket = htonl(call->ackr_prev_seq); + pkt->ack.previousPacket = htonl(call->ackr_highest_seq); pkt->ack.serial = htonl(serial); pkt->ack.reason = reason; pkt->ack.nAcks = top - hard_ack;
From: David Howells dhowells@redhat.com
[ Upstream commit 9a3dedcf18096e8f7f22b8777d78c4acfdea1651 ]
Fix the decision on when to generate an IDLE ACK by keeping a count of the number of packets we've received, but not yet soft-ACK'd, and the number of packets we've processed, but not yet hard-ACK'd, rather than trying to keep track of which DATA sequence numbers correspond to those points.
We then generate an ACK when either counter exceeds 2. The counters are both cleared when we transcribe the information into any sort of ACK packet for transmission. IDLE and DELAY ACKs are skipped if both counters are 0 (ie. no change).
Fixes: 805b21b929e2 ("rxrpc: Send an ACK after every few DATA packets we receive") Signed-off-by: David Howells dhowells@redhat.com cc: Marc Dionne marc.dionne@auristor.com cc: linux-afs@lists.infradead.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/rxrpc.h | 2 +- net/rxrpc/ar-internal.h | 4 ++-- net/rxrpc/input.c | 11 +++++++++-- net/rxrpc/output.c | 18 +++++++++++------- net/rxrpc/recvmsg.c | 8 +++----- 5 files changed, 26 insertions(+), 17 deletions(-)
diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 4a3ab0ed6e06..1c714336b863 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -1509,7 +1509,7 @@ TRACE_EVENT(rxrpc_call_reset, __entry->call_serial = call->rx_serial; __entry->conn_serial = call->conn->hi_serial; __entry->tx_seq = call->tx_hard_ack; - __entry->rx_seq = call->ackr_seen; + __entry->rx_seq = call->rx_hard_ack; ),
TP_printk("c=%08x %08x:%08x r=%08x/%08x tx=%08x rx=%08x", diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 4ba51e6d3d85..f2d593e27b64 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h @@ -680,8 +680,8 @@ struct rxrpc_call { u8 ackr_reason; /* reason to ACK */ rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ rxrpc_seq_t ackr_highest_seq; /* Higest sequence number received */ - rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ - rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ + atomic_t ackr_nr_unacked; /* Number of unacked packets */ + atomic_t ackr_nr_consumed; /* Number of packets needing hard ACK */
/* RTT management */ rxrpc_serial_t rtt_serial[4]; /* Serial number of DATA or PING sent */ diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 680b984ef87f..3521ebd0ee41 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c @@ -412,8 +412,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) { struct rxrpc_skb_priv *sp = rxrpc_skb(skb); enum rxrpc_call_state state; - unsigned int j, nr_subpackets; - rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0; + unsigned int j, nr_subpackets, nr_unacked = 0; + rxrpc_serial_t serial = sp->hdr.serial, ack_serial = serial; rxrpc_seq_t seq0 = sp->hdr.seq, hard_ack; bool immediate_ack = false, jumbo_bad = false; u8 ack = 0; @@ -569,6 +569,8 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) sp = NULL; }
+ nr_unacked++; + if (last) { set_bit(RXRPC_CALL_RX_LAST, &call->flags); if (!ack) { @@ -588,9 +590,14 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb) } call->rx_expect_next = seq + 1; } + if (!ack) + ack_serial = serial; }
ack: + if (atomic_add_return(nr_unacked, &call->ackr_nr_unacked) > 2 && !ack) + ack = RXRPC_ACK_IDLE; + if (ack) rxrpc_propose_ACK(call, ack, ack_serial, immediate_ack, true, diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index 46aae9b7006f..9683617db704 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c @@ -74,11 +74,18 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn, u8 reason) { rxrpc_serial_t serial; + unsigned int tmp; rxrpc_seq_t hard_ack, top, seq; int ix; u32 mtu, jmax; u8 *ackp = pkt->acks;
+ tmp = atomic_xchg(&call->ackr_nr_unacked, 0); + tmp |= atomic_xchg(&call->ackr_nr_consumed, 0); + if (!tmp && (reason == RXRPC_ACK_DELAY || + reason == RXRPC_ACK_IDLE)) + return 0; + /* Barrier against rxrpc_input_data(). */ serial = call->ackr_serial; hard_ack = READ_ONCE(call->rx_hard_ack); @@ -223,6 +230,10 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping, n = rxrpc_fill_out_ack(conn, call, pkt, &hard_ack, &top, reason);
spin_unlock_bh(&call->lock); + if (n == 0) { + kfree(pkt); + return 0; + }
iov[0].iov_base = pkt; iov[0].iov_len = sizeof(pkt->whdr) + sizeof(pkt->ack) + n; @@ -259,13 +270,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping, ntohl(pkt->ack.serial), false, true, rxrpc_propose_ack_retry_tx); - } else { - spin_lock_bh(&call->lock); - if (after(hard_ack, call->ackr_consumed)) - call->ackr_consumed = hard_ack; - if (after(top, call->ackr_seen)) - call->ackr_seen = top; - spin_unlock_bh(&call->lock); }
rxrpc_set_keepalive(call); diff --git a/net/rxrpc/recvmsg.c b/net/rxrpc/recvmsg.c index eca6dda26c77..250f23bc1c07 100644 --- a/net/rxrpc/recvmsg.c +++ b/net/rxrpc/recvmsg.c @@ -260,11 +260,9 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call) rxrpc_end_rx_phase(call, serial); } else { /* Check to see if there's an ACK that needs sending. */ - if (after_eq(hard_ack, call->ackr_consumed + 2) || - after_eq(top, call->ackr_seen + 2) || - (hard_ack == top && after(hard_ack, call->ackr_consumed))) - rxrpc_propose_ACK(call, RXRPC_ACK_DELAY, serial, - true, true, + if (atomic_inc_return(&call->ackr_nr_consumed) > 2) + rxrpc_propose_ACK(call, RXRPC_ACK_IDLE, serial, + true, false, rxrpc_propose_ack_rotate_rx); if (call->ackr_reason && call->ackr_reason != RXRPC_ACK_DELAY) rxrpc_send_ack_packet(call, false, NULL);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 15d221d0c345b76947911a3ac91897ffe2f1cc4e ]
'prod_idx' (atomic_t) is larger than 'shadow_idx' (u16), so some memory is over-allocated.
Fixes: b15a9f37be2b ("net-next/hinic: Add wq") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c index f7dc7d825f63..4daf6bf291ec 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c @@ -386,7 +386,7 @@ static int alloc_wqes_shadow(struct hinic_wq *wq) return -ENOMEM;
wq->shadow_idx = devm_kcalloc(&pdev->dev, wq->num_q_pages, - sizeof(wq->prod_idx), GFP_KERNEL); + sizeof(*wq->shadow_idx), GFP_KERNEL); if (!wq->shadow_idx) goto err_shadow_idx;
From: Ioana Ciornei ioana.ciornei@nxp.com
[ Upstream commit 06d129946a71f3159b3b40ee95549183edf2c79d ]
The TSO header was DMA unmapped before the virtual address was retrieved and then used to free the buffer. This meant that we were actually removing the DMA map and then trying to search for it to help in retrieving the virtual address. This lead to a invalid virtual address being used in the kfree call.
Fix this by calling dpaa2_iova_to_virt() prior to the dma_unmap call.
[ 487.231819] Unable to handle kernel paging request at virtual address fffffd9807000008
(...)
[ 487.354061] Hardware name: SolidRun LX2160A Honeycomb (DT) [ 487.359535] pstate: a0400005 (NzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 487.366485] pc : kfree+0xac/0x304 [ 487.369799] lr : kfree+0x204/0x304 [ 487.373191] sp : ffff80000c4eb120 [ 487.376493] x29: ffff80000c4eb120 x28: ffff662240c46400 x27: 0000000000000001 [ 487.383621] x26: 0000000000000001 x25: ffff662246da0cc0 x24: ffff66224af78000 [ 487.390748] x23: ffffad184f4ce008 x22: ffffad1850185000 x21: ffffad1838d13cec [ 487.397874] x20: ffff6601c0000000 x19: fffffd9807000000 x18: 0000000000000000 [ 487.405000] x17: ffffb910cdc49000 x16: ffffad184d7d9080 x15: 0000000000004000 [ 487.412126] x14: 0000000000000008 x13: 000000000000ffff x12: 0000000000000000 [ 487.419252] x11: 0000000000000004 x10: 0000000000000001 x9 : ffffad184d7d927c [ 487.426379] x8 : 0000000000000000 x7 : 0000000ffffffd1d x6 : ffff662240a94900 [ 487.433505] x5 : 0000000000000003 x4 : 0000000000000009 x3 : ffffad184f4ce008 [ 487.440632] x2 : ffff662243eec000 x1 : 0000000100000100 x0 : fffffc0000000000 [ 487.447758] Call trace: [ 487.450194] kfree+0xac/0x304 [ 487.453151] dpaa2_eth_free_tx_fd.isra.0+0x33c/0x3e0 [fsl_dpaa2_eth] [ 487.459507] dpaa2_eth_tx_conf+0x100/0x2e0 [fsl_dpaa2_eth] [ 487.464989] dpaa2_eth_poll+0xdc/0x380 [fsl_dpaa2_eth]
Fixes: 3dc709e0cd47 ("dpaa2-eth: add support for software TSO") Link: https://bugzilla.kernel.org/show_bug.cgi?id=215886 Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 4b047255d928..766391310d1b 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1097,6 +1097,7 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, u32 fd_len = dpaa2_fd_get_len(fd); struct dpaa2_sg_entry *sgt; int should_free_skb = 1; + void *tso_hdr; int i;
fd_addr = dpaa2_fd_get_addr(fd); @@ -1136,9 +1137,10 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, priv->tx_data_offset);
/* Unmap and free the header */ + tso_hdr = dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt)); dma_unmap_single(dev, dpaa2_sg_get_addr(sgt), TSO_HEADER_SIZE, DMA_TO_DEVICE); - kfree(dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt))); + kfree(tso_hdr);
/* Unmap the other SG entries for the data */ for (i = 1; i < swa->tso.num_sg; i++)
From: Ioana Ciornei ioana.ciornei@nxp.com
[ Upstream commit d5f4e19a85670b4e5697654f4a4e086e064f8a47 ]
The incorrect software annotation field was being used, swa->sg.sgt_size instead of swa->tso.sgt_size, which meant that the SGT buffer was unmapped with a wrong size. This is also confirmed by the DMA API debug prints which showed the following:
[ 38.962434] DMA-API: fsl_dpaa2_eth dpni.2: device driver frees DMA memory with different size [device address=0x0000fffffafba740] [map size=224 bytes] [unmap size=0 bytes] [ 38.980496] WARNING: CPU: 11 PID: 1131 at kernel/dma/debug.c:973 check_unmap+0x58c/0x9b0 [ 38.988586] Modules linked in: [ 38.991631] CPU: 11 PID: 1131 Comm: iperf3 Not tainted 5.18.0-rc7-00117-g59130eeb2b8f #1972 [ 38.999970] Hardware name: NXP Layerscape LX2160ARDB (DT)
Fixes: 3dc709e0cd47 ("dpaa2-eth: add support for software TSO") Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 766391310d1b..f1f140277184 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1148,7 +1148,7 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, dpaa2_sg_get_len(&sgt[i]), DMA_TO_DEVICE);
/* Unmap the SGT buffer */ - dma_unmap_single(dev, fd_addr, swa->sg.sgt_size, + dma_unmap_single(dev, fd_addr, swa->tso.sgt_size, DMA_BIDIRECTIONAL);
if (!swa->tso.is_last_fd)
From: Ioana Ciornei ioana.ciornei@nxp.com
[ Upstream commit 0a09c5b8cb8f75344da7d90c771b84f7cdeaea04 ]
DMA unmap the Scatter/Gather table before going through the array to unmap and free each of the header and data chunks. This is so we do not touch the data between the dma_map and dma_unmap calls.
Fixes: 3dc709e0cd47 ("dpaa2-eth: add support for software TSO") Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index f1f140277184..cd9ec80522e7 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1136,6 +1136,10 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, sgt = (struct dpaa2_sg_entry *)(buffer_start + priv->tx_data_offset);
+ /* Unmap the SGT buffer */ + dma_unmap_single(dev, fd_addr, swa->tso.sgt_size, + DMA_BIDIRECTIONAL); + /* Unmap and free the header */ tso_hdr = dpaa2_iova_to_virt(priv->iommu_domain, dpaa2_sg_get_addr(sgt)); dma_unmap_single(dev, dpaa2_sg_get_addr(sgt), TSO_HEADER_SIZE, @@ -1147,10 +1151,6 @@ static void dpaa2_eth_free_tx_fd(struct dpaa2_eth_priv *priv, dma_unmap_single(dev, dpaa2_sg_get_addr(&sgt[i]), dpaa2_sg_get_len(&sgt[i]), DMA_TO_DEVICE);
- /* Unmap the SGT buffer */ - dma_unmap_single(dev, fd_addr, swa->tso.sgt_size, - DMA_BIDIRECTIONAL); - if (!swa->tso.is_last_fd) should_free_skb = 0; } else {
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 0a3ad7d323686fbaae8688326cc5ea0d185c6fca ]
Since kconfig 'select' does not follow dependency chains, if symbol KSA selects KSB, then KSA should also depend on the same symbols that KSB depends on, in order to prevent Kconfig warnings and possible build errors.
Change NET_DSA_SMSC_LAN9303_I2C and NET_DSA_SMSC_LAN9303_MDIO so that they are limited to VLAN_8021Q if the latter is enabled. This prevents the Kconfig warning:
WARNING: unmet direct dependencies detected for NET_DSA_SMSC_LAN9303 Depends on [m]: NETDEVICES [=y] && NET_DSA [=y] && (VLAN_8021Q [=m] || VLAN_8021Q [=m]=n) Selected by [y]: - NET_DSA_SMSC_LAN9303_I2C [=y] && NETDEVICES [=y] && NET_DSA [=y] && I2C [=y]
Fixes: 430065e26719 ("net: dsa: lan9303: add VLAN IDs to master device") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Andrew Lunn andrew@lunn.ch Cc: Vivien Didelot vivien.didelot@gmail.com Cc: Florian Fainelli f.fainelli@gmail.com Cc: Vladimir Oltean olteanv@gmail.com Cc: Juergen Borleis jbe@pengutronix.de Cc: "David S. Miller" davem@davemloft.net Cc: Eric Dumazet edumazet@google.com Cc: Jakub Kicinski kuba@kernel.org Cc: Paolo Abeni pabeni@redhat.com Cc: Mans Rullgard mans@mansr.com Reviewed-by: Vladimir Oltean olteanv@gmail.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 37a3dabdce31..6d1fcb08bba1 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -72,7 +72,6 @@ source "drivers/net/dsa/realtek/Kconfig"
config NET_DSA_SMSC_LAN9303 tristate - depends on VLAN_8021Q || VLAN_8021Q=n select NET_DSA_TAG_LAN9303 select REGMAP help @@ -82,6 +81,7 @@ config NET_DSA_SMSC_LAN9303 config NET_DSA_SMSC_LAN9303_I2C tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in I2C managed mode" depends on I2C + depends on VLAN_8021Q || VLAN_8021Q=n select NET_DSA_SMSC_LAN9303 select REGMAP_I2C help @@ -91,6 +91,7 @@ config NET_DSA_SMSC_LAN9303_I2C config NET_DSA_SMSC_LAN9303_MDIO tristate "SMSC/Microchip LAN9303 3-ports 10/100 ethernet switch in MDIO managed mode" select NET_DSA_SMSC_LAN9303 + depends on VLAN_8021Q || VLAN_8021Q=n help Enable access functions if the SMSC/Microchip LAN9303 is configured for MDIO managed mode.
From: liuyacan liuyacan@corp.netease.com
[ Upstream commit 75c1edf23b95a9c66923d9269d8e86e4dbde151f ]
Same trigger condition as commit 86434744. When setsockopt runs in parallel to a connect(), and switch the socket into fallback mode. Then the sk_refcnt is incremented in smc_connect(), but its state stay in SMC_INIT (NOT SMC_ACTIVE). This cause the corresponding sk_refcnt decrement in __smc_release() will not be performed.
Fixes: 86434744fedf ("net/smc: add fallback check to connect()") Signed-off-by: liuyacan liuyacan@corp.netease.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/smc/af_smc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index fce16b9d6e1a..45a24d24210f 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -1564,9 +1564,9 @@ static int smc_connect(struct socket *sock, struct sockaddr *addr, if (rc && rc != -EINPROGRESS) goto out;
- sock_hold(&smc->sk); /* sock put in passive closing */ if (smc->use_fallback) goto out; + sock_hold(&smc->sk); /* sock put in passive closing */ if (flags & O_NONBLOCK) { if (queue_work(smc_hs_wq, &smc->connect_work)) smc->connect_nonblock = 1;
From: liuyacan liuyacan@corp.netease.com
[ Upstream commit 8c3b8dc5cc9bf6d273ebe18b16e2d6882bcfb36d ]
In the process of checking whether RDMAv2 is available, the current implementation first sets ini->smcrv2.ib_dev_v2, and then allocates smc buf desc, but the latter may fail. Unfortunately, the caller will only check the former. In this case, a NULL pointer reference will occur in smc_clc_send_confirm_accept() when accessing conn->rmb_desc.
This patch does two things: 1. Use the return code to determine whether V2 is available. 2. If the return code is NODEV, continue to check whether V1 is available.
Fixes: e49300a6bf62 ("net/smc: add listen processing for SMC-Rv2") Signed-off-by: liuyacan liuyacan@corp.netease.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/smc/af_smc.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 45a24d24210f..d3de54b70c05 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -2093,13 +2093,13 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first) return 0; }
-static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, - struct smc_clc_msg_proposal *pclc, - struct smc_init_info *ini) +static int smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, + struct smc_clc_msg_proposal *pclc, + struct smc_init_info *ini) { struct smc_clc_v2_extension *smc_v2_ext; u8 smcr_version; - int rc; + int rc = 0;
if (!(ini->smcr_version & SMC_V2) || !smcr_indicated(ini->smc_type_v2)) goto not_found; @@ -2117,26 +2117,31 @@ static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, ini->smcrv2.saddr = new_smc->clcsock->sk->sk_rcv_saddr; ini->smcrv2.daddr = smc_ib_gid_to_ipv4(smc_v2_ext->roce); rc = smc_find_rdma_device(new_smc, ini); - if (rc) { - smc_find_ism_store_rc(rc, ini); + if (rc) goto not_found; - } + if (!ini->smcrv2.uses_gateway) memcpy(ini->smcrv2.nexthop_mac, pclc->lcl.mac, ETH_ALEN);
smcr_version = ini->smcr_version; ini->smcr_version = SMC_V2; rc = smc_listen_rdma_init(new_smc, ini); - if (!rc) - rc = smc_listen_rdma_reg(new_smc, ini->first_contact_local); - if (!rc) - return; - ini->smcr_version = smcr_version; - smc_find_ism_store_rc(rc, ini); + if (rc) { + ini->smcr_version = smcr_version; + goto not_found; + } + rc = smc_listen_rdma_reg(new_smc, ini->first_contact_local); + if (rc) { + ini->smcr_version = smcr_version; + goto not_found; + } + return 0;
not_found: + rc = rc ?: SMC_CLC_DECL_NOSMCDEV; ini->smcr_version &= ~SMC_V2; ini->check_smcrv2 = false; + return rc; }
static int smc_find_rdma_v1_device_serv(struct smc_sock *new_smc, @@ -2169,6 +2174,7 @@ static int smc_listen_find_device(struct smc_sock *new_smc, struct smc_init_info *ini) { int prfx_rc; + int rc;
/* check for ISM device matching V2 proposed device */ smc_find_ism_v2_device_serv(new_smc, pclc, ini); @@ -2196,14 +2202,18 @@ static int smc_listen_find_device(struct smc_sock *new_smc, return ini->rc ?: SMC_CLC_DECL_NOSMCDDEV;
/* check if RDMA V2 is available */ - smc_find_rdma_v2_device_serv(new_smc, pclc, ini); - if (ini->smcrv2.ib_dev_v2) + rc = smc_find_rdma_v2_device_serv(new_smc, pclc, ini); + if (!rc) return 0;
+ /* skip V1 check if V2 is unavailable for non-Device reason */ + if (rc != SMC_CLC_DECL_NOSMCDEV && + rc != SMC_CLC_DECL_NOSMCRDEV && + rc != SMC_CLC_DECL_NOSMCDDEV) + return rc; + /* check if RDMA V1 is available */ if (!prfx_rc) { - int rc; - rc = smc_find_rdma_v1_device_serv(new_smc, pclc, ini); smc_find_ism_store_rc(rc, ini); return (!rc) ? 0 : ini->rc;
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit 4a37f3dd9a83186cb88d44808ab35b78375082c9 ]
The original x86 sev_alloc() only called set_memory_decrypted() on memory returned by alloc_pages_node(), so the page order calculation fell out of that logic. However, the common dma-direct code has several potential allocators, not all of which are guaranteed to round up the underlying allocation to a power-of-two size, so carrying over that calculation for the encryption/decryption size was a mistake. Fix it by rounding to a *number* of pages, rather than an order.
Until recently there was an even worse interaction with DMA_DIRECT_REMAP where we could have ended up decrypting part of the next adjacent vmalloc area, only averted by no architecture actually supporting both configs at once. Don't ask how I found that one out...
Fixes: c10f07aa27da ("dma/direct: Handle force decryption for DMA coherent buffers in common code") Signed-off-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Christoph Hellwig hch@lst.de Acked-by: David Rientjes rientjes@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/direct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index 3e7f4aab740e..e978f36e6be8 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -79,7 +79,7 @@ static int dma_set_decrypted(struct device *dev, void *vaddr, size_t size) { if (!force_dma_unencrypted(dev)) return 0; - return set_memory_decrypted((unsigned long)vaddr, 1 << get_order(size)); + return set_memory_decrypted((unsigned long)vaddr, PFN_UP(size)); }
static int dma_set_encrypted(struct device *dev, void *vaddr, size_t size) @@ -88,7 +88,7 @@ static int dma_set_encrypted(struct device *dev, void *vaddr, size_t size)
if (!force_dma_unencrypted(dev)) return 0; - ret = set_memory_encrypted((unsigned long)vaddr, 1 << get_order(size)); + ret = set_memory_encrypted((unsigned long)vaddr, PFN_UP(size)); if (ret) pr_warn_ratelimited("leaking DMA memory that can't be re-encrypted\n"); return ret;
From: Luiz Augusto von Dentz luiz.von.dentz@intel.com
[ Upstream commit c9f73a2178c12fb24d2807634209559d6a836e08 ]
The handling of connection failures shall be handled by the request completion callback as already done by hci_cs_le_create_conn, also make sure to use hci_conn_failed instead of hci_le_conn_failed as the later don't actually call hci_conn_del to cleanup.
Link: https://github.com/bluez/bluez/issues/340 Fixes: 8e8b92ee60de5 ("Bluetooth: hci_sync: Add hci_le_create_conn_sync") Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/hci_conn.c | 5 +++-- net/bluetooth/hci_event.c | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 882a7df13005..ac06c9724c7f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -943,10 +943,11 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
bt_dev_err(hdev, "request failed to create LE connection: err %d", err);
- if (!conn) + /* Check if connection is still pending */ + if (conn != hci_lookup_le_connect(hdev)) goto done;
- hci_le_conn_failed(conn, err); + hci_conn_failed(conn, err);
done: hci_dev_unlock(hdev); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0270e597c285..af17dfb20e01 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -5632,10 +5632,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, status = HCI_ERROR_INVALID_PARAMETERS; }
- if (status) { - hci_conn_failed(conn, status); + /* All connection failure handling is taken care of by the + * hci_conn_failed function which is triggered by the HCI + * request completion callbacks used for connecting. + */ + if (status) goto unlock; - }
if (conn->dst_type == ADDR_LE_DEV_PUBLIC) addr_type = BDADDR_LE_PUBLIC;
From: liuyacan liuyacan@corp.netease.com
[ Upstream commit 9029ac03f20a5999bc5627277c6cf008ab8e23ed ]
This reverts commit 8c3b8dc5cc9bf6d273ebe18b16e2d6882bcfb36d.
Some rollback issue will be fixed in other patches in the future.
Link: https://lore.kernel.org/all/20220523055056.2078994-1-liuyacan@corp.netease.c...
Fixes: 8c3b8dc5cc9b ("net/smc: fix listen processing for SMC-Rv2") Signed-off-by: liuyacan liuyacan@corp.netease.com Link: https://lore.kernel.org/r/20220524090230.2140302-1-liuyacan@corp.netease.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/smc/af_smc.c | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index d3de54b70c05..45a24d24210f 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -2093,13 +2093,13 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, bool local_first) return 0; }
-static int smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, - struct smc_clc_msg_proposal *pclc, - struct smc_init_info *ini) +static void smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, + struct smc_clc_msg_proposal *pclc, + struct smc_init_info *ini) { struct smc_clc_v2_extension *smc_v2_ext; u8 smcr_version; - int rc = 0; + int rc;
if (!(ini->smcr_version & SMC_V2) || !smcr_indicated(ini->smc_type_v2)) goto not_found; @@ -2117,31 +2117,26 @@ static int smc_find_rdma_v2_device_serv(struct smc_sock *new_smc, ini->smcrv2.saddr = new_smc->clcsock->sk->sk_rcv_saddr; ini->smcrv2.daddr = smc_ib_gid_to_ipv4(smc_v2_ext->roce); rc = smc_find_rdma_device(new_smc, ini); - if (rc) + if (rc) { + smc_find_ism_store_rc(rc, ini); goto not_found; - + } if (!ini->smcrv2.uses_gateway) memcpy(ini->smcrv2.nexthop_mac, pclc->lcl.mac, ETH_ALEN);
smcr_version = ini->smcr_version; ini->smcr_version = SMC_V2; rc = smc_listen_rdma_init(new_smc, ini); - if (rc) { - ini->smcr_version = smcr_version; - goto not_found; - } - rc = smc_listen_rdma_reg(new_smc, ini->first_contact_local); - if (rc) { - ini->smcr_version = smcr_version; - goto not_found; - } - return 0; + if (!rc) + rc = smc_listen_rdma_reg(new_smc, ini->first_contact_local); + if (!rc) + return; + ini->smcr_version = smcr_version; + smc_find_ism_store_rc(rc, ini);
not_found: - rc = rc ?: SMC_CLC_DECL_NOSMCDEV; ini->smcr_version &= ~SMC_V2; ini->check_smcrv2 = false; - return rc; }
static int smc_find_rdma_v1_device_serv(struct smc_sock *new_smc, @@ -2174,7 +2169,6 @@ static int smc_listen_find_device(struct smc_sock *new_smc, struct smc_init_info *ini) { int prfx_rc; - int rc;
/* check for ISM device matching V2 proposed device */ smc_find_ism_v2_device_serv(new_smc, pclc, ini); @@ -2202,18 +2196,14 @@ static int smc_listen_find_device(struct smc_sock *new_smc, return ini->rc ?: SMC_CLC_DECL_NOSMCDDEV;
/* check if RDMA V2 is available */ - rc = smc_find_rdma_v2_device_serv(new_smc, pclc, ini); - if (!rc) + smc_find_rdma_v2_device_serv(new_smc, pclc, ini); + if (ini->smcrv2.ib_dev_v2) return 0;
- /* skip V1 check if V2 is unavailable for non-Device reason */ - if (rc != SMC_CLC_DECL_NOSMCDEV && - rc != SMC_CLC_DECL_NOSMCRDEV && - rc != SMC_CLC_DECL_NOSMCDDEV) - return rc; - /* check if RDMA V1 is available */ if (!prfx_rc) { + int rc; + rc = smc_find_rdma_v1_device_serv(new_smc, pclc, ini); smc_find_ism_store_rc(rc, ini); return (!rc) ? 0 : ini->rc;
From: Sean Young sean@mess.org
[ Upstream commit e5499dd7253c8382d03f687f19a854adcc688357 ]
Commit b2a90f4fcb14 ("media: lirc: remove unused lirc features") removed feature flags which were never implemented, but they are still used by the lirc daemon went built from source.
Reinstate these symbols in order not to break the lirc build.
Fixes: b2a90f4fcb14 ("media: lirc: remove unused lirc features") Link: https://lore.kernel.org/all/a0470450-ecfd-2918-e04a-7b57c1fd7694@kernel.org/ Reported-by: Jiri Slaby jirislaby@kernel.org Cc: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Sean Young sean@mess.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/lirc.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index 23b0f2c8ba81..8d7ca7c6af42 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h @@ -84,6 +84,13 @@ #define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) #define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
+/* + * Unused features. These features were never implemented, in tree or + * out of tree. These definitions are here so not to break the lircd build. + */ +#define LIRC_CAN_SET_REC_FILTER 0 +#define LIRC_CAN_NOTIFY_DECODE 0 + /*** IOCTL commands for lirc driver ***/
#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32)
From: Shawn Lin shawn.lin@rock-chips.com
[ Upstream commit 4246d0bab2a8685e3d4aec2cb0ef8c526689ce96 ]
drive-impedance-ohm is introduced for emmc phy instead of pcie phy.
Fixes: fb8b7460c995 ("arm64: dts: rockchip: Define drive-impedance-ohm for RK3399's emmc-phy.") Signed-off-by: Shawn Lin shawn.lin@rock-chips.com Link: https://lore.kernel.org/r/1647336426-154797-1-git-send-email-shawn.lin@rock-... Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 080457a68e3c..88f26d89eea1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1534,6 +1534,7 @@ reg = <0xf780 0x24>; clocks = <&sdhci>; clock-names = "emmcclk"; + drive-impedance-ohm = <50>; #phy-cells = <0>; status = "disabled"; }; @@ -1544,7 +1545,6 @@ clock-names = "refclk"; #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; - drive-impedance-ohm = <50>; reset-names = "phy"; status = "disabled"; };
From: Allen-KH Cheng allen-kh.cheng@mediatek.com
[ Upstream commit 27f0eb16b0d417c155e96b5d3b89074699944e09 ]
Correct nor_flash status disable typo of mt8192 SoC.
Fixes: d0a197a0d064a ("arm64: dts: mt8192: add nor_flash device node")
Signed-off-by: Allen-KH Cheng allen-kh.cheng@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Miles Chen miles.chen@mediatek.com Reviewed-by: Nícolas F. R. A. Prado nfraprado@collabora.com Link: https://lore.kernel.org/r/20220318144534.17996-11-allen-kh.cheng@mediatek.co... 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 411feb294613..bcecc7484453 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi @@ -679,7 +679,7 @@ assigned-clock-parents = <&clk26m>; #address-cells = <1>; #size-cells = <0>; - status = "disable"; + status = "disabled"; };
audsys: clock-controller@11210000 {
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit dff6139015dc68e93be3822a7bd406a1d138628b ]
acpi_pci_bridge_d3(dev) returns "true" if "dev" is a hotplug bridge that can handle hotplug events while in D3. Previously this meant either:
- "dev" has a _PS0 or _PR0 method (acpi_pci_power_manageable()), or
- The Root Port above "dev" has a _DSD with a "HotPlugSupportInD3" property with value 1.
This did not consider _PRW, which tells us about wakeup GPEs (ACPI v6.4, sec 7.3.13). Without a wakeup GPE, from an ACPI perspective the Root Port has no way of generating wakeup signals, so hotplug events will be lost if we use D3.
Similarly, it did not consider _S0W, which tells us the deepest D-state from which a device can wake itself (sec 7.3.20). If _S0W tells us the device cannot wake from D3, hotplug events will again be lost if we use D3.
Some platforms, e.g., AMD Yellow Carp, supply "HotPlugSupportInD3" without _PRW or with an _S0W that says the Root Port cannot wake from D3. On those platforms, we previously put bridges in D3hot, hotplug events were lost, and hotplugged devices would not be recognized without manually rescanning.
Allow bridges to be put in D3 only if the Root Port can generate wakeup GPEs (wakeup.flags.valid), it can wake from D3 (_S0W), AND it has the "HotPlugSupportInD3" property.
Neither Windows 10 nor Windows 11 puts the bridge in D3 when the firmware is configured this way, and this change aligns the handling of the situation to be the same.
[bhelgaas: commit log, tidy "HotPlugSupportInD3" check and comment] Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/07_Power_and_Performance_Mgmt/... Link: https://docs.microsoft.com/en-us/windows-hardware/drivers/pci/dsd-for-pcie-r... Link: https://lore.kernel.org/r/20220401034003.3166-1-mario.limonciello@amd.com Fixes: 26ad34d510a87 ("PCI / ACPI: Whitelist D3 for more PCIe hotplug ports") Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci-acpi.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 1f15ab7eabf8..3ae435beaf0a 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -974,9 +974,11 @@ bool acpi_pci_power_manageable(struct pci_dev *dev)
bool acpi_pci_bridge_d3(struct pci_dev *dev) { - const union acpi_object *obj; - struct acpi_device *adev; struct pci_dev *rpdev; + struct acpi_device *adev; + acpi_status status; + unsigned long long state; + const union acpi_object *obj;
if (acpi_pci_disabled || !dev->is_hotplug_bridge) return false; @@ -985,12 +987,6 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev) if (acpi_pci_power_manageable(dev)) return true;
- /* - * The ACPI firmware will provide the device-specific properties through - * _DSD configuration object. Look for the 'HotPlugSupportInD3' property - * for the root port and if it is set we know the hierarchy behind it - * supports D3 just fine. - */ rpdev = pcie_find_root_port(dev); if (!rpdev) return false; @@ -999,11 +995,34 @@ bool acpi_pci_bridge_d3(struct pci_dev *dev) if (!adev) return false;
- if (acpi_dev_get_property(adev, "HotPlugSupportInD3", - ACPI_TYPE_INTEGER, &obj) < 0) + /* + * If the Root Port cannot signal wakeup signals at all, i.e., it + * doesn't supply a wakeup GPE via _PRW, it cannot signal hotplug + * events from low-power states including D3hot and D3cold. + */ + if (!adev->wakeup.flags.valid) return false;
- return obj->integer.value == 1; + /* + * If the Root Port cannot wake itself from D3hot or D3cold, we + * can't use D3. + */ + status = acpi_evaluate_integer(adev->handle, "_S0W", NULL, &state); + if (ACPI_SUCCESS(status) && state < ACPI_STATE_D3_HOT) + return false; + + /* + * The "HotPlugSupportInD3" property in a Root Port _DSD indicates + * the Port can signal hotplug events while in D3. We assume any + * bridges *below* that Root Port can also signal hotplug events + * while in D3. + */ + if (!acpi_dev_get_property(adev, "HotPlugSupportInD3", + ACPI_TYPE_INTEGER, &obj) && + obj->integer.value == 1) + return true; + + return false; }
int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 56653827f0d7bc7c2d8bac0e119fd1521fa9990a ]
'dmc->counter' is a 'struct devfreq_event_dev **', so there is some over memory allocation. 'counters_size' should be computed with 'sizeof(struct devfreq_event_dev *)'.
Use 'sizeof(*dmc->counter)' instead to fix it.
While at it, use devm_kcalloc() instead of devm_kzalloc()+open coded multiplication.
Fixes: 6e7674c3c6df ("memory: Add DMC driver for Exynos5422") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/69d7e69346986e2fdb994d4382954c932f9f0993.164776021... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memory/samsung/exynos5422-dmc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c index 9c8318923ed0..4733e7898ffe 100644 --- a/drivers/memory/samsung/exynos5422-dmc.c +++ b/drivers/memory/samsung/exynos5422-dmc.c @@ -1322,7 +1322,6 @@ static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc) */ static int exynos5_performance_counters_init(struct exynos5_dmc *dmc) { - int counters_size; int ret, i;
dmc->num_counters = devfreq_event_get_edev_count(dmc->dev, @@ -1332,8 +1331,8 @@ static int exynos5_performance_counters_init(struct exynos5_dmc *dmc) return dmc->num_counters; }
- counters_size = sizeof(struct devfreq_event_dev) * dmc->num_counters; - dmc->counter = devm_kzalloc(dmc->dev, counters_size, GFP_KERNEL); + dmc->counter = devm_kcalloc(dmc->dev, dmc->num_counters, + sizeof(*dmc->counter), GFP_KERNEL); if (!dmc->counter) return -ENOMEM;
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit 130b5e32ba9d2d2313e39cf3f6d0729bff02b76a ]
This fixes: arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: cru-bus@100: 'pin-controller@1c0' does not match any of the regexes: '^clock-controller@[a-f0-9]+$', '^phy@[a-f0-9]+$', '^pinctrl@[a-f0-9]+$', '^syscon@[a-f0-9]+$', '^thermal@[a-f0-9]+$' From schema: Documentation/devicetree/bindings/mfd/brcm,cru.yaml arch/arm/boot/dts/bcm4708-asus-rt-ac56u.dtb: pin-controller@1c0: $nodename:0: 'pin-controller@1c0' does not match '^(pinctrl|pinmux)(@[0-9a-f]+)?$' From schema: Documentation/devicetree/bindings/pinctrl/brcm,ns-pinmux.yaml
Ref: e7391b021e3f ("dt-bindings: mfd: brcm,cru: Rename pinctrl node") Signed-off-by: Rafał Miłecki rafal@milecki.pl Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm5301x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index 603c700c706f..65f8a759f1e3 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -455,7 +455,7 @@ reg = <0x180 0x4>; };
- pinctrl: pin-controller@1c0 { + pinctrl: pinctrl@1c0 { compatible = "brcm,bcm4708-pinmux"; reg = <0x1c0 0x24>; reg-names = "cru_gpio_control";
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit 01a850ee61cbf0ab77dcbf26bb133fec2dd640d6 ]
The F1C100 series of SoCs actually have their watchdog IP being compatible with the newer Allwinner generation, not the older one.
The currently described sun4i-a10-wdt actually does not work, neither the watchdog functionality (just never fires), nor the reset part (reboot hangs).
Replace the compatible string with the one used by the newer generation. Verified to work with both the watchdog and reboot functionality on a LicheePi Nano.
Also add the missing interrupt line and clock source, to make it binding compliant.
Fixes: 4ba16d17efdd ("ARM: dts: suniv: add initial DTSI file for F1C100s") Signed-off-by: Andre Przywara andre.przywara@arm.com Acked-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Link: https://lore.kernel.org/r/20220317162349.739636-4-andre.przywara@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/suniv-f1c100s.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi index 6100d3b75f61..def830101448 100644 --- a/arch/arm/boot/dts/suniv-f1c100s.dtsi +++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi @@ -104,8 +104,10 @@
wdt: watchdog@1c20ca0 { compatible = "allwinner,suniv-f1c100s-wdt", - "allwinner,sun4i-a10-wdt"; + "allwinner,sun6i-a31-wdt"; reg = <0x01c20ca0 0x20>; + interrupts = <16>; + clocks = <&osc32k>; };
uart0: serial@1c25000 {
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 8fd3f18ea31a398ecce4a6d3804433658678b0a3 ]
The device_node pointer is returned by of_parse_phandle() with refcount incremented. We should use of_node_put() on it when done.
Fixes: 50e99641413e ("soc: qcom: smp2p: Qualcomm Shared Memory Point to Point") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220308071942.22942-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/smp2p.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index 4a157240f419..59dbf4b61e6c 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -493,6 +493,7 @@ static int smp2p_parse_ipc(struct qcom_smp2p *smp2p) }
smp2p->ipc_regmap = syscon_node_to_regmap(syscon); + of_node_put(syscon); if (IS_ERR(smp2p->ipc_regmap)) return PTR_ERR(smp2p->ipc_regmap);
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit aad66a3c78da668f4506356c2fdb70b7a19ecc76 ]
The device_node pointer is returned by of_parse_phandle() with refcount incremented. We should use of_node_put() on it when done.
Fixes: c97c4090ff72 ("soc: qcom: smsm: Add driver for Qualcomm SMSM") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220308073648.24634-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/smsm.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index ef15d014c03a..9df9bba242f3 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -374,6 +374,7 @@ static int smsm_parse_ipc(struct qcom_smsm *smsm, unsigned host_id) return 0;
host->ipc_regmap = syscon_node_to_regmap(syscon); + of_node_put(syscon); if (IS_ERR(host->ipc_regmap)) return PTR_ERR(host->ipc_regmap);
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit e77817b4953dcf59a83bfab18ca5af80d9231d72 ]
CONFIG_SM_DISPCC_8250 is not enabled by default, but it is still necessary for the Qualcomm RB5 board. Reenable it (as it was enabled before the commit dde8cd786e37 ("arm64: defconfig: rebuild default configuration")).
Cc: Marcel Ziswiler marcel.ziswiler@toradex.com Fixes: dde8cd786e37 ("arm64: defconfig: rebuild default configuration") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220404215913.1497172-1-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 50aa3d75ab4f..f30af6e1fe40 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1029,6 +1029,7 @@ CONFIG_SM_GCC_8350=y CONFIG_SM_GCC_8450=y CONFIG_SM_GPUCC_8150=y CONFIG_SM_GPUCC_8250=y +CONFIG_SM_DISPCC_8250=y CONFIG_QCOM_HFPLL=y CONFIG_CLK_GFM_LPASS_SM8250=m CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 0aa3a0937feeb91a0e4e438c3c063b749b194192 ]
The ep->ob_region_map bitmap is a long and it has BITS_PER_LONG bits.
Link: https://lore.kernel.org/r/20220315065829.GA13572@kili Fixes: 37dddf14f1ae ("PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/cadence/pcie-cadence-ep.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-ep.c b/drivers/pci/controller/cadence/pcie-cadence-ep.c index 4b1c4bc4e003..b8b655d4047e 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-ep.c +++ b/drivers/pci/controller/cadence/pcie-cadence-ep.c @@ -187,8 +187,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn, struct cdns_pcie *pcie = &ep->pcie; u32 r;
- r = find_first_zero_bit(&ep->ob_region_map, - sizeof(ep->ob_region_map) * BITS_PER_LONG); + r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG); if (r >= ep->max_regions - 1) { dev_err(&epc->dev, "no free outbound region\n"); return -EINVAL;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 096950e230b8d83645c7cf408b9f399f58c08b96 ]
The ep->ob_region_map bitmap is a long and it has BITS_PER_LONG bits.
Link: https://lore.kernel.org/r/20220315065944.GB13572@kili Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-rockchip-ep.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/pci/controller/pcie-rockchip-ep.c b/drivers/pci/controller/pcie-rockchip-ep.c index 5fb9ce6e536e..d1a200b93b2b 100644 --- a/drivers/pci/controller/pcie-rockchip-ep.c +++ b/drivers/pci/controller/pcie-rockchip-ep.c @@ -264,8 +264,7 @@ static int rockchip_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, u8 vfn, struct rockchip_pcie *pcie = &ep->rockchip; u32 r;
- r = find_first_zero_bit(&ep->ob_region_map, - sizeof(ep->ob_region_map) * BITS_PER_LONG); + r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG); /* * Region 0 is reserved for configuration space and shouldn't * be used elsewhere per TRM, so leave it out.
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 214e0d8fe4a813ae6ffd62bc2dfe7544c20914f4 ]
The of_find_compatible_node() function returns a node pointer with refcount incremented, We should use of_node_put() on it when done Add the missing of_node_put() to release the refcount.
Link: https://lore.kernel.org/r/20220309091953.5630-1-linmq006@gmail.com Fixes: 87e8657ba99c ("PCI: mediatek: Add new method to get shared pcie-cfg base address") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Miles Chen miles.chen@mediatek.com Acked-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mediatek.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index ddfbd4aebdec..be8bd919cb88 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -1008,6 +1008,7 @@ static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie) "mediatek,generic-pciecfg"); if (cfg_node) { pcie->cfg = syscon_node_to_regmap(cfg_node); + of_node_put(cfg_node); if (IS_ERR(pcie->cfg)) return PTR_ERR(pcie->cfg); }
From: Jiantao Zhang water.zhangjiantao@huawei.com
[ Upstream commit 88557685cd72cf0db686a4ebff3fad4365cb6071 ]
When dma_mapping_error() returns error because of no enough memory, but dw_pcie_host_init() returns success, which will mislead the callers.
Link: https://lore.kernel.org/r/30170911-0e2f-98ce-9266-70465b9073e5@huawei.com Fixes: 07940c369a6b ("PCI: dwc: Fix MSI page leakage in suspend/resume") Signed-off-by: Jianrong Zhang zhangjianrong5@huawei.com Signed-off-by: Jiantao Zhang water.zhangjiantao@huawei.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-designware-host.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 2fa86f32d964..9979302532b7 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -396,7 +396,8 @@ int dw_pcie_host_init(struct pcie_port *pp) sizeof(pp->msi_msg), DMA_FROM_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); - if (dma_mapping_error(pci->dev, pp->msi_data)) { + ret = dma_mapping_error(pci->dev, pp->msi_data); + if (ret) { dev_err(pci->dev, "Failed to map MSI data\n"); pp->msi_data = 0; goto err_free_msi;
From: Thorsten Scherer t.scherer@eckelmann.de
[ Upstream commit 3d397a1277853498e8b7b305f2610881357c033f ]
Commit f3e7dae323ab ("ARM: dts: imx6qdl: add enet_out clk support") added another item to the list of clocks for the fec device. As imx6dl-eckelmann-ci4x10.dts only overwrites clocks, but not clock-names this resulted in an inconsistency with clocks having one item more than clock-names.
Also overwrite clock-names with the same value as in imx6qdl.dtsi. This is a no-op today, but prevents similar inconsistencies if the soc file will be changed in a similar way in the future.
Signed-off-by: Thorsten Scherer t.scherer@eckelmann.de Reviewed-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Fixes: f3e7dae323ab ("ARM: dts: imx6qdl: add enet_out clk support") Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts b/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts index b4a9523e325b..864dc5018451 100644 --- a/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts +++ b/arch/arm/boot/dts/imx6dl-eckelmann-ci4x10.dts @@ -297,7 +297,11 @@ phy-mode = "rmii"; phy-reset-gpios = <&gpio1 18 GPIO_ACTIVE_LOW>; phy-handle = <&phy>; - clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&rmii_clk>; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&rmii_clk>, + <&clks IMX6QDL_CLK_ENET_REF>; + clock-names = "ipg", "ahb", "ptp", "enet_out"; status = "okay";
mdio {
From: Stephen Boyd swboyd@chromium.org
[ Upstream commit f31c834d3976652753f39eb319170c8c4ac3ce55 ]
This node should be named sar1-irq-odl, not sar0-irq-odl. Otherwise we'll overwrite the settings for sar0 with what is intended for sar1, leading to probe failures for sar1 that are quite confusing.
Fixes: 116f7cc43d28 ("arm64: dts: qcom: sc7280: Add herobrine-r1") Cc: Douglas Anderson dianders@chromium.org Cc: Matthias Kaehlcke mka@chromium.org Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Matthias Kaehlcke mka@chromium.org Tested-by: Matthias Kaehlcke mka@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220324223331.876199-1-swboyd@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi index dc17f2079695..7b8fe20afcea 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi @@ -741,7 +741,7 @@ ap_ec_spi: &spi10 { bias-pull-up; };
- sar1_irq_odl: sar0-irq-odl { + sar1_irq_odl: sar1-irq-odl { pins = "gpio140"; function = "gpio"; bias-pull-up;
From: Stephen Boyd swboyd@chromium.org
[ Upstream commit dbcbeed94f3b6f7f24349a7f335cc603a682e7a7 ]
Having these pins with outputs is good on a fresh boot because it puts the boot and reset pins in a known "good" state. Unfortunately, that conflicts with the fingerprint firmware flashing code. The firmware flashing process binds and unbinds the cros-ec and spidev drivers and that reapplies the pin output values after the flashing code has overridden the gpio values. This causes a problem because we try to put the device into bootloader mode, bind the spidev driver and that inadvertently puts it right back into normal boot mode, breaking the flashing process.
Fix this by removing the outputs. We'll introduce a binding for fingerprint cros-ec specifically to set the gpios properly via gpio APIs during cros-ec driver probe instead.
Cc: Douglas Anderson dianders@chromium.org Cc: Matthias Kaehlcke mka@chromium.org Cc: Alexandru M Stan amstan@chromium.org Fixes: 116f7cc43d28 ("arm64: dts: qcom: sc7280: Add herobrine-r1") Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Matthias Kaehlcke mka@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220317010640.2498502-2-swboyd@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi | 2 -- 1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi index 7b8fe20afcea..488caa48cba3 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280-herobrine.dtsi @@ -677,7 +677,6 @@ ap_ec_spi: &spi10 { function = "gpio"; bias-disable; drive-strength = <2>; - output-high; };
fp_to_ap_irq_l: fp-to-ap-irq-l { @@ -691,7 +690,6 @@ ap_ec_spi: &spi10 { pins = "gpio68"; function = "gpio"; bias-disable; - output-low; };
gsc_ap_int_odl: gsc-ap-int-odl {
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit 5334a3b12a7233b31788de60d61bfd890059d783 ]
The llcc-qcom driver can be compiled as a module, but lacks MODULE_DEVICE_TABLE() and will therefore not be loaded automatically. Fix this.
Fixes: a3134fb09e0b ("drivers: soc: Add LLCC driver") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Sai Prakash Ranjan quic_saipraka@quicinc.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://lore.kernel.org/r/20220408213336.581661-3-bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/llcc-qcom.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index eecafeded56f..85ba8209b182 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -749,6 +749,7 @@ static const struct of_device_id qcom_llcc_of_match[] = { { .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg }, { } }; +MODULE_DEVICE_TABLE(of, qcom_llcc_of_match);
static struct platform_driver qcom_llcc_driver = { .driver = {
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit e39f9be08d9dfe685c8a325ac1755c04f383effc ]
In preparation for not treating DVSEC range initialization failures as fatal to cxl_pci_probe() add individual dev_dbg() statements for each of the major failure reasons in cxl_dvsec_ranges().
The rationale for cxl_dvsec_ranges() failure not being fatal is that there is still value for cxl_pci to enable mailbox operations even if CXL.mem operation is disabled.
Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Ben Widawsky ben.widawsky@intel.com Reviewed-by: Davidlohr Bueso dave@stgolabs.net Link: https://lore.kernel.org/r/164730734812.3806189.2726330688692684104.stgit@dwi... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/pci.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index 3f2182d66829..c4941a3ca6a8 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -466,12 +466,15 @@ static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds) { struct cxl_endpoint_dvsec_info *info = &cxlds->info; struct pci_dev *pdev = to_pci_dev(cxlds->dev); + struct device *dev = &pdev->dev; int d = cxlds->cxl_dvsec; int hdm_count, rc, i; u16 cap, ctrl;
- if (!d) + if (!d) { + dev_dbg(dev, "No DVSEC Capability\n"); return -ENXIO; + }
rc = pci_read_config_word(pdev, d + CXL_DVSEC_CAP_OFFSET, &cap); if (rc) @@ -481,8 +484,10 @@ static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds) if (rc) return rc;
- if (!(cap & CXL_DVSEC_MEM_CAPABLE)) + if (!(cap & CXL_DVSEC_MEM_CAPABLE)) { + dev_dbg(dev, "Not MEM Capable\n"); return -ENXIO; + }
/* * It is not allowed by spec for MEM.capable to be set and have 0 legacy @@ -495,8 +500,10 @@ static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds) return -EINVAL;
rc = wait_for_valid(cxlds); - if (rc) + if (rc) { + dev_dbg(dev, "Failure awaiting MEM_INFO_VALID (%d)\n", rc); return rc; + }
info->mem_enabled = FIELD_GET(CXL_DVSEC_MEM_ENABLE, ctrl);
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 36bfc6ad508af38f212cf5a38147d867fb3f80a8 ]
cxl_dvsec_ranges(), the helper for enumerating the presence of an active legacy CXL.mem configuration on a CXL 2.0 Memory Expander, is not fatal for cxl_pci because there is still value to enable mailbox operations even if CXL.mem operation is disabled. Recall that the reason cxl_pci does this initialization and not cxl_mem is to preserve the useful property (for unit testing) that cxl_mem is cxl_memdev + mmio generic, and does not require access to a 'struct pci_dev' to issue config cycles.
Update 'struct cxl_endpoint_dvsec_info' to carry either a positive number of non-zero size legacy CXL DVSEC ranges, or the negative error code from __cxl_dvsec_ranges() in its @ranges member.
Reported-by: Krzysztof Zach krzysztof.zach@intel.com Fixes: 560f78559006 ("cxl/pci: Retrieve CXL DVSEC memory info") Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Davidlohr Bueso dave@stgolabs.net Link: https://lore.kernel.org/r/164730735869.3806189.4032428192652531946.stgit@dwi... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/pci.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c index c4941a3ca6a8..bb92853c3b93 100644 --- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -462,13 +462,18 @@ static int wait_for_media_ready(struct cxl_dev_state *cxlds) return 0; }
-static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds) +/* + * Return positive number of non-zero ranges on success and a negative + * error code on failure. The cxl_mem driver depends on ranges == 0 to + * init HDM operation. + */ +static int __cxl_dvsec_ranges(struct cxl_dev_state *cxlds, + struct cxl_endpoint_dvsec_info *info) { - struct cxl_endpoint_dvsec_info *info = &cxlds->info; struct pci_dev *pdev = to_pci_dev(cxlds->dev); + int hdm_count, rc, i, ranges = 0; struct device *dev = &pdev->dev; int d = cxlds->cxl_dvsec; - int hdm_count, rc, i; u16 cap, ctrl;
if (!d) { @@ -545,10 +550,17 @@ static int cxl_dvsec_ranges(struct cxl_dev_state *cxlds) };
if (size) - info->ranges++; + ranges++; }
- return 0; + return ranges; +} + +static void cxl_dvsec_ranges(struct cxl_dev_state *cxlds) +{ + struct cxl_endpoint_dvsec_info *info = &cxlds->info; + + info->ranges = __cxl_dvsec_ranges(cxlds, info); }
static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) @@ -617,10 +629,7 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc;
- rc = cxl_dvsec_ranges(cxlds); - if (rc) - dev_warn(&pdev->dev, - "Failed to get DVSEC range information (%d)\n", rc); + cxl_dvsec_ranges(cxlds);
cxlmd = devm_cxl_add_memdev(cxlds); if (IS_ERR(cxlmd))
From: Sean Christopherson seanjc@google.com
[ Upstream commit c3634d25fbee88e2368a8e0903ae0d0670eb9e71 ]
Don't modify vmcs12 exit fields except EXIT_REASON and EXIT_QUALIFICATION when performing a nested VM-Exit due to failed VM-Entry. Per the SDM, only the two aformentioned fields are filled and "All other VM-exit information fields are unmodified".
Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1") Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220407002315.78092-3-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 | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 880d0b0c9315..afaddd43a6c0 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -4202,12 +4202,12 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, if (to_vmx(vcpu)->exit_reason.enclave_mode) vmcs12->vm_exit_reason |= VMX_EXIT_REASONS_SGX_ENCLAVE_MODE; vmcs12->exit_qualification = exit_qualification; - vmcs12->vm_exit_intr_info = exit_intr_info; - - vmcs12->idt_vectoring_info_field = 0; - vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN); - vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO);
+ /* + * On VM-Exit due to a failed VM-Entry, the VMCS isn't marked launched + * and only EXIT_REASON and EXIT_QUALIFICATION are updated, all other + * exit info fields are unmodified. + */ if (!(vmcs12->vm_exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY)) { vmcs12->launch_state = 1;
@@ -4219,8 +4219,13 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, * Transfer the event that L0 or L1 may wanted to inject into * L2 to IDT_VECTORING_INFO_FIELD. */ + vmcs12->idt_vectoring_info_field = 0; vmcs12_save_pending_event(vcpu, vmcs12);
+ vmcs12->vm_exit_intr_info = exit_intr_info; + vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN); + vmcs12->vmx_instruction_info = vmcs_read32(VMX_INSTRUCTION_INFO); + /* * According to spec, there's no need to store the guest's * MSRs if the exit is due to a VM-entry failure that occurs
From: Sean Christopherson seanjc@google.com
[ Upstream commit 9bd1f0efa859b61950d109b32ff8d529cc33a3ad ]
Clear the IDT vectoring field in vmcs12 on next VM-Exit due to a double or triple fault. Per the SDM, a VM-Exit isn't considered to occur during event delivery if the exit is due to an intercepted double fault or a triple fault. Opportunistically move the default clearing (no event "pending") into the helper so that it's more obvious that KVM does indeed handle this case.
Note, the double fault case is worded rather wierdly in the SDM:
The original event results in a double-fault exception that causes the VM exit directly.
Temporarily ignoring injected events, double faults can _only_ occur if an exception occurs while attempting to deliver a different exception, i.e. there's _always_ an original event. And for injected double fault, while there's no original event, injected events are never subject to interception.
Presumably the SDM is calling out that a the vectoring info will be valid if a different exit occurs after a double fault, e.g. if a #PF occurs and is intercepted while vectoring #DF, then the vectoring info will show the double fault. In other words, the clause can simply be read as:
The VM exit is caused by a double-fault exception.
Fixes: 4704d0befb07 ("KVM: nVMX: Exiting from L2 to L1") Cc: Chenyi Qiang chenyi.qiang@intel.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220407002315.78092-4-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 | 32 ++++++++++++++++++++++++++++---- arch/x86/kvm/vmx/vmcs.h | 5 +++++ 2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index afaddd43a6c0..ee7df31883cd 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3695,12 +3695,34 @@ vmcs12_guest_cr4(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) }
static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, - struct vmcs12 *vmcs12) + struct vmcs12 *vmcs12, + u32 vm_exit_reason, u32 exit_intr_info) { u32 idt_vectoring; unsigned int nr;
- if (vcpu->arch.exception.injected) { + /* + * Per the SDM, VM-Exits due to double and triple faults are never + * considered to occur during event delivery, even if the double/triple + * fault is the result of an escalating vectoring issue. + * + * Note, the SDM qualifies the double fault behavior with "The original + * event results in a double-fault exception". It's unclear why the + * qualification exists since exits due to double fault can occur only + * while vectoring a different exception (injected events are never + * subject to interception), i.e. there's _always_ an original event. + * + * The SDM also uses NMI as a confusing example for the "original event + * causes the VM exit directly" clause. NMI isn't special in any way, + * the same rule applies to all events that cause an exit directly. + * NMI is an odd choice for the example because NMIs can only occur on + * instruction boundaries, i.e. they _can't_ occur during vectoring. + */ + if ((u16)vm_exit_reason == EXIT_REASON_TRIPLE_FAULT || + ((u16)vm_exit_reason == EXIT_REASON_EXCEPTION_NMI && + is_double_fault(exit_intr_info))) { + vmcs12->idt_vectoring_info_field = 0; + } else if (vcpu->arch.exception.injected) { nr = vcpu->arch.exception.nr; idt_vectoring = nr | VECTORING_INFO_VALID_MASK;
@@ -3733,6 +3755,8 @@ static void vmcs12_save_pending_event(struct kvm_vcpu *vcpu, idt_vectoring |= INTR_TYPE_EXT_INTR;
vmcs12->idt_vectoring_info_field = idt_vectoring; + } else { + vmcs12->idt_vectoring_info_field = 0; } }
@@ -4219,8 +4243,8 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, * Transfer the event that L0 or L1 may wanted to inject into * L2 to IDT_VECTORING_INFO_FIELD. */ - vmcs12->idt_vectoring_info_field = 0; - vmcs12_save_pending_event(vcpu, vmcs12); + vmcs12_save_pending_event(vcpu, vmcs12, + vm_exit_reason, exit_intr_info);
vmcs12->vm_exit_intr_info = exit_intr_info; vmcs12->vm_exit_instruction_len = vmcs_read32(VM_EXIT_INSTRUCTION_LEN); diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h index e325c290a816..2b9d7a7e83f7 100644 --- a/arch/x86/kvm/vmx/vmcs.h +++ b/arch/x86/kvm/vmx/vmcs.h @@ -104,6 +104,11 @@ static inline bool is_breakpoint(u32 intr_info) return is_exception_n(intr_info, BP_VECTOR); }
+static inline bool is_double_fault(u32 intr_info) +{ + return is_exception_n(intr_info, DF_VECTOR); +} + static inline bool is_page_fault(u32 intr_info) { return is_exception_n(intr_info, PF_VECTOR);
From: Sudeep Holla sudeep.holla@arm.com
[ Upstream commit 8dd3cdeaf3032728e30a7ec5e79ca780fc86cf7a ]
The SCMI power domain ID for all the coresight components is 8 while the previous/older SCPI domain was 0. When adding SCMI variant, couple of instances retained SCPI domain ID by mistake.
Fix the same by using the correct SCMI power domain ID of 8.
Link: https://lore.kernel.org/r/20220413093547.1699535-1-sudeep.holla@arm.com Fixes: 96bb0954860a ("arm64: dts: juno: Add separate SCMI variants") Cc: Robin Murphy robin.murphy@arm.com Reported-by: Mike Leach Mike.Leach@arm.com Acked-by: Robin Murphy robin.murphy@arm.com Signed-off-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/arm/juno-r1-scmi.dts | 4 ++-- arch/arm64/boot/dts/arm/juno-r2-scmi.dts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/arm/juno-r1-scmi.dts b/arch/arm64/boot/dts/arm/juno-r1-scmi.dts index 190a0fba4ad6..fd1f0d26d751 100644 --- a/arch/arm64/boot/dts/arm/juno-r1-scmi.dts +++ b/arch/arm64/boot/dts/arm/juno-r1-scmi.dts @@ -7,11 +7,11 @@ };
etf@20140000 { - power-domains = <&scmi_devpd 0>; + power-domains = <&scmi_devpd 8>; };
funnel@20150000 { - power-domains = <&scmi_devpd 0>; + power-domains = <&scmi_devpd 8>; }; };
diff --git a/arch/arm64/boot/dts/arm/juno-r2-scmi.dts b/arch/arm64/boot/dts/arm/juno-r2-scmi.dts index dbf13770084f..35e6d4762c46 100644 --- a/arch/arm64/boot/dts/arm/juno-r2-scmi.dts +++ b/arch/arm64/boot/dts/arm/juno-r2-scmi.dts @@ -7,11 +7,11 @@ };
etf@20140000 { - power-domains = <&scmi_devpd 0>; + power-domains = <&scmi_devpd 8>; };
funnel@20150000 { - power-domains = <&scmi_devpd 0>; + power-domains = <&scmi_devpd 8>; }; };
From: Giovanni Cabiddu giovanni.cabiddu@intel.com
[ Upstream commit 6a23804cb8bcb85c6998bf193d94d4036db26f51 ]
Set the CIPHER capability for QAT DH895XCC devices if the hardware supports it. This is done if both the CIPHER and the AUTHENTICATION engines are available on the device.
Fixes: ad1332aa67ec ("crypto: qat - add support for capability detection") Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Marco Chiappero marco.chiappero@intel.com Reviewed-by: Marco Chiappero marco.chiappero@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- .../crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c index 1e7bed8b011f..8a526badf5bf 100644 --- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c @@ -60,17 +60,23 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | - ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + ICP_ACCEL_CAPABILITIES_AUTHENTICATION | + ICP_ACCEL_CAPABILITIES_CIPHER;
/* Read accelerator capabilities mask */ pci_read_config_dword(pdev, ADF_DEVICE_LEGFUSE_OFFSET, &legfuses);
- if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) + /* A set bit in legfuses means the feature is OFF in this SKU */ + if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + } if (legfuses & ICP_ACCEL_MASK_PKE_SLICE) capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; - if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) + if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + } if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE) capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;
From: Giovanni Cabiddu giovanni.cabiddu@intel.com
[ Upstream commit 0eaa51543273fd0f4ba9bea83638f7033436e5eb ]
The capability detection logic clears bits for the features that are disabled in a certain SKU. For example, if the bit associate to compression is not present in the LEGFUSE register, the correspondent bit is cleared in the capability mask. This change adds the compression capability to the mask as this was missing in the commit that enhanced the capability detection logic.
Fixes: cfe4894eccdc ("crypto: qat - set COMPRESSION capability for QAT GEN2") Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Marco Chiappero marco.chiappero@intel.com Reviewed-by: Marco Chiappero marco.chiappero@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c index 8a526badf5bf..91095ad479dc 100644 --- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c @@ -61,7 +61,8 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | ICP_ACCEL_CAPABILITIES_AUTHENTICATION | - ICP_ACCEL_CAPABILITIES_CIPHER; + ICP_ACCEL_CAPABILITIES_CIPHER | + ICP_ACCEL_CAPABILITIES_COMPRESSION;
/* Read accelerator capabilities mask */ pci_read_config_dword(pdev, ADF_DEVICE_LEGFUSE_OFFSET, &legfuses);
From: Tzung-Bi Shih tzungbi@kernel.org
[ Upstream commit 2cd01bd6b117df07b1bc2852f08694fdd29e40ed ]
Fix cros_ec_register() to unregister platform devices if blocking_notifier_chain_register() fails.
Also use the single exit path to handle the platform device unregistration.
Fixes: 42cd0ab476e2 ("platform/chrome: cros_ec: Query EC protocol version if EC transitions between RO/RW") Reviewed-by: Prashant Malani pmalani@chromium.org Signed-off-by: Tzung-Bi Shih tzungbi@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/chrome/cros_ec.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index d49a4efe46c8..a5cc8f24299e 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -189,6 +189,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) ec_dev->max_request = sizeof(struct ec_params_hello); ec_dev->max_response = sizeof(struct ec_response_get_protocol_info); ec_dev->max_passthru = 0; + ec_dev->ec = NULL; + ec_dev->pd = NULL;
ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL); if (!ec_dev->din) @@ -245,18 +247,16 @@ int cros_ec_register(struct cros_ec_device *ec_dev) if (IS_ERR(ec_dev->pd)) { dev_err(ec_dev->dev, "Failed to create CrOS PD platform device\n"); - platform_device_unregister(ec_dev->ec); - return PTR_ERR(ec_dev->pd); + err = PTR_ERR(ec_dev->pd); + goto exit; } }
if (IS_ENABLED(CONFIG_OF) && dev->of_node) { err = devm_of_platform_populate(dev); if (err) { - platform_device_unregister(ec_dev->pd); - platform_device_unregister(ec_dev->ec); dev_err(dev, "Failed to register sub-devices\n"); - return err; + goto exit; } }
@@ -278,7 +278,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) err = blocking_notifier_chain_register(&ec_dev->event_notifier, &ec_dev->notifier_ready); if (err) - return err; + goto exit; }
dev_info(dev, "Chrome EC device registered\n"); @@ -291,6 +291,10 @@ int cros_ec_register(struct cros_ec_device *ec_dev) cros_ec_irq_thread(0, ec_dev);
return 0; +exit: + platform_device_unregister(ec_dev->ec); + platform_device_unregister(ec_dev->pd); + return err; } EXPORT_SYMBOL(cros_ec_register);
From: Max Krummenacher max.krummenacher@toradex.com
[ Upstream commit 5f5c579a34a87117c20b411df583ae816c1ec84f ]
Fix names of extra pingroup node and property for gpio bus recovery. Without the change i2c2 is not functional.
Fixes: 56f0df6b6b58 ("ARM: dts: imx*(colibri|apalis): add missing recovery modes to i2c") 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-colibri.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/imx6qdl-colibri.dtsi index 4e2a309c93fa..1e86b3814708 100644 --- a/arch/arm/boot/dts/imx6qdl-colibri.dtsi +++ b/arch/arm/boot/dts/imx6qdl-colibri.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ OR MIT /* - * Copyright 2014-2020 Toradex + * Copyright 2014-2022 Toradex * Copyright 2012 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. */ @@ -132,7 +132,7 @@ clock-frequency = <100000>; pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; - pinctrl-0 = <&pinctrl_i2c2_gpio>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; scl-gpios = <&gpio2 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; sda-gpios = <&gpio3 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; @@ -488,7 +488,7 @@ >; };
- pinctrl_i2c2_gpio: i2c2grp { + pinctrl_i2c2_gpio: i2c2gpiogrp { fsl,pins = < MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x4001b8b1 MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x4001b8b1
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit 57b888ca2541785de2fcb90575b378921919b6c0 ]
Commit 413dda8f2c6f ("platform/chrome: cros_ec_chardev: Use cros_ec_cmd_xfer_status helper") inadvertendly changed the userspace ABI. Previously, cros_ec ioctls would only report errors if the EC communication failed, and otherwise return success and the result of the EC communication. An EC command execution failure was reported in the EC response field. The above mentioned commit changed this behavior, and the ioctl itself would fail. This breaks userspace commands trying to analyze the EC command execution error since the actual EC command response is no longer reported to userspace.
Fix the problem by re-introducing the cros_ec_cmd_xfer() helper, and use it to handle ioctl messages.
Fixes: 413dda8f2c6f ("platform/chrome: cros_ec_chardev: Use cros_ec_cmd_xfer_status helper") Cc: Daisuke Nojiri dnojiri@chromium.org Cc: Rob Barnes robbarnes@google.com Cc: Rajat Jain rajatja@google.com Cc: Brian Norris briannorris@chromium.org Cc: Parth Malkan parthmalkan@google.com Reviewed-by: Daisuke Nojiri dnojiri@chromium.org Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Tzung-Bi Shih tzungbi@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/chrome/cros_ec_chardev.c | 2 +- drivers/platform/chrome/cros_ec_proto.c | 50 +++++++++++++++++---- include/linux/platform_data/cros_ec_proto.h | 3 ++ 3 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c index e0bce869c49a..fd33de546aee 100644 --- a/drivers/platform/chrome/cros_ec_chardev.c +++ b/drivers/platform/chrome/cros_ec_chardev.c @@ -301,7 +301,7 @@ static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg) }
s_cmd->command += ec->cmd_offset; - ret = cros_ec_cmd_xfer_status(ec->ec_dev, s_cmd); + ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd); /* Only copy data to userland if data was received. */ if (ret < 0) goto exit; diff --git a/drivers/platform/chrome/cros_ec_proto.c b/drivers/platform/chrome/cros_ec_proto.c index c4caf2e2de82..ac1419881ff3 100644 --- a/drivers/platform/chrome/cros_ec_proto.c +++ b/drivers/platform/chrome/cros_ec_proto.c @@ -560,22 +560,28 @@ int cros_ec_query_all(struct cros_ec_device *ec_dev) EXPORT_SYMBOL(cros_ec_query_all);
/** - * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. + * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. * @ec_dev: EC device. * @msg: Message to write. * - * Call this to send a command to the ChromeOS EC. This should be used instead of calling the EC's - * cmd_xfer() callback directly. It returns success status only if both the command was transmitted - * successfully and the EC replied with success status. + * Call this to send a command to the ChromeOS EC. This should be used instead + * of calling the EC's cmd_xfer() callback directly. This function does not + * convert EC command execution error codes to Linux error codes. Most + * in-kernel users will want to use cros_ec_cmd_xfer_status() instead since + * that function implements the conversion. * * Return: - * >=0 - The number of bytes transferred - * <0 - Linux error code + * >0 - EC command was executed successfully. The return value is the number + * of bytes returned by the EC (excluding the header). + * =0 - EC communication was successful. EC command execution results are + * reported in msg->result. The result will be EC_RES_SUCCESS if the + * command was executed successfully or report an EC command execution + * error. + * <0 - EC communication error. Return value is the Linux error code. */ -int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, - struct cros_ec_command *msg) +int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg) { - int ret, mapped; + int ret;
mutex_lock(&ec_dev->lock); if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) { @@ -616,6 +622,32 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, ret = send_command(ec_dev, msg); mutex_unlock(&ec_dev->lock);
+ return ret; +} +EXPORT_SYMBOL(cros_ec_cmd_xfer); + +/** + * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. + * @ec_dev: EC device. + * @msg: Message to write. + * + * Call this to send a command to the ChromeOS EC. This should be used instead of calling the EC's + * cmd_xfer() callback directly. It returns success status only if both the command was transmitted + * successfully and the EC replied with success status. + * + * Return: + * >=0 - The number of bytes transferred. + * <0 - Linux error code + */ +int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, + struct cros_ec_command *msg) +{ + int ret, mapped; + + ret = cros_ec_cmd_xfer(ec_dev, msg); + if (ret < 0) + return ret; + mapped = cros_ec_map_error(msg->result); if (mapped) { dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n", diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index df3c78c92ca2..16931569adce 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -216,6 +216,9 @@ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, int cros_ec_check_result(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
+int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, + struct cros_ec_command *msg); + int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, struct cros_ec_command *msg);
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit ae38fda02996d43d9fb09f16e81e0008704dd524 ]
This patch marks the bit timing constants as const.
Fixes: c223da689324 ("can: xilinx_can: Add support for CANFD FD frames") Link: https://lore.kernel.org/all/20220317203119.792552-1-mkl@pengutronix.de Cc: Appana Durga Kedareswara rao appana.durga.rao@xilinx.com Cc: Naga Sureshkumar Relli naga.sureshkumar.relli@xilinx.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/xilinx_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index e562c5ab1149..43f0c6a064ba 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -239,7 +239,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd = { };
/* AXI CANFD Data Bittiming constants as per AXI CANFD 1.0 specs */ -static struct can_bittiming_const xcan_data_bittiming_const_canfd = { +static const struct can_bittiming_const xcan_data_bittiming_const_canfd = { .name = DRIVER_NAME, .tseg1_min = 1, .tseg1_max = 16, @@ -265,7 +265,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { };
/* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */ -static struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { +static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { .name = DRIVER_NAME, .tseg1_min = 1, .tseg1_max = 32,
From: Marek Vasut marex@denx.de
[ Upstream commit ef2d90708883f4025a801feb0ba8411a7a4387e1 ]
Per KSZ9031RNX PHY datasheet FIGURE 7-5: POWER-UP/POWER-DOWN/RESET TIMING Note 2: After the de-assertion of reset, wait a minimum of 100 μs before starting programming on the MIIM (MDC/MDIO) interface.
Add 1ms post-reset delay to guarantee this figure.
Fixes: 010ca9fe500bf ("ARM: dts: stm32: Add missing ethernet PHY reset on AV96") Signed-off-by: Marek Vasut marex@denx.de Cc: Alexandre Torgue alexandre.torgue@foss.st.com Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi index 61e17f44ce81..76c54b006d87 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -141,6 +141,7 @@ compatible = "snps,dwmac-mdio"; reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>; reset-delay-us = <1000>; + reset-post-delay-us = <1000>;
phy0: ethernet-phy@7 { reg = <7>;
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit e930244918092d44b60a7b538cf60d737010ceef ]
Add compatible msm8936. msm8936 covers both msm8936 and msm8939. The relevant driver already has the compat string but, we haven't documented it.
Fixes: d6e52482f5ab ("drivers: soc: Add MSM8936 SMD RPM compatible") Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Acked-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Rob Herring robh@kernel.org Link: https://lore.kernel.org/r/20220418231857.3061053-1-bryan.odonoghue@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 1 + 1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml index b32457c2fc0b..3361218e278f 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml @@ -34,6 +34,7 @@ properties: - qcom,rpm-ipq6018 - qcom,rpm-msm8226 - qcom,rpm-msm8916 + - qcom,rpm-msm8936 - qcom,rpm-msm8953 - qcom,rpm-msm8974 - qcom,rpm-msm8976
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 97c246c825f73a018169834e56ffa9a89dea37a9 ]
The clock controller of RPMH RSC does not have 'reg' property, so should not have unit address.
Fixes: bae2f5979c6e ("ARM: dts: qcom: Add SDX65 platform and MTP board support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220411085935.130072-2-krzysztof.kozlowski@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-sdx65.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/qcom-sdx65.dtsi b/arch/arm/boot/dts/qcom-sdx65.dtsi index 796641d30e06..0c3f93603adc 100644 --- a/arch/arm/boot/dts/qcom-sdx65.dtsi +++ b/arch/arm/boot/dts/qcom-sdx65.dtsi @@ -202,7 +202,7 @@ <WAKE_TCS 2>, <CONTROL_TCS 1>;
- rpmhcc: clock-controller@1 { + rpmhcc: clock-controller { compatible = "qcom,sdx65-rpmh-clk"; #clock-cells = <1>; clock-names = "xo";
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 488922c1a372579bf2caf40933e7459e3c86276f ]
qupv3_id_0 was missing iommus property which cause any dma transaction to fail and board crash. So add the missing iommus.
While at it also add interconnect nodes for qup
Fixes: 5188049c9b36 ("arm64: dts: qcom: Add base SM8450 DTSI") Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220414101630.1189052-3-vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 934e29b9e153..5facb4a5bf63 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -693,6 +693,9 @@ clock-names = "m-ahb", "s-ahb"; clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>, <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>; + iommus = <&apps_smmu 0x5a3 0x0>; + interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>; + interconnect-names = "qup-core"; #address-cells = <2>; #size-cells = <2>; ranges;
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 67ebdc6dd1e2049fd9620f0572bc81a809afbe24 ]
qupv3_id_1 was missing iommus property which cause any dma transaction to fail and board crash. So add the missing iommus.
Fixes: 5188049c9b36 ("arm64: dts: qcom: Add base SM8450 DTSI") Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220414101630.1189052-7-vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 5facb4a5bf63..e63b7b0458cf 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -721,6 +721,9 @@ clock-names = "m-ahb", "s-ahb"; clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>, <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + iommus = <&apps_smmu 0x43 0x0>; + interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>; + interconnect-names = "qup-core"; #address-cells = <2>; #size-cells = <2>; ranges;
From: Phil Elwell phil@raspberrypi.com
[ Upstream commit 2c663e5e5bbf2a5b85e0f76ccb69663f583c3e33 ]
The GPIOs 30 to 39 are connected to the Cypress CYW43438 (Wifi/BT). So fix the GPIO line names accordingly.
Fixes: 2c7c040c73e9 ("ARM: dts: bcm2835: Add Raspberry Pi Zero W") Signed-off-by: Phil Elwell phil@raspberrypi.com Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm2835-rpi-zero-w.dts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts index 243236bc1e00..8b043ab62dc8 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts @@ -74,16 +74,18 @@ "GPIO27", "SDA0", "SCL0", - "NC", /* GPIO30 */ - "NC", /* GPIO31 */ - "NC", /* GPIO32 */ - "NC", /* GPIO33 */ - "NC", /* GPIO34 */ - "NC", /* GPIO35 */ - "NC", /* GPIO36 */ - "NC", /* GPIO37 */ - "NC", /* GPIO38 */ - "NC", /* GPIO39 */ + /* Used by BT module */ + "CTS0", + "RTS0", + "TXD0", + "RXD0", + /* Used by Wifi */ + "SD1_CLK", + "SD1_CMD", + "SD1_DATA0", + "SD1_DATA1", + "SD1_DATA2", + "SD1_DATA3", "CAM_GPIO1", /* GPIO40 */ "WL_ON", /* GPIO41 */ "NC", /* GPIO42 */
From: Phil Elwell phil@raspberrypi.com
[ Upstream commit 9fd26fd02749ec964eb0d588a3bab9e09bf77927 ]
The GPIOs 46 & 47 are already used for a I2C interface to a SMPS. So fix the GPIO line names accordingly.
Fixes: a54fe8a6cf66 ("ARM: dts: add Raspberry Pi Compute Module 3 and IO board") Signed-off-by: Phil Elwell phil@raspberrypi.com Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts b/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts index 588d9411ceb6..3dfce4312dfc 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts @@ -63,8 +63,8 @@ "GPIO43", "GPIO44", "GPIO45", - "GPIO46", - "GPIO47", + "SMPS_SCL", + "SMPS_SDA", /* Used by eMMC */ "SD_CLK_R", "SD_CMD_R",
From: Phil Elwell phil@raspberrypi.com
[ Upstream commit 57f718aa4b93392fb1a8c0a874ab882b9e18136a ]
The red LED on the Raspberry Pi 3 B Plus is the power LED. So fix the GPIO line name accordingly.
Fixes: 71c0cd2283f2 ("ARM: dts: bcm2837: Add Raspberry Pi 3 B+") Signed-off-by: Phil Elwell phil@raspberrypi.com Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts index e12938baaf12..c263f5b48b96 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts @@ -45,7 +45,7 @@ #gpio-cells = <2>; gpio-line-names = "BT_ON", "WL_ON", - "STATUS_LED_R", + "PWR_LED_R", "LAN_RUN", "", "CAM_GPIO0",
From: Stefan Wahren stefan.wahren@i2se.com
[ Upstream commit 97bd8659c1c46c23e4daea7e040befca30939950 ]
Recently this has been fixed in the vendor tree, so upstream this.
Fixes: 731b26a6ac17 ("ARM: bcm2835: Add names for the Raspberry Pi GPIO lines") Signed-off-by: Phil Elwell phil@raspberrypi.com Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm2835-rpi-b.dts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts index 1b63d6b19750..25d87212cefd 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts @@ -53,18 +53,17 @@ "GPIO18", "NC", /* GPIO19 */ "NC", /* GPIO20 */ - "GPIO21", + "CAM_GPIO0", "GPIO22", "GPIO23", "GPIO24", "GPIO25", "NC", /* GPIO26 */ - "CAM_GPIO0", - /* Binary number representing build/revision */ - "CONFIG0", - "CONFIG1", - "CONFIG2", - "CONFIG3", + "GPIO27", + "GPIO28", + "GPIO29", + "GPIO30", + "GPIO31", "NC", /* GPIO32 */ "NC", /* GPIO33 */ "NC", /* GPIO34 */
From: Hangyu Hua hbh25y@gmail.com
[ Upstream commit 950cf957fe34d40d63dfa3bf3968210430b6491e ]
info_release() will be called in device_unregister() when info->dev's reference count is 0. So there is no need to call ocxl_afu_put() and kfree() again.
Fix this by adding free_minor() and return to err_unregister error path.
Fixes: 75ca758adbaf ("ocxl: Create a clear delineation between ocxl backend & frontend") Signed-off-by: Hangyu Hua hbh25y@gmail.com Acked-by: Frederic Barrat fbarrat@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220418085758.38145-1-hbh25y@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/ocxl/file.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index d881f5e40ad9..6777c419a8da 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -556,7 +556,9 @@ int ocxl_file_register_afu(struct ocxl_afu *afu)
err_unregister: ocxl_sysfs_unregister_afu(info); // safe to call even if register failed + free_minor(info); device_unregister(&info->dev); + return rc; err_put: ocxl_afu_put(afu); free_minor(info);
From: Vladis Dronov vdronov@redhat.com
[ Upstream commit 753d6770879894de10d74b437ab99ea380f1cad7 ]
This function assumes that sizeof(void) is 1 and arithmetic works for void pointers. This is a GNU C extention and may not work with other compilers. Change this by using an u8 pointer.
Also move cn10k_read_trng() out of a loop thus saving some cycles.
Fixes: 38e9791a0209 ("hwrng: cn10k - Add random number generator support") Signed-off-by: Vladis Dronov vdronov@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/cn10k-rng.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/char/hw_random/cn10k-rng.c b/drivers/char/hw_random/cn10k-rng.c index 35001c63648b..dd226630b67d 100644 --- a/drivers/char/hw_random/cn10k-rng.c +++ b/drivers/char/hw_random/cn10k-rng.c @@ -90,6 +90,7 @@ static int cn10k_rng_read(struct hwrng *hwrng, void *data, { struct cn10k_rng *rng = (struct cn10k_rng *)hwrng->priv; unsigned int size; + u8 *pos = data; int err = 0; u64 value;
@@ -102,17 +103,20 @@ static int cn10k_rng_read(struct hwrng *hwrng, void *data, while (size >= 8) { cn10k_read_trng(rng, &value);
- *((u64 *)data) = (u64)value; + *((u64 *)pos) = value; size -= 8; - data += 8; + pos += 8; }
- while (size > 0) { + if (size > 0) { cn10k_read_trng(rng, &value);
- *((u8 *)data) = (u8)value; - size--; - data++; + while (size > 0) { + *pos = (u8)value; + value >>= 8; + size--; + pos++; + } }
return max - size;
From: Vladis Dronov vdronov@redhat.com
[ Upstream commit 32547a6aedda132907fcd15cdc8271429609f216 ]
Currently check_rng_health() returns zero unconditionally. Make it to output an error code and return it.
Fixes: 38e9791a0209 ("hwrng: cn10k - Add random number generator support") Signed-off-by: Vladis Dronov vdronov@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/cn10k-rng.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/char/hw_random/cn10k-rng.c b/drivers/char/hw_random/cn10k-rng.c index dd226630b67d..a01e9307737c 100644 --- a/drivers/char/hw_random/cn10k-rng.c +++ b/drivers/char/hw_random/cn10k-rng.c @@ -31,26 +31,23 @@ struct cn10k_rng {
#define PLAT_OCTEONTX_RESET_RNG_EBG_HEALTH_STATE 0xc2000b0f
-static int reset_rng_health_state(struct cn10k_rng *rng) +static unsigned long reset_rng_health_state(struct cn10k_rng *rng) { struct arm_smccc_res res;
/* Send SMC service call to reset EBG health state */ arm_smccc_smc(PLAT_OCTEONTX_RESET_RNG_EBG_HEALTH_STATE, 0, 0, 0, 0, 0, 0, 0, &res); - if (res.a0 != 0UL) - return -EIO; - - return 0; + return res.a0; }
static int check_rng_health(struct cn10k_rng *rng) { u64 status; - int err; + unsigned long err;
/* Skip checking health */ if (!rng->reg_base) - return 0; + return -ENODEV;
status = readq(rng->reg_base + RNM_PF_EBG_HEALTH); if (status & BIT_ULL(20)) { @@ -58,7 +55,9 @@ static int check_rng_health(struct cn10k_rng *rng) if (err) { dev_err(&rng->pdev->dev, "HWRNG: Health test failed (status=%llx)\n", status); - dev_err(&rng->pdev->dev, "HWRNG: error during reset\n"); + dev_err(&rng->pdev->dev, "HWRNG: error during reset (error=%lx)\n", + err); + return -EIO; } } return 0;
From: Corentin Labbe clabbe@baylibre.com
[ Upstream commit 4ffa1763622ae5752961499588f3f8874315f974 ]
The DES3 ECB has an IV size set but ECB does not need one.
Fixes: 4ada483978237 ("crypto: marvell/cesa - add Triple-DES support") Signed-off-by: Corentin Labbe clabbe@baylibre.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/marvell/cesa/cipher.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/crypto/marvell/cesa/cipher.c b/drivers/crypto/marvell/cesa/cipher.c index b739d3b873dc..c6f2fa753b7c 100644 --- a/drivers/crypto/marvell/cesa/cipher.c +++ b/drivers/crypto/marvell/cesa/cipher.c @@ -624,7 +624,6 @@ struct skcipher_alg mv_cesa_ecb_des3_ede_alg = { .decrypt = mv_cesa_ecb_des3_ede_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = DES3_EDE_BLOCK_SIZE, .base = { .cra_name = "ecb(des3_ede)", .cra_driver_name = "mv-ecb-des3-ede",
From: Stefan Wahren stefan.wahren@i2se.com
[ Upstream commit 3550bba25d5587a701e6edf20e20984d2ee72c78 ]
Since commit 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges") the device tree nodes of GPIO controller need the gpio-ranges property to handle gpio-hogs. Unfortunately it's impossible to guarantee that every new kernel is shipped with an updated device tree binary.
In order to provide backward compatibility with those older DTB, we need a callback within of_gpiochip_add_pin_range() so the relevant platform driver can handle this case.
Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges") Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Tested-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Bartosz Golaszewski brgl@bgdev.pl Link: https://lore.kernel.org/r/20220409095129.45786-2-stefan.wahren@i2se.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpiolib-of.c | 5 +++++ include/linux/gpio/driver.h | 12 ++++++++++++ 2 files changed, 17 insertions(+)
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 7e5e51d49d09..6dec81b1f24b 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -931,6 +931,11 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!np) return 0;
+ if (!of_property_read_bool(np, "gpio-ranges") && + chip->of_gpio_ranges_fallback) { + return chip->of_gpio_ranges_fallback(chip, np); + } + group_names = of_find_property(np, group_names_propname, NULL);
for (;; index++) { diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 874aabd270c9..48d03eb4e5d8 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -501,6 +501,18 @@ struct gpio_chip { */ int (*of_xlate)(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); + + /** + * @of_gpio_ranges_fallback: + * + * Optional hook for the case that no gpio-ranges property is defined + * within the device tree node "np" (usually DT before introduction + * of gpio-ranges). So this callback is helpful to provide the + * necessary backward compatibility for the pin ranges. + */ + int (*of_gpio_ranges_fallback)(struct gpio_chip *gc, + struct device_node *np); + #endif /* CONFIG_OF_GPIO */ };
From: Stefan Wahren stefan.wahren@i2se.com
[ Upstream commit d2b67744fd99b06555b7e4d67302ede6c7c6a638 ]
The commit c8013355ead6 ("ARM: dts: gpio-ranges property is now required") fixed the GPIO probing issues caused by "pinctrl: bcm2835: Change init order for gpio hogs". This changed only the kernel DTS files. Unfortunately it isn't guaranteed that these files are shipped to all users.
So implement the necessary backward compatibility for BCM2835 and BCM2711 platform.
Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs") Signed-off-by: Stefan Wahren stefan.wahren@i2se.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Tested-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/20220409095129.45786-3-stefan.wahren@i2se.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 47e433e09c5c..dad453054776 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -358,6 +358,22 @@ static int bcm2835_gpio_direction_output(struct gpio_chip *chip, return 0; }
+static int bcm2835_of_gpio_ranges_fallback(struct gpio_chip *gc, + struct device_node *np) +{ + struct pinctrl_dev *pctldev = of_pinctrl_get(np); + + of_node_put(np); + + if (!pctldev) + return 0; + + gpiochip_add_pin_range(gc, pinctrl_dev_get_devname(pctldev), 0, 0, + gc->ngpio); + + return 0; +} + static const struct gpio_chip bcm2835_gpio_chip = { .label = MODULE_NAME, .owner = THIS_MODULE, @@ -372,6 +388,7 @@ static const struct gpio_chip bcm2835_gpio_chip = { .base = -1, .ngpio = BCM2835_NUM_GPIOS, .can_sleep = false, + .of_gpio_ranges_fallback = bcm2835_of_gpio_ranges_fallback, };
static const struct gpio_chip bcm2711_gpio_chip = { @@ -388,6 +405,7 @@ static const struct gpio_chip bcm2711_gpio_chip = { .base = -1, .ngpio = BCM2711_NUM_GPIOS, .can_sleep = false, + .of_gpio_ranges_fallback = bcm2835_of_gpio_ranges_fallback, };
static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
From: Chia-I Wu olvaffe@gmail.com
[ Upstream commit 15c411980bacddf294452fd1cf7308b14f3f8c63 ]
Move tracking and busy time calculation to msm_devfreq_get_dev_status.
Signed-off-by: Chia-I Wu olvaffe@gmail.com Cc: Rob Clark robdclark@chromium.org Link: https://lore.kernel.org/r/20220416003314.59211-2-olvaffe@gmail.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 19 ++++++---------- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 15 +++++-------- drivers/gpu/drm/msm/msm_gpu.h | 9 +++----- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 32 ++++++++++++++++++++++----- 4 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 407f50a15faa..217615e0e850 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1662,28 +1662,23 @@ static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu) return a5xx_gpu->cur_ring; }
-static unsigned long a5xx_gpu_busy(struct msm_gpu *gpu) +static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) { - u64 busy_cycles, busy_time; + 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) + 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); - - busy_time = busy_cycles - gpu->devfreq.busy_cycles; - do_div(busy_time, clk_get_rate(gpu->core_clk) / 1000000); - - gpu->devfreq.busy_cycles = busy_cycles; + *out_sample_rate = clk_get_rate(gpu->core_clk);
pm_runtime_put(&gpu->pdev->dev);
- if (WARN_ON(busy_time > ~0LU)) - return ~0LU; - - return (unsigned long)busy_time; + return busy_cycles; }
static uint32_t a5xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index a8f6d73197b1..40fb92becc78 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1649,12 +1649,14 @@ static void a6xx_destroy(struct msm_gpu *gpu) kfree(a6xx_gpu); }
-static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) +static u64 a6xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); - u64 busy_cycles, busy_time; + u64 busy_cycles;
+ /* 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) @@ -1664,17 +1666,10 @@ static unsigned long a6xx_gpu_busy(struct msm_gpu *gpu) REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
- busy_time = (busy_cycles - gpu->devfreq.busy_cycles) * 10; - do_div(busy_time, 192); - - gpu->devfreq.busy_cycles = busy_cycles;
pm_runtime_put(a6xx_gpu->gmu.dev);
- if (WARN_ON(busy_time > ~0LU)) - return ~0LU; - - return (unsigned long)busy_time; + return busy_cycles; }
static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp) diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 02419f2ca2bc..389c6dab751b 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -62,7 +62,7 @@ struct msm_gpu_funcs { /* for generation specific debugfs: */ void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor); #endif - unsigned long (*gpu_busy)(struct msm_gpu *gpu); + 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); @@ -106,11 +106,8 @@ struct msm_gpu_devfreq { struct dev_pm_qos_request boost_freq;
/** - * busy_cycles: - * - * Used by implementation of gpu->gpu_busy() to track the last - * busy counter value, for calculating elapsed busy cycles since - * last sampling period. + * busy_cycles: Last busy counter value, for calculating elapsed busy + * cycles since last sampling period. */ u64 busy_cycles;
diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 12641616acd3..d2b4c646a0ae 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -49,18 +49,38 @@ static unsigned long get_freq(struct msm_gpu *gpu) return clk_get_rate(gpu->core_clk); }
-static int msm_devfreq_get_dev_status(struct device *dev, +static void get_raw_dev_status(struct msm_gpu *gpu, struct devfreq_dev_status *status) { - struct msm_gpu *gpu = dev_to_gpu(dev); + struct msm_gpu_devfreq *df = &gpu->devfreq; + u64 busy_cycles, busy_time; + unsigned long sample_rate; ktime_t time;
status->current_frequency = get_freq(gpu); - status->busy_time = gpu->funcs->gpu_busy(gpu); - + busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate); time = ktime_get(); - status->total_time = ktime_us_delta(time, gpu->devfreq.time); - gpu->devfreq.time = time; + + busy_time = busy_cycles - df->busy_cycles; + status->total_time = ktime_us_delta(time, df->time); + + df->busy_cycles = busy_cycles; + df->time = time; + + busy_time *= USEC_PER_SEC; + do_div(busy_time, sample_rate); + if (WARN_ON(busy_time > ~0LU)) + busy_time = ~0LU; + + status->busy_time = busy_time; +} + +static int msm_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *status) +{ + struct msm_gpu *gpu = dev_to_gpu(dev); + + get_raw_dev_status(gpu, status);
return 0; }
From: Chia-I Wu olvaffe@gmail.com
[ Upstream commit 78f815c1cf8fc5f05dc5cec29eb1895cb53470e9 ]
simple_ondemand interacts poorly with clamp_to_idle. It only looks at the load since the last get_dev_status call, while it should really look at the load over polling_ms. When clamp_to_idle true, it almost always picks the lowest frequency on active because the gpu is idle between msm_devfreq_idle/msm_devfreq_active.
This logic could potentially be moved into devfreq core.
Fixes: 7c0ffcd40b16 ("drm/msm/gpu: Respect PM QoS constraints") Signed-off-by: Chia-I Wu olvaffe@gmail.com Cc: Rob Clark robdclark@chromium.org Link: https://lore.kernel.org/r/20220416003314.59211-3-olvaffe@gmail.com Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_gpu.h | 3 ++ drivers/gpu/drm/msm/msm_gpu_devfreq.c | 60 ++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 389c6dab751b..143c56f5185b 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -9,6 +9,7 @@
#include <linux/adreno-smmu-priv.h> #include <linux/clk.h> +#include <linux/devfreq.h> #include <linux/interconnect.h> #include <linux/pm_opp.h> #include <linux/regulator/consumer.h> @@ -117,6 +118,8 @@ struct msm_gpu_devfreq { /** idle_time: Time of last transition to idle: */ ktime_t idle_time;
+ struct devfreq_dev_status average_status; + /** * idle_work: * diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index d2b4c646a0ae..c7dbaa4b1926 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -9,6 +9,7 @@
#include <linux/devfreq.h> #include <linux/devfreq_cooling.h> +#include <linux/math64.h> #include <linux/units.h>
/* @@ -75,12 +76,69 @@ static void get_raw_dev_status(struct msm_gpu *gpu, status->busy_time = busy_time; }
+static void update_average_dev_status(struct msm_gpu *gpu, + const struct devfreq_dev_status *raw) +{ + struct msm_gpu_devfreq *df = &gpu->devfreq; + const u32 polling_ms = df->devfreq->profile->polling_ms; + const u32 max_history_ms = polling_ms * 11 / 10; + struct devfreq_dev_status *avg = &df->average_status; + u64 avg_freq; + + /* simple_ondemand governor interacts poorly with gpu->clamp_to_idle. + * When we enforce the constraint on idle, it calls get_dev_status + * which would normally reset the stats. When we remove the + * constraint on active, it calls get_dev_status again where busy_time + * would be 0. + * + * To remedy this, we always return the average load over the past + * polling_ms. + */ + + /* raw is longer than polling_ms or avg has no history */ + if (div_u64(raw->total_time, USEC_PER_MSEC) >= polling_ms || + !avg->total_time) { + *avg = *raw; + return; + } + + /* Truncate the oldest history first. + * + * Because we keep the history with a single devfreq_dev_status, + * rather than a list of devfreq_dev_status, we have to assume freq + * and load are the same over avg->total_time. We can scale down + * avg->busy_time and avg->total_time by the same factor to drop + * history. + */ + if (div_u64(avg->total_time + raw->total_time, USEC_PER_MSEC) >= + max_history_ms) { + const u32 new_total_time = polling_ms * USEC_PER_MSEC - + raw->total_time; + avg->busy_time = div_u64( + mul_u32_u32(avg->busy_time, new_total_time), + avg->total_time); + avg->total_time = new_total_time; + } + + /* compute the average freq over avg->total_time + raw->total_time */ + avg_freq = mul_u32_u32(avg->current_frequency, avg->total_time); + avg_freq += mul_u32_u32(raw->current_frequency, raw->total_time); + do_div(avg_freq, avg->total_time + raw->total_time); + + avg->current_frequency = avg_freq; + avg->busy_time += raw->busy_time; + avg->total_time += raw->total_time; +} + static int msm_devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *status) { struct msm_gpu *gpu = dev_to_gpu(dev); + struct devfreq_dev_status raw;
- get_raw_dev_status(gpu, status); + get_raw_dev_status(gpu, &raw); + update_average_dev_status(gpu, &raw); + *status = gpu->devfreq.average_status;
return 0; }
From: Chuanhong Guo gch981213@gmail.com
[ Upstream commit d66aea197d534e23d4989eb72fca9c0c114b97c9 ]
This chip has an armv7 arch timer according to the dts. Select it in Kconfig to enforce the support for it. Otherwise the system time is just completely wrong if user forget to enable ARM_ARCH_TIMER in kernel config.
Fixes: a43379dddf1b ("arm: mediatek: add MT7629 smp bring up code") Signed-off-by: Chuanhong Guo gch981213@gmail.com Link: https://lore.kernel.org/r/20220409091347.2473449-1-gch981213@gmail.com Signed-off-by: Matthias Brugger matthias.bgg@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-mediatek/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index 9e0f592d87d8..35a3430c7942 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -30,6 +30,7 @@ config MACH_MT7623 config MACH_MT7629 bool "MediaTek MT7629 SoCs support" default ARCH_MEDIATEK + select HAVE_ARM_ARCH_TIMER
config MACH_MT8127 bool "MediaTek MT8127 SoCs support"
From: Caleb Connolly kc@postmarketos.org
[ Upstream commit 8ce5ef64546850294b021497046588a7abcebe96 ]
Add support for deferring other params like PIN_CONFIG_INPUT_ENABLE. This will be used to add support for PIN_CONFIG_INPUT_ENABLE to the driver.
Fixes: e7165b1dff06 ("pinctrl/rockchip: add a queue for deferred pin output settings on probe") Fixes: 59dd178e1d7c ("gpio/rockchip: fetch deferred output settings on probe") Signed-off-by: Caleb Connolly kc@postmarketos.org Link: https://lore.kernel.org/r/20220328005005.72492-2-kc@postmarketos.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpio-rockchip.c | 24 ++++++++----- drivers/pinctrl/pinctrl-rockchip.c | 54 ++++++++++++++++-------------- drivers/pinctrl/pinctrl-rockchip.h | 7 ++-- 3 files changed, 50 insertions(+), 35 deletions(-)
diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index 099e358d2491..bcf5214e3586 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -19,6 +19,7 @@ #include <linux/of_address.h> #include <linux/of_device.h> #include <linux/of_irq.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/regmap.h>
#include "../pinctrl/core.h" @@ -706,7 +707,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev) struct device_node *pctlnp = of_get_parent(np); struct pinctrl_dev *pctldev = NULL; struct rockchip_pin_bank *bank = NULL; - struct rockchip_pin_output_deferred *cfg; + struct rockchip_pin_deferred *cfg; static int gpio; int id, ret;
@@ -747,15 +748,22 @@ static int rockchip_gpio_probe(struct platform_device *pdev) return ret; }
- while (!list_empty(&bank->deferred_output)) { - cfg = list_first_entry(&bank->deferred_output, - struct rockchip_pin_output_deferred, head); + while (!list_empty(&bank->deferred_pins)) { + cfg = list_first_entry(&bank->deferred_pins, + struct rockchip_pin_deferred, head); list_del(&cfg->head);
- ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); - if (ret) - dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, cfg->arg); - + switch (cfg->param) { + case PIN_CONFIG_OUTPUT: + ret = rockchip_gpio_direction_output(&bank->gpio_chip, cfg->pin, cfg->arg); + if (ret) + dev_warn(dev, "setting output pin %u to %u failed\n", cfg->pin, + cfg->arg); + break; + default: + dev_warn(dev, "unknown deferred config param %d\n", cfg->param); + break; + } kfree(cfg); }
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 2cb79e649fcf..bb0783fb86d5 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2110,19 +2110,20 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, return false; }
-static int rockchip_pinconf_defer_output(struct rockchip_pin_bank *bank, - unsigned int pin, u32 arg) +static int rockchip_pinconf_defer_pin(struct rockchip_pin_bank *bank, + unsigned int pin, u32 param, u32 arg) { - struct rockchip_pin_output_deferred *cfg; + struct rockchip_pin_deferred *cfg;
cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); if (!cfg) return -ENOMEM;
cfg->pin = pin; + cfg->param = param; cfg->arg = arg;
- list_add_tail(&cfg->head, &bank->deferred_output); + list_add_tail(&cfg->head, &bank->deferred_pins);
return 0; } @@ -2143,6 +2144,25 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, param = pinconf_to_config_param(configs[i]); arg = pinconf_to_config_argument(configs[i]);
+ if (param == (PIN_CONFIG_OUTPUT | PIN_CONFIG_INPUT_ENABLE)) { + /* + * Check for gpio driver not being probed yet. + * The lock makes sure that either gpio-probe has completed + * or the gpio driver hasn't probed yet. + */ + mutex_lock(&bank->deferred_lock); + if (!gpio || !gpio->direction_output) { + rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param, + arg); + mutex_unlock(&bank->deferred_lock); + if (rc) + return rc; + + break; + } + mutex_unlock(&bank->deferred_lock); + } + switch (param) { case PIN_CONFIG_BIAS_DISABLE: rc = rockchip_set_pull(bank, pin - bank->pin_base, @@ -2171,22 +2191,6 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, if (rc != RK_FUNC_GPIO) return -EINVAL;
- /* - * Check for gpio driver not being probed yet. - * The lock makes sure that either gpio-probe has completed - * or the gpio driver hasn't probed yet. - */ - mutex_lock(&bank->deferred_lock); - if (!gpio || !gpio->direction_output) { - rc = rockchip_pinconf_defer_output(bank, pin - bank->pin_base, arg); - mutex_unlock(&bank->deferred_lock); - if (rc) - return rc; - - break; - } - mutex_unlock(&bank->deferred_lock); - rc = gpio->direction_output(gpio, pin - bank->pin_base, arg); if (rc) @@ -2500,7 +2504,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, pdesc++; }
- INIT_LIST_HEAD(&pin_bank->deferred_output); + INIT_LIST_HEAD(&pin_bank->deferred_pins); mutex_init(&pin_bank->deferred_lock); }
@@ -2763,7 +2767,7 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev) { struct rockchip_pinctrl *info = platform_get_drvdata(pdev); struct rockchip_pin_bank *bank; - struct rockchip_pin_output_deferred *cfg; + struct rockchip_pin_deferred *cfg; int i;
of_platform_depopulate(&pdev->dev); @@ -2772,9 +2776,9 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev) bank = &info->ctrl->pin_banks[i];
mutex_lock(&bank->deferred_lock); - while (!list_empty(&bank->deferred_output)) { - cfg = list_first_entry(&bank->deferred_output, - struct rockchip_pin_output_deferred, head); + while (!list_empty(&bank->deferred_pins)) { + cfg = list_first_entry(&bank->deferred_pins, + struct rockchip_pin_deferred, head); list_del(&cfg->head); kfree(cfg); } diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h index 91f10279d084..98a01a616da6 100644 --- a/drivers/pinctrl/pinctrl-rockchip.h +++ b/drivers/pinctrl/pinctrl-rockchip.h @@ -171,7 +171,7 @@ struct rockchip_pin_bank { u32 toggle_edge_mode; u32 recalced_mask; u32 route_mask; - struct list_head deferred_output; + struct list_head deferred_pins; struct mutex deferred_lock; };
@@ -247,9 +247,12 @@ struct rockchip_pin_config { unsigned int nconfigs; };
-struct rockchip_pin_output_deferred { +enum pin_config_param; + +struct rockchip_pin_deferred { struct list_head head; unsigned int pin; + enum pin_config_param param; u32 arg; };
Hi Greg,
This commit contains a bug which was fixed in commit 42d90a1e5caf ("pinctrl/rockchip: support setting input-enable param")
It uses bitwise OR to check non-bitwise values (see below).
On 07/06/2022 18:01, Greg Kroah-Hartman wrote:
From: Caleb Connolly kc@postmarketos.org
[ Upstream commit 8ce5ef64546850294b021497046588a7abcebe96 ]
Add support for deferring other params like PIN_CONFIG_INPUT_ENABLE. This will be used to add support for PIN_CONFIG_INPUT_ENABLE to the driver.
Fixes: e7165b1dff06 ("pinctrl/rockchip: add a queue for deferred pin output settings on probe") Fixes: 59dd178e1d7c ("gpio/rockchip: fetch deferred output settings on probe") Signed-off-by: Caleb Connolly kc@postmarketos.org Link: https://lore.kernel.org/r/20220328005005.72492-2-kc@postmarketos.org Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org
drivers/gpio/gpio-rockchip.c | 24 ++++++++----- drivers/pinctrl/pinctrl-rockchip.c | 54 ++++++++++++++++-------------- drivers/pinctrl/pinctrl-rockchip.h | 7 ++-- 3 files changed, 50 insertions(+), 35 deletions(-)
[snip]
@@ -2143,6 +2144,25 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, param = pinconf_to_config_param(configs[i]); arg = pinconf_to_config_argument(configs[i]);
if (param == (PIN_CONFIG_OUTPUT | PIN_CONFIG_INPUT_ENABLE)) {
Should be if (param == PIN_CONFIG_OUTPUT || param == PIN_CONFIG_INPUT_ENABLE) {
/*
* Check for gpio driver not being probed yet.
* The lock makes sure that either gpio-probe has completed
* or the gpio driver hasn't probed yet.
*/
mutex_lock(&bank->deferred_lock);
if (!gpio || !gpio->direction_output) {
rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param,
arg);
mutex_unlock(&bank->deferred_lock);
if (rc)
return rc;
break;
}
mutex_unlock(&bank->deferred_lock);
}
- switch (param) { case PIN_CONFIG_BIAS_DISABLE: rc = rockchip_set_pull(bank, pin - bank->pin_base,
@@ -2171,22 +2191,6 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, if (rc != RK_FUNC_GPIO) return -EINVAL;
/*
* Check for gpio driver not being probed yet.
* The lock makes sure that either gpio-probe has completed
* or the gpio driver hasn't probed yet.
*/
mutex_lock(&bank->deferred_lock);
if (!gpio || !gpio->direction_output) {
rc = rockchip_pinconf_defer_output(bank, pin - bank->pin_base, arg);
mutex_unlock(&bank->deferred_lock);
if (rc)
return rc;
break;
}
mutex_unlock(&bank->deferred_lock);
rc = gpio->direction_output(gpio, pin - bank->pin_base, arg); if (rc)
@@ -2500,7 +2504,7 @@ static int rockchip_pinctrl_register(struct platform_device *pdev, pdesc++; }
INIT_LIST_HEAD(&pin_bank->deferred_output);
mutex_init(&pin_bank->deferred_lock); }INIT_LIST_HEAD(&pin_bank->deferred_pins);
@@ -2763,7 +2767,7 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev) { struct rockchip_pinctrl *info = platform_get_drvdata(pdev); struct rockchip_pin_bank *bank;
- struct rockchip_pin_output_deferred *cfg;
- struct rockchip_pin_deferred *cfg; int i;
of_platform_depopulate(&pdev->dev); @@ -2772,9 +2776,9 @@ static int rockchip_pinctrl_remove(struct platform_device *pdev) bank = &info->ctrl->pin_banks[i]; mutex_lock(&bank->deferred_lock);
while (!list_empty(&bank->deferred_output)) {
cfg = list_first_entry(&bank->deferred_output,
struct rockchip_pin_output_deferred, head);
while (!list_empty(&bank->deferred_pins)) {
cfg = list_first_entry(&bank->deferred_pins,
}struct rockchip_pin_deferred, head); list_del(&cfg->head); kfree(cfg);
diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h index 91f10279d084..98a01a616da6 100644 --- a/drivers/pinctrl/pinctrl-rockchip.h +++ b/drivers/pinctrl/pinctrl-rockchip.h @@ -171,7 +171,7 @@ struct rockchip_pin_bank { u32 toggle_edge_mode; u32 recalced_mask; u32 route_mask;
- struct list_head deferred_output;
- struct list_head deferred_pins; struct mutex deferred_lock; };
@@ -247,9 +247,12 @@ struct rockchip_pin_config { unsigned int nconfigs; }; -struct rockchip_pin_output_deferred { +enum pin_config_param;
+struct rockchip_pin_deferred { struct list_head head; unsigned int pin;
- enum pin_config_param param; u32 arg; };
On Wed, Jun 08, 2022 at 11:25:02AM +0100, Caleb Connolly wrote:
Hi Greg,
This commit contains a bug which was fixed in commit 42d90a1e5caf ("pinctrl/rockchip: support setting input-enable param")
Thanks for letting me know, have now picked that one up too.
greg k-h
From: Fabien Parent fparent@baylibre.com
[ Upstream commit 931d7fa89e640dea146e00b77c1d73459e66ab6e ]
Set the pinctrl driver as built-in by default if ARM64 and ARCH_MEDIATEK are enabled.
Fixes: 6cf5e9ef362a ("pinctrl: add pinctrl driver on mt8195") Signed-off-by: Fabien Parent fparent@baylibre.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Miles Chen miles.chen@mediatek.com Link: https://lore.kernel.org/r/20220327160813.2978637-1-fparent@baylibre.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mediatek/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index 40accd110c3d..b3074082c56d 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -166,6 +166,7 @@ config PINCTRL_MT8195 bool "Mediatek MT8195 pin control" depends on OF depends on ARM64 || COMPILE_TEST + default ARM64 && ARCH_MEDIATEK select PINCTRL_MTK_PARIS
config PINCTRL_MT8365
From: Vinod Koul vkoul@kernel.org
[ Upstream commit 1eae95fb1d696968ca72be3ac8e0d62bb4d8da42 ]
Per DT spec node names should not have underscores (_) in them, so change can_clock to can-clock.
Fixes: 5c44c564e449 ("arm64: dts: qcom: qrb5165-rb5: Add support for MCP2518FD") Signed-off-by: Vinod Koul vkoul@kernel.org Acked-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220421073502.1824089-1-vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/qrb5165-rb5.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts index 845eb7a6bf92..0e63f707b911 100644 --- a/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ b/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -29,7 +29,7 @@ };
/* Fixed crystal oscillator dedicated to MCP2518FD */ - clk40M: can_clock { + clk40M: can-clock { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <40000000>;
From: Andrea Parri (Microsoft) parri.andrea@gmail.com
[ Upstream commit 82cd4bacff88a11e36f143e2cb950174b09c86c3 ]
vmbus_request_addr() returns 0 (zero) if the transaction ID passed to as argument is 0. This is unfortunate for two reasons: first, netvsc_send_completion() does not check for a NULL cmd_rqst (before dereferencing the corresponding NVSP message); second, 0 is a *valid* value of cmd_rqst in netvsc_send_tx_complete(), cf. the call of vmbus_sendpacket() in netvsc_send_pkt().
vmbus_request_addr() has included the code in question since its introduction with commit e8b7db38449ac ("Drivers: hv: vmbus: Add vmbus_requestor data structure for VMBus hardening"); such code was motivated by the early use of vmbus_requestor by hv_storvsc. Since hv_storvsc moved to a tag-based mechanism to generate and retrieve transaction IDs with commit bf5fd8cae3c8f ("scsi: storvsc: Use blk_mq_unique_tag() to generate requestIDs"), vmbus_request_addr() can be modified to return VMBUS_RQST_ERROR if the ID is 0. This change solves the issues in hv_netvsc (and makes the handling of messages with transaction ID of 0 consistent with the semantics "the ID is not contained in the requestor/invalid ID").
vmbus_next_request_id(), vmbus_request_addr() should still reserve the ID of 0 for Hyper-V, because Hyper-V will "ignore" (not respond to) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED packets/requests with transaction ID of 0 from the guest.
Fixes: bf5fd8cae3c8f ("scsi: storvsc: Use blk_mq_unique_tag() to generate requestIDs") Signed-off-by: Andrea Parri (Microsoft) parri.andrea@gmail.com Reviewed-by: Michael Kelley mikelley@microsoft.com Link: https://lore.kernel.org/r/20220419122325.10078-2-parri.andrea@gmail.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hv/channel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index dc5c35210c16..20fc8d50a039 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -1245,7 +1245,9 @@ u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr)
/* * Cannot return an ID of 0, which is reserved for an unsolicited - * message from Hyper-V. + * message from Hyper-V; Hyper-V does not acknowledge (respond to) + * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED requests with ID of + * 0 sent by the guest. */ return current_id + 1; } @@ -1270,7 +1272,7 @@ u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id)
/* Hyper-V can send an unsolicited message with ID of 0 */ if (!trans_id) - return trans_id; + return VMBUS_RQST_ERROR;
spin_lock_irqsave(&rqstor->req_lock, flags);
From: Hari Bathini hbathini@linux.ibm.com
[ Upstream commit 15eb77f873255cf9f4d703b63cfbd23c46579654 ]
Boot memory area is setup as separate PT_LOAD segment in the vmcore as it is moved by f/w, on crash, to a destination address provided by the kernel. Having separate PT_LOAD segment helps in handling the different physical address and offset for boot memory area in the vmcore.
Commit ced1bf52f477 ("powerpc/fadump: merge adjacent memory ranges to reduce PT_LOAD segements") inadvertly broke this pre-condition for cases where some of the first kernel memory is available adjacent to boot memory area. This scenario is rare but possible when memory for fadump could not be reserved adjacent to boot memory area owing to memory hole or such. Reading memory from a vmcore exported in such scenario provides incorrect data. Fix it by ensuring no other region is folded into boot memory area.
Fixes: ced1bf52f477 ("powerpc/fadump: merge adjacent memory ranges to reduce PT_LOAD segements") Signed-off-by: Hari Bathini hbathini@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220406093839.206608-2-hbathini@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/fadump.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 65562c4a0a69..dc2350b288cf 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -867,7 +867,6 @@ static int fadump_alloc_mem_ranges(struct fadump_mrange_info *mrange_info) sizeof(struct fadump_memory_range)); return 0; } - static inline int fadump_add_mem_range(struct fadump_mrange_info *mrange_info, u64 base, u64 end) { @@ -886,7 +885,12 @@ static inline int fadump_add_mem_range(struct fadump_mrange_info *mrange_info, start = mem_ranges[mrange_info->mem_range_cnt - 1].base; size = mem_ranges[mrange_info->mem_range_cnt - 1].size;
- if ((start + size) == base) + /* + * Boot memory area needs separate PT_LOAD segment(s) as it + * is moved to a different location at the time of crash. + * So, fold only if the region is not boot memory area. + */ + if ((start + size) == base && start >= fw_dump.boot_mem_top) is_adjacent = true; } if (!is_adjacent) {
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit 3b49ae380ce1a3054e0c505dd9a356b82a5b48e8 ]
platform_get_irq() return negative value on failure, so null check of irq is incorrect. Fix it by comparing whether it is less than zero.
Fixes: dcc21cc09e3c ("mfd: Add driver for Atmel Microcontroller on iPaq h3xxx") Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20220412085305.2533030-1-lv.ruyi@zte.com.cn Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/ipaq-micro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c index e92eeeb67a98..4cd5ecc72211 100644 --- a/drivers/mfd/ipaq-micro.c +++ b/drivers/mfd/ipaq-micro.c @@ -403,7 +403,7 @@ static int __init micro_probe(struct platform_device *pdev) micro_reset_comm(micro);
irq = platform_get_irq(pdev, 0); - if (!irq) + if (irq < 0) return -EINVAL; ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr, IRQF_SHARED, "ipaq-micro",
From: Gustavo A. R. Silva gustavoars@kernel.org
[ Upstream commit 54db804d5d7d36709d1ce70bde3b9a6c61b290b6 ]
Fix the following Wstringop-overflow warnings when building with GCC-11:
drivers/scsi/fcoe/fcoe.c: In function ‘fcoe_netdev_config’: drivers/scsi/fcoe/fcoe.c:744:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=] 744 | wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/scsi/fcoe/fcoe.c:744:32: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/fcoe/fcoe.c:36: ./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); | ^~~~~~~~~~~~~~~~~ drivers/scsi/fcoe/fcoe.c:747:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=] 747 | wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 748 | 2, 0); | ~~~~~ drivers/scsi/fcoe/fcoe.c:747:32: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/fcoe/fcoe.c:36: ./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); | ^~~~~~~~~~~~~~~~~ CC drivers/scsi/bnx2fc/bnx2fc_io.o In function ‘bnx2fc_net_config’, inlined from ‘bnx2fc_if_create’ at drivers/scsi/bnx2fc/bnx2fc_fcoe.c:1543:7: drivers/scsi/bnx2fc/bnx2fc_fcoe.c:833:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=] 833 | wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 834 | 1, 0); | ~~~~~ drivers/scsi/bnx2fc/bnx2fc_fcoe.c: In function ‘bnx2fc_if_create’: drivers/scsi/bnx2fc/bnx2fc_fcoe.c:833:32: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/bnx2fc/bnx2fc.h:53, from drivers/scsi/bnx2fc/bnx2fc_fcoe.c:17: ./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); | ^~~~~~~~~~~~~~~~~ In function ‘bnx2fc_net_config’, inlined from ‘bnx2fc_if_create’ at drivers/scsi/bnx2fc/bnx2fc_fcoe.c:1543:7: drivers/scsi/bnx2fc/bnx2fc_fcoe.c:839:32: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=] 839 | wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 840 | 2, 0); | ~~~~~ drivers/scsi/bnx2fc/bnx2fc_fcoe.c: In function ‘bnx2fc_if_create’: drivers/scsi/bnx2fc/bnx2fc_fcoe.c:839:32: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/bnx2fc/bnx2fc.h:53, from drivers/scsi/bnx2fc/bnx2fc_fcoe.c:17: ./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); | ^~~~~~~~~~~~~~~~~ drivers/scsi/qedf/qedf_main.c: In function ‘__qedf_probe’: drivers/scsi/qedf/qedf_main.c:3520:30: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=] 3520 | qedf->wwnn = fcoe_wwn_from_mac(qedf->mac, 1, 0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/scsi/qedf/qedf_main.c:3520:30: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/qedf/qedf.h:9, from drivers/scsi/qedf/qedf_main.c:23: ./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); | ^~~~~~~~~~~~~~~~~ drivers/scsi/qedf/qedf_main.c:3521:30: warning: ‘fcoe_wwn_from_mac’ accessing 32 bytes in a region of size 6 [-Wstringop-overflow=] 3521 | qedf->wwpn = fcoe_wwn_from_mac(qedf->mac, 2, 0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/scsi/qedf/qedf_main.c:3521:30: note: referencing argument 1 of type ‘unsigned char *’ In file included from drivers/scsi/qedf/qedf.h:9, from drivers/scsi/qedf/qedf_main.c:23: ./include/scsi/libfcoe.h:252:5: note: in a call to function ‘fcoe_wwn_from_mac’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); | ^~~~~~~~~~~~~~~~~
by changing the array size to the correct value of ETH_ALEN in the argument declaration.
Also, fix a couple of checkpatch warnings: WARNING: function definition argument 'unsigned int' should also have an identifier name
This helps with the ongoing efforts to globally enable -Wstringop-overflow.
Link: https://github.com/KSPP/linux/issues/181 Fixes: 85b4aa4926a5 ("[SCSI] fcoe: Fibre Channel over Ethernet") Signed-off-by: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/fcoe/fcoe_ctlr.c | 2 +- include/scsi/libfcoe.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 1756a0ac6f08..558f3f4e1859 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -1969,7 +1969,7 @@ EXPORT_SYMBOL(fcoe_ctlr_recv_flogi); * * Returns: u64 fc world wide name */ -u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], +u64 fcoe_wwn_from_mac(unsigned char mac[ETH_ALEN], unsigned int scheme, unsigned int port) { u64 wwn; diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index fac8e89aed81..310e0dbffda9 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -249,7 +249,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, struct fc_frame *);
/* libfcoe funcs */ -u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); +u64 fcoe_wwn_from_mac(unsigned char mac[ETH_ALEN], unsigned int scheme, + unsigned int port); int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *, const struct libfc_function_template *, int init_fcp); u32 fcoe_fc_crc(struct fc_frame *fp);
From: QintaoShen unSimple1993@163.com
[ Upstream commit b4bd2aafacce48db26b0a213d849818d940556dd ]
As the potential failure of allocation, devm_kzalloc() may return NULL. Then the 'pd->pmb' and the follow lines of code may bring null pointer dereference.
Therefore, it is better to check the return value of devm_kzalloc() to avoid this confusion.
Fixes: 8bcac4011ebe ("soc: bcm: add PM driver for Broadcom's PMB") Signed-off-by: QintaoShen unSimple1993@163.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/bcm/bcm63xx/bcm-pmb.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/soc/bcm/bcm63xx/bcm-pmb.c b/drivers/soc/bcm/bcm63xx/bcm-pmb.c index 7bbe46ea5f94..9407cac47fdb 100644 --- a/drivers/soc/bcm/bcm63xx/bcm-pmb.c +++ b/drivers/soc/bcm/bcm63xx/bcm-pmb.c @@ -312,6 +312,9 @@ static int bcm_pmb_probe(struct platform_device *pdev) for (e = table; e->name; e++) { struct bcm_pmb_pm_domain *pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) + return -ENOMEM; + pd->pmb = pmb; pd->data = e; pd->genpd.name = e->name;
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit 439677d416b17dd39964d5f7d64b742a2e51da5b ]
We found that (at least some versions of) the sci-fw set the base clock rate for UARTs in the MCU domain to 96 MHz instead of the expected 48 MHz, leading to incorrect baud rates when used from Linux.
As the 8250_omap driver will query the actual clock rate from the clk driver when clock-frequency is unset, removing the incorrect property is sufficient to fix the baud rate.
Fixes: 8abae9389bdb ("arm64: dts: ti: Add support for AM642 SoC") Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Signed-off-by: Vignesh Raghavendra vigneshr@ti.com Reviewed-by: Vignesh Raghavendra vigneshr@ti.com Link: https://lore.kernel.org/r/20220419075157.189347-1-matthias.schiffer@ew.tq-gr... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi | 2 -- 1 file changed, 2 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi index 2bb5c9ff172c..02d4285acbb8 100644 --- a/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am64-mcu.dtsi @@ -10,7 +10,6 @@ compatible = "ti,am64-uart", "ti,am654-uart"; reg = <0x00 0x04a00000 0x00 0x100>; interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <48000000>; current-speed = <115200>; power-domains = <&k3_pds 149 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 149 0>; @@ -21,7 +20,6 @@ compatible = "ti,am64-uart", "ti,am654-uart"; reg = <0x00 0x04a10000 0x00 0x100>; interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; - clock-frequency = <48000000>; current-speed = <115200>; power-domains = <&k3_pds 160 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 160 0>;
From: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
[ Upstream commit 91686a3984f34df0ab844cdbaa7e4d9621129f5d ]
Propagate error codes returned from platform_get_irq_byname() instead of returning -ENODEV. platform_get_irq_byname() may return -EPROBE_DEFER, to handle such cases propagate the error codes.
While at it drop the dev_err_probe() messages as platform_get_irq_byname() already does this for us in case of error.
Signed-off-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Link: https://lore.kernel.org/r/20220426074922.13319-3-prabhakar.mahadev-lad.rj@bp... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sh/rz-ssi.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index e8edaed05d4c..8bbcebbe7e73 100644 --- a/sound/soc/sh/rz-ssi.c +++ b/sound/soc/sh/rz-ssi.c @@ -979,8 +979,7 @@ static int rz_ssi_probe(struct platform_device *pdev) /* Error Interrupt */ ssi->irq_int = platform_get_irq_byname(pdev, "int_req"); if (ssi->irq_int < 0) - return dev_err_probe(&pdev->dev, -ENODEV, - "Unable to get SSI int_req IRQ\n"); + return ssi->irq_int;
ret = devm_request_irq(&pdev->dev, ssi->irq_int, &rz_ssi_interrupt, 0, dev_name(&pdev->dev), ssi); @@ -992,8 +991,7 @@ static int rz_ssi_probe(struct platform_device *pdev) /* Tx and Rx interrupts (pio only) */ ssi->irq_tx = platform_get_irq_byname(pdev, "dma_tx"); if (ssi->irq_tx < 0) - return dev_err_probe(&pdev->dev, -ENODEV, - "Unable to get SSI dma_tx IRQ\n"); + return ssi->irq_tx;
ret = devm_request_irq(&pdev->dev, ssi->irq_tx, &rz_ssi_interrupt, 0, @@ -1004,8 +1002,7 @@ static int rz_ssi_probe(struct platform_device *pdev)
ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx"); if (ssi->irq_rx < 0) - return dev_err_probe(&pdev->dev, -ENODEV, - "Unable to get SSI dma_rx IRQ\n"); + return ssi->irq_rx;
ret = devm_request_irq(&pdev->dev, ssi->irq_rx, &rz_ssi_interrupt, 0,
From: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
[ Upstream commit 767e6f26204d3f5406630e86b720d01818b8616d ]
DMA channels requested by rz_ssi_dma_request() in rz_ssi_probe() were never released in the error path apart from one place. This patch fixes this issue by calling rz_ssi_release_dma_channels() in the error path.
Fixes: 26ac471c5354 ("ASoC: sh: rz-ssi: Add SSI DMAC support") Reported-by: Pavel Machek pavel@denx.de Signed-off-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Link: https://lore.kernel.org/r/20220426074922.13319-4-prabhakar.mahadev-lad.rj@bp... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sh/rz-ssi.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index 8bbcebbe7e73..8a0c01ca06be 100644 --- a/sound/soc/sh/rz-ssi.c +++ b/sound/soc/sh/rz-ssi.c @@ -978,14 +978,18 @@ static int rz_ssi_probe(struct platform_device *pdev)
/* Error Interrupt */ ssi->irq_int = platform_get_irq_byname(pdev, "int_req"); - if (ssi->irq_int < 0) + if (ssi->irq_int < 0) { + rz_ssi_release_dma_channels(ssi); return ssi->irq_int; + }
ret = devm_request_irq(&pdev->dev, ssi->irq_int, &rz_ssi_interrupt, 0, dev_name(&pdev->dev), ssi); - if (ret < 0) + if (ret < 0) { + rz_ssi_release_dma_channels(ssi); return dev_err_probe(&pdev->dev, ret, "irq request error (int_req)\n"); + }
if (!rz_ssi_is_dma_enabled(ssi)) { /* Tx and Rx interrupts (pio only) */ @@ -1013,13 +1017,16 @@ static int rz_ssi_probe(struct platform_device *pdev) }
ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(ssi->rstc)) + if (IS_ERR(ssi->rstc)) { + rz_ssi_release_dma_channels(ssi); return PTR_ERR(ssi->rstc); + }
reset_control_deassert(ssi->rstc); pm_runtime_enable(&pdev->dev); ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { + rz_ssi_release_dma_channels(ssi); pm_runtime_disable(ssi->dev); reset_control_assert(ssi->rstc); return dev_err_probe(ssi->dev, ret, "pm_runtime_resume_and_get failed\n");
From: Cristian Marussi cristian.marussi@arm.com
[ Upstream commit 8009120e0354a67068e920eb10dce532391361d0 ]
While enumerating protocols implemented by the SCMI platform using BASE_DISCOVER_LIST_PROTOCOLS, the number of returned protocols is currently validated in an improper way since the check employs a sum between unsigned integers that could overflow and cause the check itself to be silently bypassed if the returned value 'loop_num_ret' is big enough.
Fix the validation avoiding the addition.
Link: https://lore.kernel.org/r/20220330150551.2573938-4-cristian.marussi@arm.com Fixes: b6f20ff8bd94 ("firmware: arm_scmi: add common infrastructure and support for base protocol") Signed-off-by: Cristian Marussi cristian.marussi@arm.com Signed-off-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/arm_scmi/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c index f5219334fd3a..3fe172c03c24 100644 --- a/drivers/firmware/arm_scmi/base.c +++ b/drivers/firmware/arm_scmi/base.c @@ -197,7 +197,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph, break;
loop_num_ret = le32_to_cpu(*num_ret); - if (tot_num_ret + loop_num_ret > MAX_PROTOCOLS_IMP) { + if (loop_num_ret > MAX_PROTOCOLS_IMP - tot_num_ret) { dev_err(dev, "No. of Protocol > MAX_PROTOCOLS_IMP"); break; }
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit e6829d1bd3c4b58296ee9e412f7ed4d6cb390192 ]
Lockdep reports the following deadlock scenarios for CXL root device power-management, device_prepare(), operations, and device_shutdown() operations for 'nd_region' devices:
Chain exists of: &nvdimm_region_key --> &nvdimm_bus->reconfig_mutex --> system_transition_mutex
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(system_transition_mutex); lock(&nvdimm_bus->reconfig_mutex); lock(system_transition_mutex); lock(&nvdimm_region_key);
Chain exists of: &cxl_nvdimm_bridge_key --> acpi_scan_lock --> &cxl_root_key
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&cxl_root_key); lock(acpi_scan_lock); lock(&cxl_root_key); lock(&cxl_nvdimm_bridge_key);
These stem from holding nvdimm_bus_lock() over hibernate_quiet_exec() which walks the entire system device topology taking device_lock() along the way. The nvdimm_bus_lock() is protecting against unregistration, multiple simultaneous ops callers, and preventing activate_show() from racing activate_store(). For the first 2, the lock is redundant. Unregistration already flushes all ops users, and sysfs already prevents multiple threads to be active in an ops handler at the same time. For the last userspace should already be waiting for its last activate_store() to complete, and does not need activate_show() to flush the write side, so this lock usage can be deleted in these attributes.
Fixes: 48001ea50d17 ("PM, libnvdimm: Add runtime firmware activation support") Reviewed-by: Ira Weiny ira.weiny@intel.com Link: https://lore.kernel.org/r/165074883800.4116052.10737040861825806582.stgit@dw... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvdimm/core.c | 9 --------- 1 file changed, 9 deletions(-)
diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index 69a03358817f..681cc28703a3 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -368,9 +368,7 @@ static ssize_t capability_show(struct device *dev, if (!nd_desc->fw_ops) return -EOPNOTSUPP;
- nvdimm_bus_lock(dev); cap = nd_desc->fw_ops->capability(nd_desc); - nvdimm_bus_unlock(dev);
switch (cap) { case NVDIMM_FWA_CAP_QUIESCE: @@ -395,10 +393,8 @@ static ssize_t activate_show(struct device *dev, if (!nd_desc->fw_ops) return -EOPNOTSUPP;
- nvdimm_bus_lock(dev); cap = nd_desc->fw_ops->capability(nd_desc); state = nd_desc->fw_ops->activate_state(nd_desc); - nvdimm_bus_unlock(dev);
if (cap < NVDIMM_FWA_CAP_QUIESCE) return -EOPNOTSUPP; @@ -443,7 +439,6 @@ static ssize_t activate_store(struct device *dev, else return -EINVAL;
- nvdimm_bus_lock(dev); state = nd_desc->fw_ops->activate_state(nd_desc);
switch (state) { @@ -461,7 +456,6 @@ static ssize_t activate_store(struct device *dev, default: rc = -ENXIO; } - nvdimm_bus_unlock(dev);
if (rc == 0) rc = len; @@ -484,10 +478,7 @@ static umode_t nvdimm_bus_firmware_visible(struct kobject *kobj, struct attribut if (!nd_desc->fw_ops) return 0;
- nvdimm_bus_lock(dev); cap = nd_desc->fw_ops->capability(nd_desc); - nvdimm_bus_unlock(dev); - if (cap < NVDIMM_FWA_CAP_QUIESCE) return 0;
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit bb7bf697fed58eae9d3445944e457ab0de4da54f ]
It is not clear why the original implementation of overwrite support required the dimm driver to be active before overwrite could proceed. In fact that can lead to cases where the kernel retains an invalid cached copy of the labels from before the overwrite. Unfortunately the kernel has not only allowed that case, but enforced it.
Going forward, allow for overwrite to happen while the label area is offline, and follow-on with updates to 'ndctl sanitize-dimm --overwrite' to trigger the label area invalidation by default.
Cc: Vishal Verma vishal.l.verma@intel.com Cc: Dave Jiang dave.jiang@intel.com Cc: Ira Weiny ira.weiny@intel.com Cc: Jeff Moyer jmoyer@redhat.com Reported-by: Krzysztof Kensicki krzysztof.kensicki@intel.com Fixes: 7d988097c546 ("acpi/nfit, libnvdimm/security: Add security DSM overwrite support") Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvdimm/security.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c index 4b80150e4afa..b5aa55c61461 100644 --- a/drivers/nvdimm/security.c +++ b/drivers/nvdimm/security.c @@ -379,11 +379,6 @@ static int security_overwrite(struct nvdimm *nvdimm, unsigned int keyid) || !nvdimm->sec.flags) return -EOPNOTSUPP;
- if (dev->driver == NULL) { - dev_dbg(dev, "Unable to overwrite while DIMM active.\n"); - return -EINVAL; - } - rc = check_security_state(nvdimm); if (rc) return rc;
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 71bc7cf3be65bab441e03667cf215c557712976c ]
The irq_of_parse_and_map() returns 0 on failure, not a negative ERRNO.
Fixes: 2f227605394b ("pinctrl: armada-37xx: Add irqchip support") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20220422105339.78810-1-krzysztof.kozlowski@linaro.... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index 08cad14042e2..adccf03b3e5a 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -773,7 +773,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev, for (i = 0; i < nr_irq_parent; i++) { int irq = irq_of_parse_and_map(np, i);
- if (irq < 0) + if (!irq) continue; girq->parents[i] = irq; }
From: Jacky Li jackyli@google.com
[ Upstream commit 05def5cacfa0bd5ba380116046747da07ff5bd78 ]
There are 2 common cases when INIT_EX data file might not be opened successfully and fail the sev initialization:
1. In user namespaces, normal user tasks (e.g. VMM) can change their current->fs->root to point to arbitrary directories. While init_ex_path is provided as a module param related to root file system. Solution: use the root directory of init_task to avoid accessing the wrong file.
2. Normal user tasks (e.g. VMM) don't have the privilege to access the INIT_EX data file. Solution: open the file as root and restore permissions immediately.
Fixes: 3d725965f836 ("crypto: ccp - Add SEV_INIT_EX support") Signed-off-by: Jacky Li jackyli@google.com Reviewed-by: Peter Gonda pgonda@google.com Acked-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/ccp/sev-dev.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 6ab93dfd478a..3aefb177715e 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -23,6 +23,7 @@ #include <linux/gfp.h> #include <linux/cpufeature.h> #include <linux/fs.h> +#include <linux/fs_struct.h>
#include <asm/smp.h>
@@ -170,6 +171,31 @@ static void *sev_fw_alloc(unsigned long len) return page_address(page); }
+static struct file *open_file_as_root(const char *filename, int flags, umode_t mode) +{ + struct file *fp; + struct path root; + struct cred *cred; + const struct cred *old_cred; + + task_lock(&init_task); + get_fs_root(init_task.fs, &root); + task_unlock(&init_task); + + cred = prepare_creds(); + if (!cred) + return ERR_PTR(-ENOMEM); + cred->fsuid = GLOBAL_ROOT_UID; + old_cred = override_creds(cred); + + fp = file_open_root(&root, filename, flags, mode); + path_put(&root); + + revert_creds(old_cred); + + return fp; +} + static int sev_read_init_ex_file(void) { struct sev_device *sev = psp_master->sev_data; @@ -181,7 +207,7 @@ static int sev_read_init_ex_file(void) if (!sev_init_ex_buffer) return -EOPNOTSUPP;
- fp = filp_open(init_ex_path, O_RDONLY, 0); + fp = open_file_as_root(init_ex_path, O_RDONLY, 0); if (IS_ERR(fp)) { int ret = PTR_ERR(fp);
@@ -217,7 +243,7 @@ static void sev_write_init_ex_file(void) if (!sev_init_ex_buffer) return;
- fp = filp_open(init_ex_path, O_CREAT | O_WRONLY, 0600); + fp = open_file_as_root(init_ex_path, O_CREAT | O_WRONLY, 0600); if (IS_ERR(fp)) { dev_err(sev->dev, "SEV: could not open file for write, error %ld\n",
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit da63dc84befaa9e6079a0bc363ff0eaa975f9073 ]
Compaction sysfs file is created via compaction_register_node in register_node. But we forgot to remove it in unregister_node. Thus compaction sysfs file is leaked. Using compaction_unregister_node to fix this issue.
Link: https://lkml.kernel.org/r/20220401070905.43679-1-linmiaohe@huawei.com Fixes: ed4a6d7f0676 ("mm: compaction: add /sys trigger for per-node memory compaction") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Rafael J. Wysocki rafael@kernel.org Cc: Mel Gorman mel@csn.ul.ie Cc: Minchan Kim minchan.kim@gmail.com Cc: KAMEZAWA Hiroyuki kamezawa.hiroyu@jp.fujitsu.com Cc: KOSAKI Motohiro kosaki.motohiro@jp.fujitsu.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/node.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/base/node.c b/drivers/base/node.c index ec8bb24a5a22..0ac6376ef7a1 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -682,6 +682,7 @@ static int register_node(struct node *node, int num) */ void unregister_node(struct node *node) { + compaction_unregister_node(node); hugetlb_unregister_node(node); /* no-op, if memoryless node */ node_remove_accesses(node); node_remove_caches(node);
From: Muchun Song songmuchun@bytedance.com
[ Upstream commit e583b5c472bd23d450e06f148dc1f37be74f7666 ]
The flush_cache_page() only remove a PAGE_SIZE sized range from the cache. However, it does not cover the full pages in a THP except a head page. Replace it with flush_cache_range() to fix this issue. This is just a documentation issue with the respect to properly documenting the expected usage of cache flushing before modifying the pmd. However, in practice this is not a problem due to the fact that DAX is not available on architectures with virtually indexed caches per:
commit d92576f1167c ("dax: does not work correctly with virtual aliasing caches")
Link: https://lkml.kernel.org/r/20220403053957.10770-3-songmuchun@bytedance.com Fixes: f729c8c9b24f ("dax: wrprotect pmd_t in dax_mapping_entry_mkclean") Signed-off-by: Muchun Song songmuchun@bytedance.com Reviewed-by: Dan Williams dan.j.williams@intel.com Reviewed-by: Christoph Hellwig hch@lst.de Cc: Alistair Popple apopple@nvidia.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Hugh Dickins hughd@google.com Cc: Jan Kara jack@suse.cz Cc: "Kirill A. Shutemov" kirill.shutemov@linux.intel.com Cc: Matthew Wilcox willy@infradead.org Cc: Ralph Campbell rcampbell@nvidia.com Cc: Ross Zwisler zwisler@kernel.org Cc: Xiongchun Duan duanxiongchun@bytedance.com Cc: Xiyu Yang xiyuyang19@fudan.edu.cn Cc: Yang Shi shy828301@gmail.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/dax.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/dax.c b/fs/dax.c index 67a08a32fccb..a372304c9695 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -845,7 +845,8 @@ static void dax_entry_mkclean(struct address_space *mapping, pgoff_t index, if (!pmd_dirty(*pmdp) && !pmd_write(*pmdp)) goto unlock_pmd;
- flush_cache_page(vma, address, pfn); + flush_cache_range(vma, address, + address + HPAGE_PMD_SIZE); pmd = pmdp_invalidate(vma, address, pmdp); pmd = pmd_wrprotect(pmd); pmd = pmd_mkclean(pmd);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit f47f758cff59c68015d6b9b9c077110df7c2c828 ]
__add_memory_block() calls both put_device() and device_unregister() when storing the memory block into the xarray. This is incorrect because xarray doesn't take an additional reference and device_unregister() already calls put_device().
Triggering the issue looks really unlikely and its only effect should be to log a spurious warning about a ref counted issue.
Link: https://lkml.kernel.org/r/d44c63d78affe844f020dc02ad6af29abc448fc4.165061170... Fixes: 4fb6eabf1037 ("drivers/base/memory.c: cache memory blocks in xarray to accelerate lookup") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Michal Hocko mhocko@suse.com Reviewed-by: David Hildenbrand david@redhat.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: Scott Cheloha cheloha@linux.vnet.ibm.com Cc: Nathan Lynch nathanl@linux.ibm.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/memory.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 7222ff9b5e05..084d67fd55cc 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -636,10 +636,9 @@ static int __add_memory_block(struct memory_block *memory) } ret = xa_err(xa_store(&memory_blocks, memory->dev.id, memory, GFP_KERNEL)); - if (ret) { - put_device(&memory->dev); + if (ret) device_unregister(&memory->dev); - } + return ret; }
From: Sudeep Holla sudeep.holla@arm.com
[ Upstream commit f3c45c045e25ed52461829d2ce07954f72b6ad15 ]
While we pass uuid_null intentionally to ffa_partition_probe in ffa_setup_partitions to get the count of the partitions, it must not be uuid_null in ffa_partition_info_get which is used by the ffa_drivers to fetch the specific partition info passing the UUID of the partition.
Fix ffa_partition_info_get by passing the received uuid down to ffa_partition_probe so that the correct partition information is fetched.
Link: https://lore.kernel.org/r/20220429113946.2087145-1-sudeep.holla@arm.com Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions") Reported-by: Arunachalam Ganapathy arunachalam.ganapathy@arm.com Signed-off-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/arm_ffa/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 14f900047ac0..8fa1785afd42 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -582,7 +582,7 @@ static int ffa_partition_info_get(const char *uuid_str, return -ENODEV; }
- count = ffa_partition_probe(&uuid_null, &pbuf); + count = ffa_partition_probe(&uuid, &pbuf); if (count <= 0) return -ENOENT;
From: Sudeep Holla sudeep.holla@arm.com
[ Upstream commit 00512d2930b338fdd42bd90bbd1793fe212c2d31 ]
The ffa core driver currently assigns its own driver information to individual ffa device driver_data which is wrong. Firstly, it leaks this core driver information to individual ffa_device and hence to ffa_driver. Secondly the ffa_device driver_data is for use by individual ffa_driver and not for this core driver managing all those devices.
Link: https://lore.kernel.org/r/20220429113946.2087145-2-sudeep.holla@arm.com Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions") Signed-off-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/arm_ffa/driver.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 8fa1785afd42..44300dbcc643 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -688,8 +688,6 @@ static void ffa_setup_partitions(void) __func__, tpbuf->id); continue; } - - ffa_dev_set_drvdata(ffa_dev, drv_info); } kfree(pbuf); }
From: Heming Zhao via Ocfs2-devel ocfs2-devel@oss.oracle.com
[ Upstream commit bb20b31dee1a6c329c2f721fbe21c51945cdfc29 ]
Patch series "rewrite error handling during mounting stage".
This patch (of 5):
After commit da5e7c87827e8 ("ocfs2: cleanup journal init and shutdown"), journal init later than before, it makes NULL pointer access in free routine.
Crash flow:
ocfs2_fill_super + ocfs2_mount_volume | + ocfs2_dlm_init //fail & return, osb->journal is NULL. | + ... | + ocfs2_check_volume //no chance to init osb->journal | + ... + ocfs2_dismount_volume ocfs2_release_system_inodes ... evict ... ocfs2_clear_inode ocfs2_checkpoint_inode ocfs2_ci_fully_checkpointed time_after(journal->j_trans_id, ci->ci_last_trans) + journal is empty, crash!
For fixing, there are three solutions:
1> Partly revert commit da5e7c87827e8
For avoiding kernel crash, this make sense for us. We only concerned whether there has any non-system inode access before dlm init. The answer is NO. And all journal replay/recovery handling happen after dlm & journal init done. So this method is not graceful but workable.
2> Add osb->journal check in free inode routine (eg ocfs2_clear_inode)
The fix code is special for mounting phase, but it will continue working after mounting stage. In another word, this method adds useless code in normal inode free flow.
3> Do directly free inode in mounting phase
This method is brutal/complex and may introduce unsafe code, currently maintainer didn't like.
At last, we chose method <1> and did partly reverted job. We reverted journal init codes, and kept cleanup codes flow.
Link: https://lkml.kernel.org/r/20220424130952.2436-1-heming.zhao@suse.com Link: https://lkml.kernel.org/r/20220424130952.2436-2-heming.zhao@suse.com Fixes: da5e7c87827e8 ("ocfs2: cleanup journal init and shutdown") Signed-off-by: Heming Zhao heming.zhao@suse.com Reviewed-by: Joseph Qi joseph.qi@linux.alibaba.com Cc: Mark Fasheh mark@fasheh.com Cc: Joel Becker jlbec@evilplan.org Cc: Junxiao Bi junxiao.bi@oracle.com Cc: Changwei Ge gechangwei@live.cn Cc: Gang He ghe@suse.com Cc: Jun Piao piaojun@huawei.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ocfs2/inode.c | 4 ++-- fs/ocfs2/journal.c | 33 +++++++++++++++++++++++---------- fs/ocfs2/journal.h | 2 ++ fs/ocfs2/super.c | 15 +++++++++++++++ 4 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 5739dc301569..bb116c39b581 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -125,6 +125,7 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, struct inode *inode = NULL; struct super_block *sb = osb->sb; struct ocfs2_find_inode_args args; + journal_t *journal = osb->journal->j_journal;
trace_ocfs2_iget_begin((unsigned long long)blkno, flags, sysfile_type); @@ -171,11 +172,10 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, * part of the transaction - the inode could have been reclaimed and * now it is reread from disk. */ - if (osb->journal) { + if (journal) { transaction_t *transaction; tid_t tid; struct ocfs2_inode_info *oi = OCFS2_I(inode); - journal_t *journal = osb->journal->j_journal;
read_lock(&journal->j_state_lock); if (journal->j_running_transaction) diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 1887a2708709..fa87d89cf754 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -810,22 +810,20 @@ void ocfs2_set_journal_params(struct ocfs2_super *osb) write_unlock(&journal->j_state_lock); }
-int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty) +/* + * alloc & initialize skeleton for journal structure. + * ocfs2_journal_init() will make fs have journal ability. + */ +int ocfs2_journal_alloc(struct ocfs2_super *osb) { - int status = -1; - struct inode *inode = NULL; /* the journal inode */ - journal_t *j_journal = NULL; - struct ocfs2_journal *journal = NULL; - struct ocfs2_dinode *di = NULL; - struct buffer_head *bh = NULL; - int inode_lock = 0; + int status = 0; + struct ocfs2_journal *journal;
- /* initialize our journal structure */ journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL); if (!journal) { mlog(ML_ERROR, "unable to alloc journal\n"); status = -ENOMEM; - goto done; + goto bail; } osb->journal = journal; journal->j_osb = osb; @@ -839,6 +837,21 @@ int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty) INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); journal->j_state = OCFS2_JOURNAL_FREE;
+bail: + return status; +} + +int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty) +{ + int status = -1; + struct inode *inode = NULL; /* the journal inode */ + journal_t *j_journal = NULL; + struct ocfs2_journal *journal = osb->journal; + struct ocfs2_dinode *di = NULL; + struct buffer_head *bh = NULL; + int inode_lock = 0; + + BUG_ON(!journal); /* already have the inode for our journal */ inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE, osb->slot_num); diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 8dcb2f2cadbc..969d0aa28718 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h @@ -154,6 +154,7 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb); * Journal Control: * Initialize, Load, Shutdown, Wipe a journal. * + * ocfs2_journal_alloc - Initialize skeleton for journal structure. * ocfs2_journal_init - Initialize journal structures in the OSB. * ocfs2_journal_load - Load the given journal off disk. Replay it if * there's transactions still in there. @@ -167,6 +168,7 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb); * ocfs2_start_checkpoint - Kick the commit thread to do a checkpoint. */ void ocfs2_set_journal_params(struct ocfs2_super *osb); +int ocfs2_journal_alloc(struct ocfs2_super *osb); int ocfs2_journal_init(struct ocfs2_super *osb, int *dirty); void ocfs2_journal_shutdown(struct ocfs2_super *osb); int ocfs2_journal_wipe(struct ocfs2_journal *journal, diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 477cdf94122e..311433c69a3f 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -2195,6 +2195,15 @@ static int ocfs2_initialize_super(struct super_block *sb,
get_random_bytes(&osb->s_next_generation, sizeof(u32));
+ /* + * FIXME + * This should be done in ocfs2_journal_init(), but any inode + * writes back operation will cause the filesystem to crash. + */ + status = ocfs2_journal_alloc(osb); + if (status < 0) + goto bail; + INIT_WORK(&osb->dquot_drop_work, ocfs2_drop_dquot_refs); init_llist_head(&osb->dquot_drop_list);
@@ -2483,6 +2492,12 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb)
kfree(osb->osb_orphan_wipes); kfree(osb->slot_recovery_generations); + /* FIXME + * This belongs in journal shutdown, but because we have to + * allocate osb->journal at the middle of ocfs2_initialize_super(), + * we free it here. + */ + kfree(osb->journal); kfree(osb->local_alloc_copy); kfree(osb->uuid_str); kfree(osb->vol_label);
From: Kuniyuki Iwashima kuniyu@amazon.co.jp
[ Upstream commit d679ae94fdd5d3ab00c35078f5af5f37e068b03d ]
ep_poll() first calls ep_events_available() with no lock held and checks if ep->rdllist is empty by list_empty_careful(), which reads rdllist->prev. Thus all accesses to it need some protection to avoid store/load-tearing.
Note INIT_LIST_HEAD_RCU() already has the annotation for both prev and next.
Commit bf3b9f6372c4 ("epoll: Add busy poll support to epoll with socket fds.") added the first lockless ep_events_available(), and commit c5a282e9635e ("fs/epoll: reduce the scope of wq lock in epoll_wait()") made some ep_events_available() calls lockless and added single call under a lock, finally commit e59d3c64cba6 ("epoll: eliminate unnecessary lock for zero timeout") made the last ep_events_available() lockless.
BUG: KCSAN: data-race in do_epoll_wait / do_epoll_wait
write to 0xffff88810480c7d8 of 8 bytes by task 1802 on cpu 0: INIT_LIST_HEAD include/linux/list.h:38 [inline] list_splice_init include/linux/list.h:492 [inline] ep_start_scan fs/eventpoll.c:622 [inline] ep_send_events fs/eventpoll.c:1656 [inline] ep_poll fs/eventpoll.c:1806 [inline] do_epoll_wait+0x4eb/0xf40 fs/eventpoll.c:2234 do_epoll_pwait fs/eventpoll.c:2268 [inline] __do_sys_epoll_pwait fs/eventpoll.c:2281 [inline] __se_sys_epoll_pwait+0x12b/0x240 fs/eventpoll.c:2275 __x64_sys_epoll_pwait+0x74/0x80 fs/eventpoll.c:2275 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
read to 0xffff88810480c7d8 of 8 bytes by task 1799 on cpu 1: list_empty_careful include/linux/list.h:329 [inline] ep_events_available fs/eventpoll.c:381 [inline] ep_poll fs/eventpoll.c:1797 [inline] do_epoll_wait+0x279/0xf40 fs/eventpoll.c:2234 do_epoll_pwait fs/eventpoll.c:2268 [inline] __do_sys_epoll_pwait fs/eventpoll.c:2281 [inline] __se_sys_epoll_pwait+0x12b/0x240 fs/eventpoll.c:2275 __x64_sys_epoll_pwait+0x74/0x80 fs/eventpoll.c:2275 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xd0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
value changed: 0xffff88810480c7d0 -> 0xffff888103c15098
Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 1799 Comm: syz-fuzzer Tainted: G W 5.17.0-rc7-syzkaller-dirty #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Link: https://lkml.kernel.org/r/20220322002653.33865-3-kuniyu@amazon.co.jp Fixes: e59d3c64cba6 ("epoll: eliminate unnecessary lock for zero timeout") Fixes: c5a282e9635e ("fs/epoll: reduce the scope of wq lock in epoll_wait()") Fixes: bf3b9f6372c4 ("epoll: Add busy poll support to epoll with socket fds.") Signed-off-by: Kuniyuki Iwashima kuniyu@amazon.co.jp Reported-by: syzbot+bdd6e38a1ed5ee58d8bd@syzkaller.appspotmail.com Cc: Al Viro viro@zeniv.linux.org.uk, Andrew Morton akpm@linux-foundation.org Cc: Kuniyuki Iwashima kuniyu@amazon.co.jp Cc: Kuniyuki Iwashima kuni1840@gmail.com Cc: "Soheil Hassas Yeganeh" soheil@google.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: "Sridhar Samudrala" sridhar.samudrala@intel.com Cc: Alexander Duyck alexander.h.duyck@intel.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/list.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/linux/list.h b/include/linux/list.h index 0f7d8ec5b4ed..0df13cb03028 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -35,7 +35,7 @@ static inline void INIT_LIST_HEAD(struct list_head *list) { WRITE_ONCE(list->next, list); - list->prev = list; + WRITE_ONCE(list->prev, list); }
#ifdef CONFIG_DEBUG_LIST @@ -306,7 +306,7 @@ static inline int list_empty(const struct list_head *head) static inline void list_del_init_careful(struct list_head *entry) { __list_del_entry(entry); - entry->prev = entry; + WRITE_ONCE(entry->prev, entry); smp_store_release(&entry->next, entry); }
@@ -326,7 +326,7 @@ static inline void list_del_init_careful(struct list_head *entry) static inline int list_empty_careful(const struct list_head *head) { struct list_head *next = smp_load_acquire(&head->next); - return list_is_head(next, head) && (next == head->prev); + return list_is_head(next, head) && (next == READ_ONCE(head->prev)); }
/**
From: Lv Ruyi lv.ruyi@zte.com.cn
[ Upstream commit 95093595914c17f32e1d6228b4db06fab8cebd35 ]
The irq_of_parse_and_map() function returns 0 on failure, and does not return a negative value anyhow, so never enter this conditional branch.
Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Lv Ruyi lv.ruyi@zte.com.cn Reviewed-by: Stephen Boyd swboyd@chromium.org Patchwork: https://patchwork.freedesktop.org/patch/483291/ Link: https://lore.kernel.org/r/20220425090947.3498897-1-lv.ruyi@zte.com.cn Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index c8089678f733..c95bacd4f458 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1244,7 +1244,7 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
priv->kms = &dpu_kms->base;
- return ret; + return 0; }
static void dpu_unbind(struct device *dev, struct device *master, void *data)
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 22f8e625ebabd7ed3185b82b44b4f12fc0402113 ]
Fix missing export for a loadable module build:
ERROR: modpost: "cpm_setbrg" [drivers/tty/serial/cpm_uart/cpm_uart.ko] undefined!
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com [chleroy: Changed Fixes: tag] Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210122010819.30986-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/8xx/cpm1.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/platforms/8xx/cpm1.c b/arch/powerpc/platforms/8xx/cpm1.c index c58b6f1c40e3..3ef5e9fd3a9b 100644 --- a/arch/powerpc/platforms/8xx/cpm1.c +++ b/arch/powerpc/platforms/8xx/cpm1.c @@ -280,6 +280,7 @@ cpm_setbrg(uint brg, uint rate) out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); } +EXPORT_SYMBOL(cpm_setbrg);
struct cpm_ioport16 { __be16 dir, par, odr_sor, dat, intr;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 4288caed9a6319b766dc0adf605c7b401180db34 ]
Unlike on R-Car Gen3 SoCs, setting a bit to zero in a GPIO / Peripheral Function Select Register (GPSRn) on R-Car V3U is not always sufficient to configure a pin for GPIO. For I2C-capable pins, the I2C function must also be explicitly disabled in the corresponding Module Select Register (MODSELn).
Add the missing FN_SEL_I2Ci_0 function enums to the pinmux_data[] array by temporarily overriding the GP_2_j_FN function enum to expand to two enums: the original GP_2_j_FN enum to configure the GSPR register bits, and the missing FN_SEL_I2Ci_0 enum to configure the MODSEL register bits.
Fixes: 741a7370fc3b8b54 ("pinctrl: renesas: Initial R8A779A0 (V3U) PFC support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/4611e29e7b105513883084c1d6dc39c3ac8b525c.165061047... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/pfc-r8a779a0.c | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/pinctrl/renesas/pfc-r8a779a0.c b/drivers/pinctrl/renesas/pfc-r8a779a0.c index 4a668a04b7ca..0c26e95ba7db 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779a0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779a0.c @@ -629,7 +629,36 @@ enum { };
static const u16 pinmux_data[] = { +/* Using GP_2_[2-15] requires disabling I2C in MOD_SEL2 */ +#define GP_2_2_FN GP_2_2_FN, FN_SEL_I2C0_0 +#define GP_2_3_FN GP_2_3_FN, FN_SEL_I2C0_0 +#define GP_2_4_FN GP_2_4_FN, FN_SEL_I2C1_0 +#define GP_2_5_FN GP_2_5_FN, FN_SEL_I2C1_0 +#define GP_2_6_FN GP_2_6_FN, FN_SEL_I2C2_0 +#define GP_2_7_FN GP_2_7_FN, FN_SEL_I2C2_0 +#define GP_2_8_FN GP_2_8_FN, FN_SEL_I2C3_0 +#define GP_2_9_FN GP_2_9_FN, FN_SEL_I2C3_0 +#define GP_2_10_FN GP_2_10_FN, FN_SEL_I2C4_0 +#define GP_2_11_FN GP_2_11_FN, FN_SEL_I2C4_0 +#define GP_2_12_FN GP_2_12_FN, FN_SEL_I2C5_0 +#define GP_2_13_FN GP_2_13_FN, FN_SEL_I2C5_0 +#define GP_2_14_FN GP_2_14_FN, FN_SEL_I2C6_0 +#define GP_2_15_FN GP_2_15_FN, FN_SEL_I2C6_0 PINMUX_DATA_GP_ALL(), +#undef GP_2_2_FN +#undef GP_2_3_FN +#undef GP_2_4_FN +#undef GP_2_5_FN +#undef GP_2_6_FN +#undef GP_2_7_FN +#undef GP_2_8_FN +#undef GP_2_9_FN +#undef GP_2_10_FN +#undef GP_2_11_FN +#undef GP_2_12_FN +#undef GP_2_13_FN +#undef GP_2_14_FN +#undef GP_2_15_FN
PINMUX_SINGLE(MMC_D7), PINMUX_SINGLE(MMC_D6),
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 8bdd369dba7ff2f89cfd723ca3a26602aae4e498 ]
Unlike on R-Car Gen3 SoCs, setting a bit to zero in a GPIO / Peripheral Function Select Register (GPSRn) on R-Car S4-8 is not always sufficient to configure a pin for GPIO. For I2C-capable pins, the I2C function must also be explicitly disabled in the corresponding Module Select Register (MODSELn).
Add the missing FN_SEL_I2Ci_0 function enums to the pinmux_data[] array by temporarily overriding the GP_1_j_FN function enum to expand to two enums: the original GP_1_j_FN enum to configure the GPSR register bits, and the missing FN_SEL_I2Ci_0 enum to configure the MODSEL register bits.
Fixes: 030ac6d7eeff81e3 ("pinctrl: renesas: Initial R8A779F0 PFC support") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/c12c60ec1058140a37f03650043ab73f730f104f.165061047... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/pfc-r8a779f0.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/drivers/pinctrl/renesas/pfc-r8a779f0.c b/drivers/pinctrl/renesas/pfc-r8a779f0.c index 91860608242c..3b4ca9622bbe 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779f0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779f0.c @@ -257,7 +257,28 @@ enum { };
static const u16 pinmux_data[] = { +/* Using GP_1_[0-9] requires disabling I2C in MOD_SEL1 */ +#define GP_1_0_FN GP_1_0_FN, FN_SEL_I2C0_0 +#define GP_1_1_FN GP_1_1_FN, FN_SEL_I2C0_0 +#define GP_1_2_FN GP_1_2_FN, FN_SEL_I2C1_0 +#define GP_1_3_FN GP_1_3_FN, FN_SEL_I2C1_0 +#define GP_1_4_FN GP_1_4_FN, FN_SEL_I2C2_0 +#define GP_1_5_FN GP_1_5_FN, FN_SEL_I2C2_0 +#define GP_1_6_FN GP_1_6_FN, FN_SEL_I2C3_0 +#define GP_1_7_FN GP_1_7_FN, FN_SEL_I2C3_0 +#define GP_1_8_FN GP_1_8_FN, FN_SEL_I2C4_0 +#define GP_1_9_FN GP_1_9_FN, FN_SEL_I2C4_0 PINMUX_DATA_GP_ALL(), +#undef GP_1_0_FN +#undef GP_1_1_FN +#undef GP_1_2_FN +#undef GP_1_3_FN +#undef GP_1_4_FN +#undef GP_1_5_FN +#undef GP_1_6_FN +#undef GP_1_7_FN +#undef GP_1_8_FN +#undef GP_1_9_FN
PINMUX_SINGLE(SD_WP), PINMUX_SINGLE(SD_CD),
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 5376e3d904532e657fd7ca1a9b1ff3d351527b90 ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref. And use devm_platform_get_and_ioremap_resource() to simplify code.
Fixes: c7977ec4a336 ("pinctrl: sh-pfc: Convert to platform_get_*()") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20220429082637.1308182-1-yangyingliang@huawei.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/core.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index d0d4714731c1..3d8bf521c3e7 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -71,12 +71,11 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc,
/* Fill them. */ for (i = 0; i < num_windows; i++) { - res = platform_get_resource(pdev, IORESOURCE_MEM, i); - windows->phys = res->start; - windows->size = resource_size(res); - windows->virt = devm_ioremap_resource(pfc->dev, res); + windows->virt = devm_platform_get_and_ioremap_resource(pdev, i, &res); if (IS_ERR(windows->virt)) return -ENOMEM; + windows->phys = res->start; + windows->size = resource_size(res); windows++; } for (i = 0; i < num_irqs; i++)
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit b793a01000122d2bd133ba451a76cc135b5e162c ]
__setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled.
A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument or environment strings.
Also, error return codes don't mean anything to obsolete_checksetup() -- only non-zero (usually 1) or zero. So return 1 from powersave_off().
Fixes: 302eca184fb8 ("[POWERPC] cell: use ppc_md->power_save instead of cbe_idle_loop") Reported-by: Igor Zhbanov izh1979@gmail.com Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220502192925.19954-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 4ad79eb638c6..77cd4c5a2d63 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -37,7 +37,7 @@ static int __init powersave_off(char *arg) { ppc_md.power_save = NULL; cpuidle_disable = IDLE_POWERSAVE_OFF; - return 0; + return 1; } __setup("powersave=off", powersave_off);
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 5bb99fd4090fe1acfdb90a97993fcda7f8f5a3d6 ]
__setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled.
A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) argument or environment strings.
Also, error return codes don't mean anything to obsolete_checksetup() -- only non-zero (usually 1) or zero. So return 1 from cpm_powersave_off().
Fixes: d164f6d4f910 ("powerpc/4xx: Add suspend and idle support") Reported-by: Igor Zhbanov izh1979@gmail.com Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220502192941.20955-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/4xx/cpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/4xx/cpm.c b/arch/powerpc/platforms/4xx/cpm.c index 2571841625a2..1d3bc35ee1a7 100644 --- a/arch/powerpc/platforms/4xx/cpm.c +++ b/arch/powerpc/platforms/4xx/cpm.c @@ -327,6 +327,6 @@ late_initcall(cpm_init); static int __init cpm_powersave_off(char *arg) { cpm.powersave_off = 1; - return 0; + return 1; } __setup("powersave=off", cpm_powersave_off);
From: Yangyang Li liyangyang20@huawei.com
[ Upstream commit e8ea058edc2b225a68b307057a65599625daaebf ]
CMDQ may fail during HNS ROCEE initialization. The following is the log when the execution fails:
hns3 0000:bd:00.2: In reset process RoCE client reinit. hns3 0000:bd:00.2: CMDQ move tail from 840 to 839 hns3 0000:bd:00.2 hns_2: failed to set gid, ret = -11! hns3 0000:bd:00.2: CMDQ move tail from 840 to 839 <...> hns3 0000:bd:00.2: CMDQ move tail from 840 to 839 hns3 0000:bd:00.2: CMDQ move tail from 840 to 0 hns3 0000:bd:00.2: [cmd]token 14e mailbox 20 timeout. hns3 0000:bd:00.2 hns_2: set HEM step 0 failed! hns3 0000:bd:00.2 hns_2: set HEM address to HW failed! hns3 0000:bd:00.2 hns_2: failed to alloc mtpt, ret = -16. infiniband hns_2: Couldn't create ib_mad PD infiniband hns_2: Couldn't open port 1 hns3 0000:bd:00.2: Reset done, RoCE client reinit finished.
However, even if ib_mad client registration failed, ib_register_device() still returns success to the driver.
In the device initialization process, CMDQ execution fails because HW/FW is abnormal. Therefore, if CMDQ fails, the initialization function should set CMDQ to a fatal error state and return a failure to the caller.
Fixes: 9a4435375cd1 ("IB/hns: Add driver files for hns RoCE driver") Link: https://lore.kernel.org/r/20220429093104.26687-1-liangwenpeng@huawei.com Signed-off-by: Yangyang Li liyangyang20@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_device.h | 6 ++++++ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+)
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h index 3083d6db1d68..8604d16db8c4 100644 --- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -535,6 +535,11 @@ struct hns_roce_cmd_context { u16 busy; };
+enum hns_roce_cmdq_state { + HNS_ROCE_CMDQ_STATE_NORMAL, + HNS_ROCE_CMDQ_STATE_FATAL_ERR, +}; + struct hns_roce_cmdq { struct dma_pool *pool; struct semaphore poll_sem; @@ -554,6 +559,7 @@ struct hns_roce_cmdq { * close device, switch into poll mode(non event mode) */ u8 use_events; + enum hns_roce_cmdq_state state; };
struct hns_roce_cmd_mailbox { diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 2b0cef17ad45..1946ad8410cc 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1265,6 +1265,16 @@ static int hns_roce_cmq_csq_done(struct hns_roce_dev *hr_dev) return tail == priv->cmq.csq.head; }
+static void update_cmdq_status(struct hns_roce_dev *hr_dev) +{ + struct hns_roce_v2_priv *priv = hr_dev->priv; + struct hnae3_handle *handle = priv->handle; + + if (handle->rinfo.reset_state == HNS_ROCE_STATE_RST_INIT || + handle->rinfo.instance_state == HNS_ROCE_STATE_INIT) + hr_dev->cmd.state = HNS_ROCE_CMDQ_STATE_FATAL_ERR; +} + static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, struct hns_roce_cmq_desc *desc, int num) { @@ -1318,6 +1328,8 @@ static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev, csq->head, tail); csq->head = tail;
+ update_cmdq_status(hr_dev); + ret = -EAGAIN; }
@@ -1332,6 +1344,9 @@ static int hns_roce_cmq_send(struct hns_roce_dev *hr_dev, bool busy; int ret;
+ if (hr_dev->cmd.state == HNS_ROCE_CMDQ_STATE_FATAL_ERR) + return -EIO; + if (!v2_chk_mbox_is_avail(hr_dev, &busy)) return busy ? -EBUSY : 0;
@@ -1528,6 +1543,9 @@ static void hns_roce_function_clear(struct hns_roce_dev *hr_dev) { int i;
+ if (hr_dev->cmd.state == HNS_ROCE_CMDQ_STATE_FATAL_ERR) + return; + for (i = hr_dev->func_num - 1; i >= 0; i--) { __hns_roce_function_clear(hr_dev, i); if (i != 0) @@ -3000,6 +3018,9 @@ static int v2_wait_mbox_complete(struct hns_roce_dev *hr_dev, u32 timeout, mb_st = (struct hns_roce_mbox_status *)desc.data; end = msecs_to_jiffies(timeout) + jiffies; while (v2_chk_mbox_is_avail(hr_dev, &busy)) { + if (hr_dev->cmd.state == HNS_ROCE_CMDQ_STATE_FATAL_ERR) + return -EIO; + status = 0; hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_QUERY_MB_ST, true);
From: Robert Marko robert.marko@sartura.hr
[ Upstream commit 5202f4c3816b42e989f9cad49a73c7e88fba89f4 ]
SPI config for the SPI-NOR is incorrect and completely breaking reading/writing to the onboard SPI-NOR.
SPI-NOR is connected in the single(x1) IO mode and not in the quad (x4) mode. Also, there is no need to override the max frequency from the DTSI as the mx25u3235f that is used supports 104Mhz.
Fixes: 3404fe15a60f ("arm64: dts: marvell: add DT for ESPRESSObin-Ultra") Signed-off-by: Robert Marko robert.marko@sartura.hr Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts index c5eb3604dd5b..610ff6f385c7 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts @@ -71,10 +71,6 @@
&spi0 { flash@0 { - spi-max-frequency = <108000000>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - partitions { compatible = "fixed-partitions"; #address-cells = <1>;
From: Robert Marko robert.marko@sartura.hr
[ Upstream commit eacec7ebc16cf5d2f6a6c7cf5d57156da2c3e98f ]
Espressobin Ultra has a front panel USB3.0 Type-A port which works just fine so enable it. I dont see a reason why it was disabled in the first place anyway.
Fixes: 3404fe15a60f ("arm64: dts: marvell: add DT for ESPRESSObin-Ultra") Signed-off-by: Robert Marko robert.marko@sartura.hr Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts index 610ff6f385c7..119db6b541b7 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin-ultra.dts @@ -108,7 +108,6 @@
&usb3 { usb-phy = <&usb3_phy>; - status = "disabled"; };
&mdio {
From: Charles Keepax ckeepax@opensource.cirrus.com
[ Upstream commit 52857c3baa0e5ddeba7b2c84e56bb71c9674e048 ]
The endianness flag should have been removed when the driver was ported across from having both a CODEC and CPU side component, to just having a CPU component and using the dummy for the CODEC. The endianness flag is used to indicate that the device is completely ambivalent to the endianness of the data, typically due to the endianness being lost over the hardware link (ie. the link defines bit ordering). It's usage didn't have any effect when the driver had both a CPU and CODEC component, since the union of those equals the CPU side settings, but now causes the driver to falsely report it supports big endian. Correct this by removing the flag.
Fixes: f3c668074a04 ("ASoC: atmel-pdmic: remove codec component") Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Link: https://lore.kernel.org/r/20220504170905.332415-3-ckeepax@opensource.cirrus.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/atmel/atmel-pdmic.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/atmel/atmel-pdmic.c b/sound/soc/atmel/atmel-pdmic.c index 42117de299e7..ea34efac2fff 100644 --- a/sound/soc/atmel/atmel-pdmic.c +++ b/sound/soc/atmel/atmel-pdmic.c @@ -481,7 +481,6 @@ static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = { .num_controls = ARRAY_SIZE(atmel_pdmic_snd_controls), .idle_bias_on = 1, .use_pmdown_time = 1, - .endianness = 1, };
/* ASoC sound card */
From: Charles Keepax ckeepax@opensource.cirrus.com
[ Upstream commit 0104d52a6a69b06b0e8167f7c1247e8c76aca070 ]
The endianness flag should have been removed when the driver was ported across from having both a CODEC and CPU side component, to just having a CPU component and using the dummy for the CODEC. The endianness flag is used to indicate that the device is completely ambivalent to the endianness of the data, typically due to the endianness being lost over the hardware link (ie. the link defines bit ordering). It's usage didn't have any effect when the driver had both a CPU and CODEC component, since the union of those equals the CPU side settings, but now causes the driver to falsely report it supports big endian. Correct this by removing the flag.
Fixes: 1dfdbe73ccf9 ("ASoC: atmel-classd: remove codec component") Signed-off-by: Charles Keepax ckeepax@opensource.cirrus.com Link: https://lore.kernel.org/r/20220504170905.332415-4-ckeepax@opensource.cirrus.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/atmel/atmel-classd.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index a9f9f449c48c..74b7b2611aa7 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c @@ -458,7 +458,6 @@ static const struct snd_soc_component_driver atmel_classd_cpu_dai_component = { .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), .idle_bias_on = 1, .use_pmdown_time = 1, - .endianness = 1, };
/* ASoC sound card */
From: Alexey Dobriyan adobriyan@gmail.com
[ Upstream commit 7055197705709c59b8ab77e6a5c7d46d61edd96e ]
When a process exits, /proc/${pid}, and /proc/${pid}/net dentries are flushed. However some leaf dentries like /proc/${pid}/net/arp_cache aren't. That's because respective PDEs have proc_misc_d_revalidate() hook which returns 1 and leaves dentries/inodes in the LRU.
Force revalidation/lookup on everything under /proc/${pid}/net by inheriting proc_net_dentry_ops.
[akpm@linux-foundation.org: coding-style cleanups] Link: https://lkml.kernel.org/r/YjdVHgildbWO7diJ@localhost.localdomain Fixes: c6c75deda813 ("proc: fix lookup in /proc/net subdirectories after setns(2)") Signed-off-by: Alexey Dobriyan adobriyan@gmail.com Reported-by: hui li juanfengpy@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/generic.c | 3 +++ fs/proc/proc_net.c | 3 +++ 2 files changed, 6 insertions(+)
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index f2132407e133..587b91d9d998 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -448,6 +448,9 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, proc_set_user(ent, (*parent)->uid, (*parent)->gid);
ent->proc_dops = &proc_misc_dentry_ops; + /* Revalidate everything under /proc/${pid}/net */ + if ((*parent)->proc_dops == &proc_net_dentry_ops) + pde_force_lookup(ent);
out: return ent; diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index e1cfeda397f3..913e5acefbb6 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -376,6 +376,9 @@ static __net_init int proc_net_ns_init(struct net *net)
proc_set_user(netd, uid, gid);
+ /* Seed dentry revalidation for /proc/${pid}/net */ + pde_force_lookup(netd); + err = -EEXIST; net_statd = proc_net_mkdir(net, "stat", netd); if (!net_statd)
From: Waiman Long longman@redhat.com
[ Upstream commit d60c4d01a98bc1942dba6e3adc02031f5519f94b ]
When running the stress-ng clone benchmark with multiple testing threads, it was found that there were significant spinlock contention in sget_fc(). The contended spinlock was the sb_lock. It is under heavy contention because the following code in the critcal section of sget_fc():
hlist_for_each_entry(old, &fc->fs_type->fs_supers, s_instances) { if (test(old, fc)) goto share_extant_sb; }
After testing with added instrumentation code, it was found that the benchmark could generate thousands of ipc namespaces with the corresponding number of entries in the mqueue's fs_supers list where the namespaces are the key for the search. This leads to excessive time in scanning the list for a match.
Looking back at the mqueue calling sequence leading to sget_fc():
mq_init_ns() => mq_create_mount() => fc_mount() => vfs_get_tree() => mqueue_get_tree() => get_tree_keyed() => vfs_get_super() => sget_fc()
Currently, mq_init_ns() is the only mqueue function that will indirectly call mqueue_get_tree() with a newly allocated ipc namespace as the key for searching. As a result, there will never be a match with the exising ipc namespaces stored in the mqueue's fs_supers list.
So using get_tree_keyed() to do an existing ipc namespace search is just a waste of time. Instead, we could use get_tree_nodev() to eliminate the useless search. By doing so, we can greatly reduce the sb_lock hold time and avoid the spinlock contention problem in case a large number of ipc namespaces are present.
Of course, if the code is modified in the future to allow mqueue_get_tree() to be called with an existing ipc namespace instead of a new one, we will have to use get_tree_keyed() in this case.
The following stress-ng clone benchmark command was run on a 2-socket 48-core Intel system:
./stress-ng --clone 32 --verbose --oomable --metrics-brief -t 20
The "bogo ops/s" increased from 5948.45 before patch to 9137.06 after patch. This is an increase of 54% in performance.
Link: https://lkml.kernel.org/r/20220121172315.19652-1-longman@redhat.com Fixes: 935c6912b198 ("ipc: Convert mqueue fs to fs_context") Signed-off-by: Waiman Long longman@redhat.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: David Howells dhowells@redhat.com Cc: Manfred Spraul manfred@colorfullife.com Cc: Davidlohr Bueso dave@stgolabs.net Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- ipc/mqueue.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 7c08eb3c258d..54cb6264f8cf 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -45,6 +45,7 @@
struct mqueue_fs_context { struct ipc_namespace *ipc_ns; + bool newns; /* Set if newly created ipc namespace */ };
#define MQUEUE_MAGIC 0x19800202 @@ -427,6 +428,14 @@ static int mqueue_get_tree(struct fs_context *fc) { struct mqueue_fs_context *ctx = fc->fs_private;
+ /* + * With a newly created ipc namespace, we don't need to do a search + * for an ipc namespace match, but we still need to set s_fs_info. + */ + if (ctx->newns) { + fc->s_fs_info = ctx->ipc_ns; + return get_tree_nodev(fc, mqueue_fill_super); + } return get_tree_keyed(fc, mqueue_fill_super, ctx->ipc_ns); }
@@ -454,6 +463,10 @@ static int mqueue_init_fs_context(struct fs_context *fc) return 0; }
+/* + * mq_init_ns() is currently the only caller of mq_create_mount(). + * So the ns parameter is always a newly created ipc namespace. + */ static struct vfsmount *mq_create_mount(struct ipc_namespace *ns) { struct mqueue_fs_context *ctx; @@ -465,6 +478,7 @@ static struct vfsmount *mq_create_mount(struct ipc_namespace *ns) return ERR_CAST(fc);
ctx = fc->fs_private; + ctx->newns = true; put_ipc_ns(ctx->ipc_ns); ctx->ipc_ns = get_ipc_ns(ns); put_user_ns(fc->user_ns);
From: Francesco Dolcini francesco.dolcini@toradex.com
[ Upstream commit a6809941c1f17f455db2cf4ca19c6d8c8746ec25 ]
According to the PCIe standard the PERST# signal (reset-gpio in fsl,imx* compatible dts) should be kept asserted for at least 100 usec before the PCIe refclock is stable, should be kept asserted for at least 100 msec after the power rails are stable and the host should wait at least 100 msec after it is de-asserted before accessing the configuration space of any attached device.
From PCIe CEM r2.0, sec 2.6.2
T-PVPERL: Power stable to PERST# inactive - 100 msec T-PERST-CLK: REFCLK stable before PERST# inactive - 100 usec.
From PCIe r5.0, sec 6.6.1
With a Downstream Port that does not support Link speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms before sending a Configuration Request to the device immediately below that Port.
Failure to do so could prevent PCIe devices to be working correctly, and this was experienced with real devices.
Move reset assert to imx6_pcie_assert_core_reset(), this way we ensure that PERST# is asserted before enabling any clock, move de-assert to the end of imx6_pcie_deassert_core_reset() after the clock is enabled and deemed stable and add a new delay of 100 msec just afterward.
Link: https://lore.kernel.org/all/20220211152550.286821-1-francesco.dolcini@torade... Link: https://lore.kernel.org/r/20220404081509.94356-1-francesco.dolcini@toradex.c... Fixes: bb38919ec56e ("PCI: imx6: Add support for i.MX6 PCIe controller") Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Lucas Stach l.stach@pengutronix.de Acked-by: Richard Zhu hongxing.zhu@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-imx6.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index 6619e3caffe2..7a285fb0f619 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -408,6 +408,11 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie) dev_err(dev, "failed to disable vpcie regulator: %d\n", ret); } + + /* Some boards don't have PCIe reset GPIO. */ + if (gpio_is_valid(imx6_pcie->reset_gpio)) + gpio_set_value_cansleep(imx6_pcie->reset_gpio, + imx6_pcie->gpio_active_high); }
static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) @@ -540,15 +545,6 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) /* allow the clocks to stabilize */ usleep_range(200, 500);
- /* Some boards don't have PCIe reset GPIO. */ - if (gpio_is_valid(imx6_pcie->reset_gpio)) { - gpio_set_value_cansleep(imx6_pcie->reset_gpio, - imx6_pcie->gpio_active_high); - msleep(100); - gpio_set_value_cansleep(imx6_pcie->reset_gpio, - !imx6_pcie->gpio_active_high); - } - switch (imx6_pcie->drvdata->variant) { case IMX8MQ: reset_control_deassert(imx6_pcie->pciephy_reset); @@ -595,6 +591,15 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) break; }
+ /* Some boards don't have PCIe reset GPIO. */ + if (gpio_is_valid(imx6_pcie->reset_gpio)) { + msleep(100); + gpio_set_value_cansleep(imx6_pcie->reset_gpio, + !imx6_pcie->gpio_active_high); + /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ + msleep(100); + } + return;
err_ref_clk:
From: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com
[ Upstream commit 1d565935e3b9ccc682631e0bc6e415a7f48295d9 ]
The controller may have been left out of reset by the bootloader, in which case, before the powerup sequence, the controller will be found preconfigured with values that were set before booting the kernel: this produces a controller failure, with the result of a failure during the mtk_pcie_startup_port() sequence as the PCIe link never gets up.
To ensure that we get a clean start in an expected state, assert both the PHY and MAC resets before executing the controller power-up sequence.
Link: https://lore.kernel.org/r/20220404144858.92390-1-angelogioacchino.delregno@c... Fixes: d3bf75b579b9 ("PCI: mediatek-gen3: Add MediaTek Gen3 driver for MT8192") Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-mediatek-gen3.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 3e8d70bfabc6..5d9fd36b02d1 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -838,6 +838,14 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie) if (err) return err;
+ /* + * The controller may have been left out of reset by the bootloader + * so make sure that we get a clean start by asserting resets here. + */ + reset_control_assert(pcie->phy_reset); + reset_control_assert(pcie->mac_reset); + usleep_range(10, 20); + /* Don't touch the hardware registers before power up */ err = mtk_pcie_power_up(pcie); if (err)
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
[ Upstream commit 80140a81f7f833998d732102eea0fea230b88067 ]
In commit ca321ec74322 ("module.h: allow #define strings to work with MODULE_IMPORT_NS") I fixed up the MODULE_IMPORT_NS() macro to allow defined strings to work with it. Unfortunatly I did it in a two-stage process, when it could just be done with the __stringify() macro as pointed out by Masahiro Yamada.
Clean this up to only be one macro instead of two steps to achieve the same end result.
Fixes: ca321ec74322 ("module.h: allow #define strings to work with MODULE_IMPORT_NS") Reported-by: Masahiro Yamada masahiroy@kernel.org Cc: Luis Chamberlain mcgrof@kernel.org Cc: Jessica Yu jeyu@kernel.org Cc: Matthias Maennich maennich@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Luis Chamberlain mcgrof@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/module.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/linux/module.h b/include/linux/module.h index 1e135fd5c076..d5e9066990ca 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -290,8 +290,7 @@ extern typeof(name) __mod_##type##__##name##_device_table \ * files require multiple MODULE_FIRMWARE() specifiers */ #define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
-#define _MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns) -#define MODULE_IMPORT_NS(ns) _MODULE_IMPORT_NS(ns) +#define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, __stringify(ns))
struct notifier_block;
From: Alexey Dobriyan adobriyan@gmail.com
[ Upstream commit 391e982bfa632b8315235d8be9c0a81374c6a19c ]
It is trivial to craft a module to trigger OOB access in this line:
if (info->secstrings[strhdr->sh_size - 1] != '\0') {
BUG: unable to handle page fault for address: ffffc90000aa0fff PGD 100000067 P4D 100000067 PUD 100066067 PMD 10436f067 PTE 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 7 PID: 1215 Comm: insmod Not tainted 5.18.0-rc5-00007-g9bf578647087-dirty #10 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/01/2014 RIP: 0010:load_module+0x19b/0x2391
Fixes: ec2a29593c83 ("module: harden ELF info handling") Signed-off-by: Alexey Dobriyan adobriyan@gmail.com [rebased patch onto modules-next] Signed-off-by: Luis Chamberlain mcgrof@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/module.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/kernel/module.c b/kernel/module.c index 6cea788fd965..6529c84c536f 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3033,6 +3033,10 @@ static int elf_validity_check(struct load_info *info) * strings in the section safe. */ info->secstrings = (void *)info->hdr + strhdr->sh_offset; + if (strhdr->sh_size == 0) { + pr_err("empty section name table\n"); + goto no_exec; + } if (info->secstrings[strhdr->sh_size - 1] != '\0') { pr_err("ELF Spec violation: section name table isn't null terminated\n"); goto no_exec;
From: Qi Zheng zhengqi.arch@bytedance.com
[ Upstream commit 6b9dbedbe3499fef862c4dff5217cf91f34e43b3 ]
pty_write() invokes kmalloc() which may invoke a normal printk() to print failure message. This can cause a deadlock in the scenario reported by syz-bot below:
CPU0 CPU1 CPU2 ---- ---- ---- lock(console_owner); lock(&port_lock_key); lock(&port->lock); lock(&port_lock_key); lock(&port->lock); lock(console_owner);
As commit dbdda842fe96 ("printk: Add console owner and waiter logic to load balance console writes") said, such deadlock can be prevented by using printk_deferred() in kmalloc() (which is invoked in the section guarded by the port->lock). But there are too many printk() on the kmalloc() path, and kmalloc() can be called from anywhere, so changing printk() to printk_deferred() is too complicated and inelegant.
Therefore, this patch chooses to specify __GFP_NOWARN to kmalloc(), so that printk() will not be called, and this deadlock problem can be avoided.
Syzbot reported the following lockdep error:
====================================================== WARNING: possible circular locking dependency detected 5.4.143-00237-g08ccc19a-dirty #10 Not tainted ------------------------------------------------------ syz-executor.4/29420 is trying to acquire lock: ffffffff8aedb2a0 (console_owner){....}-{0:0}, at: console_trylock_spinning kernel/printk/printk.c:1752 [inline] ffffffff8aedb2a0 (console_owner){....}-{0:0}, at: vprintk_emit+0x2ca/0x470 kernel/printk/printk.c:2023
but task is already holding lock: ffff8880119c9158 (&port->lock){-.-.}-{2:2}, at: pty_write+0xf4/0x1f0 drivers/tty/pty.c:120
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&port->lock){-.-.}-{2:2}: __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159 tty_port_tty_get drivers/tty/tty_port.c:288 [inline] <-- lock(&port->lock); tty_port_default_wakeup+0x1d/0xb0 drivers/tty/tty_port.c:47 serial8250_tx_chars+0x530/0xa80 drivers/tty/serial/8250/8250_port.c:1767 serial8250_handle_irq.part.0+0x31f/0x3d0 drivers/tty/serial/8250/8250_port.c:1854 serial8250_handle_irq drivers/tty/serial/8250/8250_port.c:1827 [inline] <-- lock(&port_lock_key); serial8250_default_handle_irq+0xb2/0x220 drivers/tty/serial/8250/8250_port.c:1870 serial8250_interrupt+0xfd/0x200 drivers/tty/serial/8250/8250_core.c:126 __handle_irq_event_percpu+0x109/0xa50 kernel/irq/handle.c:156 [...]
-> #1 (&port_lock_key){-.-.}-{2:2}: __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0x35/0x50 kernel/locking/spinlock.c:159 serial8250_console_write+0x184/0xa40 drivers/tty/serial/8250/8250_port.c:3198 <-- lock(&port_lock_key); call_console_drivers kernel/printk/printk.c:1819 [inline] console_unlock+0x8cb/0xd00 kernel/printk/printk.c:2504 vprintk_emit+0x1b5/0x470 kernel/printk/printk.c:2024 <-- lock(console_owner); vprintk_func+0x8d/0x250 kernel/printk/printk_safe.c:394 printk+0xba/0xed kernel/printk/printk.c:2084 register_console+0x8b3/0xc10 kernel/printk/printk.c:2829 univ8250_console_init+0x3a/0x46 drivers/tty/serial/8250/8250_core.c:681 console_init+0x49d/0x6d3 kernel/printk/printk.c:2915 start_kernel+0x5e9/0x879 init/main.c:713 secondary_startup_64+0xa4/0xb0 arch/x86/kernel/head_64.S:241
-> #0 (console_owner){....}-{0:0}: [...] lock_acquire+0x127/0x340 kernel/locking/lockdep.c:4734 console_trylock_spinning kernel/printk/printk.c:1773 [inline] <-- lock(console_owner); vprintk_emit+0x307/0x470 kernel/printk/printk.c:2023 vprintk_func+0x8d/0x250 kernel/printk/printk_safe.c:394 printk+0xba/0xed kernel/printk/printk.c:2084 fail_dump lib/fault-inject.c:45 [inline] should_fail+0x67b/0x7c0 lib/fault-inject.c:144 __should_failslab+0x152/0x1c0 mm/failslab.c:33 should_failslab+0x5/0x10 mm/slab_common.c:1224 slab_pre_alloc_hook mm/slab.h:468 [inline] slab_alloc_node mm/slub.c:2723 [inline] slab_alloc mm/slub.c:2807 [inline] __kmalloc+0x72/0x300 mm/slub.c:3871 kmalloc include/linux/slab.h:582 [inline] tty_buffer_alloc+0x23f/0x2a0 drivers/tty/tty_buffer.c:175 __tty_buffer_request_room+0x156/0x2a0 drivers/tty/tty_buffer.c:273 tty_insert_flip_string_fixed_flag+0x93/0x250 drivers/tty/tty_buffer.c:318 tty_insert_flip_string include/linux/tty_flip.h:37 [inline] pty_write+0x126/0x1f0 drivers/tty/pty.c:122 <-- lock(&port->lock); n_tty_write+0xa7a/0xfc0 drivers/tty/n_tty.c:2356 do_tty_write drivers/tty/tty_io.c:961 [inline] tty_write+0x512/0x930 drivers/tty/tty_io.c:1045 __vfs_write+0x76/0x100 fs/read_write.c:494 [...]
other info that might help us debug this:
Chain exists of: console_owner --> &port_lock_key --> &port->lock
Link: https://lkml.kernel.org/r/20220511061951.1114-2-zhengqi.arch@bytedance.com Link: https://lkml.kernel.org/r/20220510113809.80626-2-zhengqi.arch@bytedance.com Fixes: b6da31b2c07c ("tty: Fix data race in tty_insert_flip_string_fixed_flag") Signed-off-by: Qi Zheng zhengqi.arch@bytedance.com Acked-by: Jiri Slaby jirislaby@kernel.org Acked-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Akinobu Mita akinobu.mita@gmail.com Cc: Vlastimil Babka vbabka@suse.cz Cc: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 646510476c30..bfa431a8e690 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -175,7 +175,8 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) */ if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit) return NULL; - p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); + p = kmalloc(sizeof(struct tty_buffer) + 2 * size, + GFP_ATOMIC | __GFP_NOWARN); if (p == NULL) return NULL;
From: Corentin Labbe clabbe@baylibre.com
[ Upstream commit 359e893e8af456be2fefabe851716237df289cbf ]
sun8i-ss fail handling IVs when doing decryption of multiple SGs in-place. It should backup the last block of each SG source for using it later as IVs. In the same time remove allocation on requests path for storing all IVs.
Fixes: f08fcced6d00 ("crypto: allwinner - Add sun8i-ss cryptographic offloader") Signed-off-by: Corentin Labbe clabbe@baylibre.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- .../allwinner/sun8i-ss/sun8i-ss-cipher.c | 115 ++++++++++++------ .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 30 +++-- drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h | 14 ++- 3 files changed, 107 insertions(+), 52 deletions(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c index 554e400d41ca..70e2e6e37389 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-cipher.c @@ -93,6 +93,68 @@ static int sun8i_ss_cipher_fallback(struct skcipher_request *areq) return err; }
+static int sun8i_ss_setup_ivs(struct skcipher_request *areq) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); + struct sun8i_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm); + struct sun8i_ss_dev *ss = op->ss; + struct sun8i_cipher_req_ctx *rctx = skcipher_request_ctx(areq); + struct scatterlist *sg = areq->src; + unsigned int todo, offset; + unsigned int len = areq->cryptlen; + unsigned int ivsize = crypto_skcipher_ivsize(tfm); + struct sun8i_ss_flow *sf = &ss->flows[rctx->flow]; + int i = 0; + u32 a; + int err; + + rctx->ivlen = ivsize; + if (rctx->op_dir & SS_DECRYPTION) { + offset = areq->cryptlen - ivsize; + scatterwalk_map_and_copy(sf->biv, areq->src, offset, + ivsize, 0); + } + + /* we need to copy all IVs from source in case DMA is bi-directionnal */ + while (sg && len) { + if (sg_dma_len(sg) == 0) { + sg = sg_next(sg); + continue; + } + if (i == 0) + memcpy(sf->iv[0], areq->iv, ivsize); + a = dma_map_single(ss->dev, sf->iv[i], ivsize, DMA_TO_DEVICE); + if (dma_mapping_error(ss->dev, a)) { + memzero_explicit(sf->iv[i], ivsize); + dev_err(ss->dev, "Cannot DMA MAP IV\n"); + err = -EFAULT; + goto dma_iv_error; + } + rctx->p_iv[i] = a; + /* we need to setup all others IVs only in the decrypt way */ + if (rctx->op_dir & SS_ENCRYPTION) + return 0; + todo = min(len, sg_dma_len(sg)); + len -= todo; + i++; + if (i < MAX_SG) { + offset = sg->length - ivsize; + scatterwalk_map_and_copy(sf->iv[i], sg, offset, ivsize, 0); + } + rctx->niv = i; + sg = sg_next(sg); + } + + return 0; +dma_iv_error: + i--; + while (i >= 0) { + dma_unmap_single(ss->dev, rctx->p_iv[i], ivsize, DMA_TO_DEVICE); + memzero_explicit(sf->iv[i], ivsize); + } + return err; +} + static int sun8i_ss_cipher(struct skcipher_request *areq) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq); @@ -101,9 +163,9 @@ static int sun8i_ss_cipher(struct skcipher_request *areq) struct sun8i_cipher_req_ctx *rctx = skcipher_request_ctx(areq); struct skcipher_alg *alg = crypto_skcipher_alg(tfm); struct sun8i_ss_alg_template *algt; + struct sun8i_ss_flow *sf = &ss->flows[rctx->flow]; struct scatterlist *sg; unsigned int todo, len, offset, ivsize; - void *backup_iv = NULL; int nr_sgs = 0; int nr_sgd = 0; int err = 0; @@ -134,30 +196,9 @@ static int sun8i_ss_cipher(struct skcipher_request *areq)
ivsize = crypto_skcipher_ivsize(tfm); if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) { - rctx->ivlen = ivsize; - rctx->biv = kzalloc(ivsize, GFP_KERNEL | GFP_DMA); - if (!rctx->biv) { - err = -ENOMEM; + err = sun8i_ss_setup_ivs(areq); + if (err) goto theend_key; - } - if (rctx->op_dir & SS_DECRYPTION) { - backup_iv = kzalloc(ivsize, GFP_KERNEL); - if (!backup_iv) { - err = -ENOMEM; - goto theend_key; - } - offset = areq->cryptlen - ivsize; - scatterwalk_map_and_copy(backup_iv, areq->src, offset, - ivsize, 0); - } - memcpy(rctx->biv, areq->iv, ivsize); - rctx->p_iv = dma_map_single(ss->dev, rctx->biv, rctx->ivlen, - DMA_TO_DEVICE); - if (dma_mapping_error(ss->dev, rctx->p_iv)) { - dev_err(ss->dev, "Cannot DMA MAP IV\n"); - err = -ENOMEM; - goto theend_iv; - } } if (areq->src == areq->dst) { nr_sgs = dma_map_sg(ss->dev, areq->src, sg_nents(areq->src), @@ -243,21 +284,19 @@ static int sun8i_ss_cipher(struct skcipher_request *areq) }
theend_iv: - if (rctx->p_iv) - dma_unmap_single(ss->dev, rctx->p_iv, rctx->ivlen, - DMA_TO_DEVICE); - if (areq->iv && ivsize > 0) { - if (rctx->biv) { - offset = areq->cryptlen - ivsize; - if (rctx->op_dir & SS_DECRYPTION) { - memcpy(areq->iv, backup_iv, ivsize); - kfree_sensitive(backup_iv); - } else { - scatterwalk_map_and_copy(areq->iv, areq->dst, offset, - ivsize, 0); - } - kfree(rctx->biv); + for (i = 0; i < rctx->niv; i++) { + dma_unmap_single(ss->dev, rctx->p_iv[i], ivsize, DMA_TO_DEVICE); + memzero_explicit(sf->iv[i], ivsize); + } + + offset = areq->cryptlen - ivsize; + if (rctx->op_dir & SS_DECRYPTION) { + memcpy(areq->iv, sf->biv, ivsize); + memzero_explicit(sf->biv, ivsize); + } else { + scatterwalk_map_and_copy(areq->iv, areq->dst, offset, + ivsize, 0); } }
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c index 319fe3279a71..657530578643 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c @@ -66,6 +66,7 @@ int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx const char *name) { int flow = rctx->flow; + unsigned int ivlen = rctx->ivlen; u32 v = SS_START; int i;
@@ -104,15 +105,14 @@ int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx mutex_lock(&ss->mlock); writel(rctx->p_key, ss->base + SS_KEY_ADR_REG);
- if (i == 0) { - if (rctx->p_iv) - writel(rctx->p_iv, ss->base + SS_IV_ADR_REG); - } else { - if (rctx->biv) { - if (rctx->op_dir == SS_ENCRYPTION) - writel(rctx->t_dst[i - 1].addr + rctx->t_dst[i - 1].len * 4 - rctx->ivlen, ss->base + SS_IV_ADR_REG); + if (ivlen) { + if (rctx->op_dir == SS_ENCRYPTION) { + if (i == 0) + writel(rctx->p_iv[0], ss->base + SS_IV_ADR_REG); else - writel(rctx->t_src[i - 1].addr + rctx->t_src[i - 1].len * 4 - rctx->ivlen, ss->base + SS_IV_ADR_REG); + writel(rctx->t_dst[i - 1].addr + rctx->t_dst[i - 1].len * 4 - ivlen, ss->base + SS_IV_ADR_REG); + } else { + writel(rctx->p_iv[i], ss->base + SS_IV_ADR_REG); } }
@@ -464,7 +464,7 @@ static void sun8i_ss_free_flows(struct sun8i_ss_dev *ss, int i) */ static int allocate_flows(struct sun8i_ss_dev *ss) { - int i, err; + int i, j, err;
ss->flows = devm_kcalloc(ss->dev, MAXFLOW, sizeof(struct sun8i_ss_flow), GFP_KERNEL); @@ -474,6 +474,18 @@ static int allocate_flows(struct sun8i_ss_dev *ss) for (i = 0; i < MAXFLOW; i++) { init_completion(&ss->flows[i].complete);
+ ss->flows[i].biv = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, + GFP_KERNEL | GFP_DMA); + if (!ss->flows[i].biv) + 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]) + goto error_engine; + } + ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true); if (!ss->flows[i].engine) { dev_err(ss->dev, "Cannot allocate engine\n"); diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h index 28188685b910..57ada8653855 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h @@ -121,11 +121,15 @@ struct sginfo { * @complete: completion for the current task on this flow * @status: set to 1 by interrupt if task is done * @stat_req: number of request done by this flow + * @iv: list of IV to use for each step + * @biv: buffer which contain the backuped IV */ struct sun8i_ss_flow { struct crypto_engine *engine; struct completion complete; int status; + u8 *iv[MAX_SG]; + u8 *biv; #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG unsigned long stat_req; #endif @@ -164,28 +168,28 @@ struct sun8i_ss_dev { * @t_src: list of mapped SGs with their size * @t_dst: list of mapped SGs with their size * @p_key: DMA address of the key - * @p_iv: DMA address of the IV + * @p_iv: DMA address of the IVs + * @niv: Number of IVs DMA mapped * @method: current algorithm for this request * @op_mode: op_mode for this request * @op_dir: direction (encrypt vs decrypt) for this request * @flow: the flow to use for this request - * @ivlen: size of biv + * @ivlen: size of IVs * @keylen: keylen for this request - * @biv: buffer which contain the IV * @fallback_req: request struct for invoking the fallback skcipher TFM */ struct sun8i_cipher_req_ctx { struct sginfo t_src[MAX_SG]; struct sginfo t_dst[MAX_SG]; u32 p_key; - u32 p_iv; + u32 p_iv[MAX_SG]; + int niv; u32 method; u32 op_mode; u32 op_dir; int flow; unsigned int ivlen; unsigned int keylen; - void *biv; struct skcipher_request fallback_req; // keep at the end };
From: Corentin Labbe clabbe@baylibre.com
[ Upstream commit c149e4763d28bb4c0e5daae8a59f2c74e889f407 ]
sun8i-ss does not handle well the possible zero sized sg.
Fixes: d9b45418a917 ("crypto: sun8i-ss - support hash algorithms") Signed-off-by: Corentin Labbe clabbe@baylibre.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 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c index 1a71ed49d233..ca4f280af35d 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c @@ -380,13 +380,21 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq) }
len = areq->nbytes; - for_each_sg(areq->src, sg, nr_sgs, i) { + sg = areq->src; + i = 0; + while (len > 0 && sg) { + if (sg_dma_len(sg) == 0) { + sg = sg_next(sg); + continue; + } rctx->t_src[i].addr = sg_dma_address(sg); todo = min(len, sg_dma_len(sg)); rctx->t_src[i].len = todo / 4; len -= todo; rctx->t_dst[i].addr = addr_res; rctx->t_dst[i].len = digestsize / 4; + sg = sg_next(sg); + i++; } if (len > 0) { dev_err(ss->dev, "remaining len %d\n", len);
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit 91e8bcd7b4da182e09ea19a2c73167345fe14c98 ]
The access to cryptd_queue::cpu_queue is synchronized by disabling preemption in cryptd_enqueue_request() and disabling BH in cryptd_queue_worker(). This implies that access is allowed from BH.
If cryptd_enqueue_request() is invoked from preemptible context _and_ soft interrupt then this can lead to list corruption since cryptd_enqueue_request() is not protected against access from soft interrupt.
Replace get_cpu() in cryptd_enqueue_request() with local_bh_disable() to ensure BH is always disabled. Remove preempt_disable() from cryptd_queue_worker() since it is not needed because local_bh_disable() ensures synchronisation.
Fixes: 254eff771441 ("crypto: cryptd - Per-CPU thread implementation...") Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/cryptd.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index a1bea0f4baa8..668095eca0fa 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c @@ -39,6 +39,10 @@ struct cryptd_cpu_queue { };
struct cryptd_queue { + /* + * Protected by disabling BH to allow enqueueing from softinterrupt and + * dequeuing from kworker (cryptd_queue_worker()). + */ struct cryptd_cpu_queue __percpu *cpu_queue; };
@@ -125,28 +129,28 @@ static void cryptd_fini_queue(struct cryptd_queue *queue) static int cryptd_enqueue_request(struct cryptd_queue *queue, struct crypto_async_request *request) { - int cpu, err; + int err; struct cryptd_cpu_queue *cpu_queue; refcount_t *refcnt;
- cpu = get_cpu(); + local_bh_disable(); cpu_queue = this_cpu_ptr(queue->cpu_queue); err = crypto_enqueue_request(&cpu_queue->queue, request);
refcnt = crypto_tfm_ctx(request->tfm);
if (err == -ENOSPC) - goto out_put_cpu; + goto out;
- queue_work_on(cpu, cryptd_wq, &cpu_queue->work); + queue_work_on(smp_processor_id(), cryptd_wq, &cpu_queue->work);
if (!refcount_read(refcnt)) - goto out_put_cpu; + goto out;
refcount_inc(refcnt);
-out_put_cpu: - put_cpu(); +out: + local_bh_enable();
return err; } @@ -162,15 +166,10 @@ static void cryptd_queue_worker(struct work_struct *work) cpu_queue = container_of(work, struct cryptd_cpu_queue, work); /* * Only handle one request at a time to avoid hogging crypto workqueue. - * preempt_disable/enable is used to prevent being preempted by - * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent - * cryptd_enqueue_request() being accessed from software interrupts. */ local_bh_disable(); - preempt_disable(); backlog = crypto_get_backlog(&cpu_queue->queue); req = crypto_dequeue_request(&cpu_queue->queue); - preempt_enable(); local_bh_enable();
if (!req)
From: Eugen Hristev eugen.hristev@microchip.com
[ Upstream commit b7e86ef7afd128577ff7bb0db0ae82d27d7ed7ad ]
interrupt-parent is not to be used as a boolean property. It is already present in the DT in the proper way it's supposed to be used: interrupt-parent = <&gic>;
This is also reported by dtbs_check: arch/arm/boot/dts/at91-sama7g5ek.dtb: interrupt-controller@e8c11000: interrupt-parent: True is not of type 'array' From schema: /.local/lib/python3.8/site-packages/dtschema/schemas/interrupts.yaml
Fixes: 7540629e2fc7 ("ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek") Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20220503133127.64320-1-eugen.hristev@microchip.com Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/sama7g5.dtsi | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi index f691c8f08d04..b63263129692 100644 --- a/arch/arm/boot/dts/sama7g5.dtsi +++ b/arch/arm/boot/dts/sama7g5.dtsi @@ -857,7 +857,6 @@ #interrupt-cells = <3>; #address-cells = <0>; interrupt-controller; - interrupt-parent; reg = <0xe8c11000 0x1000>, <0xe8c12000 0x2000>; };
From: Michael Walle michael@walle.cc
[ Upstream commit 8b4092fd0c1a0aaa985413c43b027f87dd457207 ]
The YAML binding (crypto/atmel,at91sam9g46-aes.yaml) mandates the order of the channels. Swap them to pass devicetree validation.
Fixes: 290deaa10c50 ("ARM: dts: add DT for lan966 SoC and 2-port board pcb8291") Signed-off-by: Michael Walle michael@walle.cc Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Tested-by: Horatiu Vultur horatiu.vultur@microchip.com Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20220502224127.2604333-2-michael@walle.cc Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/lan966x.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi index 7d2869648050..5e9cbc8cdcbc 100644 --- a/arch/arm/boot/dts/lan966x.dtsi +++ b/arch/arm/boot/dts/lan966x.dtsi @@ -114,9 +114,9 @@ compatible = "atmel,at91sam9g46-aes"; reg = <0xe004c000 0x100>; interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>, - <&dma0 AT91_XDMAC_DT_PERID(12)>; - dma-names = "rx", "tx"; + dmas = <&dma0 AT91_XDMAC_DT_PERID(12)>, + <&dma0 AT91_XDMAC_DT_PERID(13)>; + dma-names = "tx", "rx"; clocks = <&nic_clk>; clock-names = "aes_clk"; };
From: Mina Almasry almasrymina@google.com
[ Upstream commit 4b25f030ae69ba710eff587cabb4c57cb7e7a8a1 ]
After commit db71ef79b59b ("hugetlb: make free_huge_page irq safe"), the subpool lock should be locked with spin_lock_irq() and all call sites was modified as such, except for the ones in hugetlbfs_statfs().
Link: https://lkml.kernel.org/r/20220429202207.3045-1-almasrymina@google.com Fixes: db71ef79b59b ("hugetlb: make free_huge_page irq safe") Signed-off-by: Mina Almasry almasrymina@google.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/hugetlbfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index dd3a088db11d..591599829e2a 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -1048,12 +1048,12 @@ static int hugetlbfs_statfs(struct dentry *dentry, struct kstatfs *buf) if (sbinfo->spool) { long free_pages;
- spin_lock(&sbinfo->spool->lock); + spin_lock_irq(&sbinfo->spool->lock); buf->f_blocks = sbinfo->spool->max_hpages; free_pages = sbinfo->spool->max_hpages - sbinfo->spool->used_hpages; buf->f_bavail = buf->f_bfree = free_pages; - spin_unlock(&sbinfo->spool->lock); + spin_unlock_irq(&sbinfo->spool->lock); buf->f_files = sbinfo->max_inodes; buf->f_ffree = sbinfo->free_inodes; }
From: Jane Chu jane.chu@oracle.com
[ Upstream commit b3fdf9398a16f01dc013967a4ab25e99c3f4fc12 ]
Relocate the twin mce functions to arch/x86/mm/pat/set_memory.c file where they belong.
While at it, fixup a function name in a comment.
Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Jane Chu jane.chu@oracle.com Acked-by: Borislav Petkov bp@suse.de Cc: Stephen Rothwell sfr@canb.auug.org.au [sfr: gate {set,clear}_mce_nospec() by CONFIG_X86_64] Link: https://lore.kernel.org/r/165272527328.90175.8336008202048685278.stgit@dwill... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/set_memory.h | 52 ------------------------------- arch/x86/mm/pat/set_memory.c | 50 +++++++++++++++++++++++++++-- include/linux/set_memory.h | 8 ++--- 3 files changed, 52 insertions(+), 58 deletions(-)
diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h index 78ca53512486..b45c4d27fd46 100644 --- a/arch/x86/include/asm/set_memory.h +++ b/arch/x86/include/asm/set_memory.h @@ -86,56 +86,4 @@ bool kernel_page_present(struct page *page);
extern int kernel_set_to_readonly;
-#ifdef CONFIG_X86_64 -/* - * Prevent speculative access to the page by either unmapping - * it (if we do not require access to any part of the page) or - * marking it uncacheable (if we want to try to retrieve data - * from non-poisoned lines in the page). - */ -static inline int set_mce_nospec(unsigned long pfn, bool unmap) -{ - unsigned long decoy_addr; - int rc; - - /* SGX pages are not in the 1:1 map */ - if (arch_is_platform_page(pfn << PAGE_SHIFT)) - return 0; - /* - * We would like to just call: - * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1); - * but doing that would radically increase the odds of a - * speculative access to the poison page because we'd have - * the virtual address of the kernel 1:1 mapping sitting - * around in registers. - * Instead we get tricky. We create a non-canonical address - * that looks just like the one we want, but has bit 63 flipped. - * This relies on set_memory_XX() properly sanitizing any __pa() - * results with __PHYSICAL_MASK or PTE_PFN_MASK. - */ - decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63)); - - if (unmap) - rc = set_memory_np(decoy_addr, 1); - else - rc = set_memory_uc(decoy_addr, 1); - if (rc) - pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); - return rc; -} -#define set_mce_nospec set_mce_nospec - -/* Restore full speculative operation to the pfn. */ -static inline int clear_mce_nospec(unsigned long pfn) -{ - return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1); -} -#define clear_mce_nospec clear_mce_nospec -#else -/* - * Few people would run a 32-bit kernel on a machine that supports - * recoverable errors because they have too much memory to boot 32-bit. - */ -#endif - #endif /* _ASM_X86_SET_MEMORY_H */ diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 0656db33574d..417440c6bf80 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -19,6 +19,7 @@ #include <linux/vmstat.h> #include <linux/kernel.h> #include <linux/cc_platform.h> +#include <linux/set_memory.h>
#include <asm/e820/api.h> #include <asm/processor.h> @@ -29,7 +30,6 @@ #include <asm/pgalloc.h> #include <asm/proto.h> #include <asm/memtype.h> -#include <asm/set_memory.h> #include <asm/hyperv-tlfs.h> #include <asm/mshyperv.h>
@@ -1805,7 +1805,7 @@ static inline int cpa_clear_pages_array(struct page **pages, int numpages, }
/* - * _set_memory_prot is an internal helper for callers that have been passed + * __set_memory_prot is an internal helper for callers that have been passed * a pgprot_t value from upper layers and a reservation has already been taken. * If you want to set the pgprot to a specific page protocol, use the * set_memory_xx() functions. @@ -1914,6 +1914,52 @@ int set_memory_wb(unsigned long addr, int numpages) } EXPORT_SYMBOL(set_memory_wb);
+/* + * Prevent speculative access to the page by either unmapping + * it (if we do not require access to any part of the page) or + * marking it uncacheable (if we want to try to retrieve data + * from non-poisoned lines in the page). + */ +#ifdef CONFIG_X86_64 +int set_mce_nospec(unsigned long pfn, bool unmap) +{ + unsigned long decoy_addr; + int rc; + + /* SGX pages are not in the 1:1 map */ + if (arch_is_platform_page(pfn << PAGE_SHIFT)) + return 0; + /* + * We would like to just call: + * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1); + * but doing that would radically increase the odds of a + * speculative access to the poison page because we'd have + * the virtual address of the kernel 1:1 mapping sitting + * around in registers. + * Instead we get tricky. We create a non-canonical address + * that looks just like the one we want, but has bit 63 flipped. + * This relies on set_memory_XX() properly sanitizing any __pa() + * results with __PHYSICAL_MASK or PTE_PFN_MASK. + */ + decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63)); + + if (unmap) + rc = set_memory_np(decoy_addr, 1); + else + rc = set_memory_uc(decoy_addr, 1); + if (rc) + pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); + return rc; +} + +/* Restore full speculative operation to the pfn. */ +int clear_mce_nospec(unsigned long pfn) +{ + return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1); +} +EXPORT_SYMBOL_GPL(clear_mce_nospec); +#endif /* CONFIG_X86_64 */ + int set_memory_x(unsigned long addr, int numpages) { if (!(__supported_pte_mask & _PAGE_NX)) diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h index f36be5166c19..683a6c3f7179 100644 --- a/include/linux/set_memory.h +++ b/include/linux/set_memory.h @@ -42,14 +42,14 @@ static inline bool can_set_direct_map(void) #endif #endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */
-#ifndef set_mce_nospec +#ifdef CONFIG_X86_64 +int set_mce_nospec(unsigned long pfn, bool unmap); +int clear_mce_nospec(unsigned long pfn); +#else static inline int set_mce_nospec(unsigned long pfn, bool unmap) { return 0; } -#endif - -#ifndef clear_mce_nospec static inline int clear_mce_nospec(unsigned long pfn) { return 0;
From: Jane Chu jane.chu@oracle.com
[ Upstream commit 5898b43af954b83c4a4ee4ab85c4dbafa395822a ]
The set_memory_uc() approach doesn't work well in all cases. As Dan pointed out when "The VMM unmapped the bad page from guest physical space and passed the machine check to the guest." "The guest gets virtual #MC on an access to that page. When the guest tries to do set_memory_uc() and instructs cpa_flush() to do clean caches that results in taking another fault / exception perhaps because the VMM unmapped the page from the guest."
Since the driver has special knowledge to handle NP or UC, mark the poisoned page with NP and let driver handle it when it comes down to repair.
Please refer to discussions here for more details. https://lore.kernel.org/all/CAPcyv4hrXPb1tASBZUg-GgdVs0OOFKXMXLiHmktg_kFi7YB...
Now since poisoned page is marked as not-present, in order to avoid writing to a not-present page and trigger kernel Oops, also fix pmem_do_write().
Fixes: 284ce4011ba6 ("x86/memory_failure: Introduce {set, clear}_mce_nospec()") Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Jane Chu jane.chu@oracle.com Acked-by: Tony Luck tony.luck@intel.com Link: https://lore.kernel.org/r/165272615484.103830.2563950688772226611.stgit@dwil... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/mce/core.c | 6 +++--- arch/x86/mm/pat/set_memory.c | 23 +++++++++++------------ drivers/nvdimm/pmem.c | 30 +++++++----------------------- include/linux/set_memory.h | 4 ++-- 4 files changed, 23 insertions(+), 40 deletions(-)
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 981496e6bc0e..fa67bb9d1afe 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -579,7 +579,7 @@ static int uc_decode_notifier(struct notifier_block *nb, unsigned long val,
pfn = mce->addr >> PAGE_SHIFT; if (!memory_failure(pfn, 0)) { - set_mce_nospec(pfn, whole_page(mce)); + set_mce_nospec(pfn); mce->kflags |= MCE_HANDLED_UC; }
@@ -1316,7 +1316,7 @@ static void kill_me_maybe(struct callback_head *cb)
ret = memory_failure(p->mce_addr >> PAGE_SHIFT, flags); if (!ret) { - set_mce_nospec(p->mce_addr >> PAGE_SHIFT, p->mce_whole_page); + set_mce_nospec(p->mce_addr >> PAGE_SHIFT); sync_core(); return; } @@ -1342,7 +1342,7 @@ static void kill_me_never(struct callback_head *cb) p->mce_count = 0; pr_err("Kernel accessed poison in user space at %llx\n", p->mce_addr); if (!memory_failure(p->mce_addr >> PAGE_SHIFT, 0)) - set_mce_nospec(p->mce_addr >> PAGE_SHIFT, p->mce_whole_page); + set_mce_nospec(p->mce_addr >> PAGE_SHIFT); }
static void queue_task_work(struct mce *m, char *msg, void (*func)(struct callback_head *)) diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 417440c6bf80..1abd5438f126 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -1914,14 +1914,9 @@ int set_memory_wb(unsigned long addr, int numpages) } EXPORT_SYMBOL(set_memory_wb);
-/* - * Prevent speculative access to the page by either unmapping - * it (if we do not require access to any part of the page) or - * marking it uncacheable (if we want to try to retrieve data - * from non-poisoned lines in the page). - */ +/* Prevent speculative access to a page by marking it not-present */ #ifdef CONFIG_X86_64 -int set_mce_nospec(unsigned long pfn, bool unmap) +int set_mce_nospec(unsigned long pfn) { unsigned long decoy_addr; int rc; @@ -1943,19 +1938,23 @@ int set_mce_nospec(unsigned long pfn, bool unmap) */ decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63));
- if (unmap) - rc = set_memory_np(decoy_addr, 1); - else - rc = set_memory_uc(decoy_addr, 1); + rc = set_memory_np(decoy_addr, 1); if (rc) pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); return rc; }
+static int set_memory_present(unsigned long *addr, int numpages) +{ + return change_page_attr_set(addr, numpages, __pgprot(_PAGE_PRESENT), 0); +} + /* Restore full speculative operation to the pfn. */ int clear_mce_nospec(unsigned long pfn) { - return set_memory_wb((unsigned long) pfn_to_kaddr(pfn), 1); + unsigned long addr = (unsigned long) pfn_to_kaddr(pfn); + + return set_memory_present(&addr, 1); } EXPORT_SYMBOL_GPL(clear_mce_nospec); #endif /* CONFIG_X86_64 */ diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 58d95242a836..4aa17132a557 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -158,36 +158,20 @@ static blk_status_t pmem_do_write(struct pmem_device *pmem, struct page *page, unsigned int page_off, sector_t sector, unsigned int len) { - blk_status_t rc = BLK_STS_OK; - bool bad_pmem = false; phys_addr_t pmem_off = sector * 512 + pmem->data_offset; void *pmem_addr = pmem->virt_addr + pmem_off;
- if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) - bad_pmem = true; + if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) { + blk_status_t rc = pmem_clear_poison(pmem, pmem_off, len); + + if (rc != BLK_STS_OK) + return rc; + }
- /* - * Note that we write the data both before and after - * clearing poison. The write before clear poison - * handles situations where the latest written data is - * preserved and the clear poison operation simply marks - * the address range as valid without changing the data. - * In this case application software can assume that an - * interrupted write will either return the new good - * data or an error. - * - * However, if pmem_clear_poison() leaves the data in an - * indeterminate state we need to perform the write - * after clear poison. - */ flush_dcache_page(page); write_pmem(pmem_addr, page, page_off, len); - if (unlikely(bad_pmem)) { - rc = pmem_clear_poison(pmem, pmem_off, len); - write_pmem(pmem_addr, page, page_off, len); - }
- return rc; + return BLK_STS_OK; }
static void pmem_submit_bio(struct bio *bio) diff --git a/include/linux/set_memory.h b/include/linux/set_memory.h index 683a6c3f7179..369769ce7399 100644 --- a/include/linux/set_memory.h +++ b/include/linux/set_memory.h @@ -43,10 +43,10 @@ static inline bool can_set_direct_map(void) #endif /* CONFIG_ARCH_HAS_SET_DIRECT_MAP */
#ifdef CONFIG_X86_64 -int set_mce_nospec(unsigned long pfn, bool unmap); +int set_mce_nospec(unsigned long pfn); int clear_mce_nospec(unsigned long pfn); #else -static inline int set_mce_nospec(unsigned long pfn, bool unmap) +static inline int set_mce_nospec(unsigned long pfn) { return 0; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit c8994b30d71d64d5dcc9bc0edbfdf367171aa96f ]
of_find_node_by_path() calls of_find_node_opts_by_path(), which 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: 9c1a5077fdca ("input: Rewrite sparcspkr device probing.") Signed-off-by: Miaoqian Lin linmq006@gmail.com Link: https://lore.kernel.org/r/20220516081018.42728-1-linmq006@gmail.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/sparcspkr.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c index fe43e5557ed7..cdcb7737c46a 100644 --- a/drivers/input/misc/sparcspkr.c +++ b/drivers/input/misc/sparcspkr.c @@ -205,6 +205,7 @@ static int bbc_beep_probe(struct platform_device *op)
info = &state->u.bbc; info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0); + of_node_put(dp); if (!info->clock_freq) goto out_free;
From: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com
[ Upstream commit 203926da2bff8e172200a2f11c758987af112d4a ]
When a Root Port or Root Complex Event Collector receives an error Message e.g., ERR_COR, it sets PCI_ERR_ROOT_COR_RCV in the Root Error Status register and logs the Requester ID in the Error Source Identification register. If it receives a second ERR_COR Message before software clears PCI_ERR_ROOT_COR_RCV, hardware sets PCI_ERR_ROOT_MULTI_COR_RCV and the Requester ID is lost.
In the following scenario, PCI_ERR_ROOT_MULTI_COR_RCV was never cleared:
- hardware receives ERR_COR message - hardware sets PCI_ERR_ROOT_COR_RCV - aer_irq() entered - aer_irq(): status = pci_read_config_dword(PCI_ERR_ROOT_STATUS) - aer_irq(): now status == PCI_ERR_ROOT_COR_RCV - hardware receives second ERR_COR message - hardware sets PCI_ERR_ROOT_MULTI_COR_RCV - aer_irq(): pci_write_config_dword(PCI_ERR_ROOT_STATUS, status) - PCI_ERR_ROOT_COR_RCV is cleared; PCI_ERR_ROOT_MULTI_COR_RCV is set - aer_irq() entered again - aer_irq(): status = pci_read_config_dword(PCI_ERR_ROOT_STATUS) - aer_irq(): now status == PCI_ERR_ROOT_MULTI_COR_RCV - aer_irq() exits because PCI_ERR_ROOT_COR_RCV not set - PCI_ERR_ROOT_MULTI_COR_RCV is still set
The same problem occurred with ERR_NONFATAL/ERR_FATAL Messages and PCI_ERR_ROOT_UNCOR_RCV and PCI_ERR_ROOT_MULTI_UNCOR_RCV.
Fix the problem by queueing an AER event and clearing the Root Error Status bits when any of these bits are set:
PCI_ERR_ROOT_COR_RCV PCI_ERR_ROOT_UNCOR_RCV PCI_ERR_ROOT_MULTI_COR_RCV PCI_ERR_ROOT_MULTI_UNCOR_RCV
See the bugzilla link for details from Eric about how to reproduce this problem.
[bhelgaas: commit log, move repro details to bugzilla] Fixes: e167bfcaa4cd ("PCI: aerdrv: remove magical ROOT_ERR_STATUS_MASKS") Link: https://bugzilla.kernel.org/show_bug.cgi?id=215992 Link: https://lore.kernel.org/r/20220418150237.1021519-1-sathyanarayanan.kuppuswam... Reported-by: Eric Badger ebadger@purestorage.com Signed-off-by: Kuppuswamy Sathyanarayanan sathyanarayanan.kuppuswamy@linux.intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Ashok Raj ashok.raj@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pcie/aer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 9fa1f97e5b27..7952e5efd6cf 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -101,6 +101,11 @@ struct aer_stats { #define ERR_COR_ID(d) (d & 0xffff) #define ERR_UNCOR_ID(d) (d >> 16)
+#define AER_ERR_STATUS_MASK (PCI_ERR_ROOT_UNCOR_RCV | \ + PCI_ERR_ROOT_COR_RCV | \ + PCI_ERR_ROOT_MULTI_COR_RCV | \ + PCI_ERR_ROOT_MULTI_UNCOR_RCV) + static int pcie_aer_disable; static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
@@ -1196,7 +1201,7 @@ static irqreturn_t aer_irq(int irq, void *context) struct aer_err_source e_src = {};
pci_read_config_dword(rp, aer + PCI_ERR_ROOT_STATUS, &e_src.status); - if (!(e_src.status & (PCI_ERR_ROOT_UNCOR_RCV|PCI_ERR_ROOT_COR_RCV))) + if (!(e_src.status & AER_ERR_STATUS_MASK)) return IRQ_NONE;
pci_read_config_dword(rp, aer + PCI_ERR_ROOT_ERR_SRC, &e_src.id);
From: Fabiano Rosas farosas@linux.ibm.com
[ Upstream commit ad55bae7dc364417434b69dd6c30104f20d0f84d ]
We removed most of the vcore logic from the P9 path but there's still a tracepoint that tried to dereference vc->runner.
Fixes: ecb6a7207f92 ("KVM: PPC: Book3S HV P9: Remove most of the vcore logic") Signed-off-by: Fabiano Rosas farosas@linux.ibm.com Reviewed-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220328215831.320409-1-farosas@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_hv.c | 8 ++++---- arch/powerpc/kvm/trace_hv.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 43af871383c2..aef0a6b423d8 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4233,13 +4233,13 @@ static void kvmppc_vcore_blocked(struct kvmppc_vcore *vc) start_wait = ktime_get();
vc->vcore_state = VCORE_SLEEPING; - trace_kvmppc_vcore_blocked(vc, 0); + trace_kvmppc_vcore_blocked(vc->runner, 0); spin_unlock(&vc->lock); schedule(); finish_rcuwait(&vc->wait); spin_lock(&vc->lock); vc->vcore_state = VCORE_INACTIVE; - trace_kvmppc_vcore_blocked(vc, 1); + trace_kvmppc_vcore_blocked(vc->runner, 1); ++vc->runner->stat.halt_successful_wait;
cur = ktime_get(); @@ -4619,9 +4619,9 @@ int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, if (kvmppc_vcpu_check_block(vcpu)) break;
- trace_kvmppc_vcore_blocked(vc, 0); + trace_kvmppc_vcore_blocked(vcpu, 0); schedule(); - trace_kvmppc_vcore_blocked(vc, 1); + trace_kvmppc_vcore_blocked(vcpu, 1); } finish_rcuwait(wait); } diff --git a/arch/powerpc/kvm/trace_hv.h b/arch/powerpc/kvm/trace_hv.h index 38cd0ed0a617..32e2cb5811cc 100644 --- a/arch/powerpc/kvm/trace_hv.h +++ b/arch/powerpc/kvm/trace_hv.h @@ -409,9 +409,9 @@ TRACE_EVENT(kvmppc_run_core, );
TRACE_EVENT(kvmppc_vcore_blocked, - TP_PROTO(struct kvmppc_vcore *vc, int where), + TP_PROTO(struct kvm_vcpu *vcpu, int where),
- TP_ARGS(vc, where), + TP_ARGS(vcpu, where),
TP_STRUCT__entry( __field(int, n_runnable) @@ -421,8 +421,8 @@ TRACE_EVENT(kvmppc_vcore_blocked, ),
TP_fast_assign( - __entry->runner_vcpu = vc->runner->vcpu_id; - __entry->n_runnable = vc->n_runnable; + __entry->runner_vcpu = vcpu->vcpu_id; + __entry->n_runnable = vcpu->arch.vcore->n_runnable; __entry->where = where; __entry->tgid = current->tgid; ),
From: Daire McNamara daire.mcnamara@microchip.com
[ Upstream commit 7013654af694f6e1a2e699a6450ea50d309dd0e5 ]
Clear the MSI bit in ISTATUS_LOCAL register after reading it, but before reading and handling individual MSI bits from the ISTATUS_MSI register. This avoids a potential race where new MSI bits may be set on the ISTATUS_MSI register after it was read and be missed when the MSI bit in the ISTATUS_LOCAL register is cleared.
ISTATUS_LOCAL is a read/write/clear register; the register's bits are set when the corresponding interrupt source is activated. Each source is independent and thus multiple sources may be active simultaneously. The processor can monitor and clear status bits. If one or more ISTATUS_LOCAL interrupt sources are active, the RootPort issues an interrupt towards the processor (on the AXI domain). Bit 28 of this register reports an MSI has been received by the RootPort.
ISTATUS_MSI is a read/write/clear register. Bits 31-0 are asserted when an MSI with message number 31-0 is received by the RootPort. The processor must monitor and clear these bits.
Effectively, Bit 28 of ISTATUS_LOCAL informs the processor that an MSI has arrived at the RootPort and ISTATUS_MSI informs the processor which MSI (in the range 0 - 31) needs handling.
Reported by: Bjorn Helgaas bhelgaas@google.com Link: https://lore.kernel.org/linux-pci/20220127202000.GA126335@bhelgaas/
Link: https://lore.kernel.org/r/20220517141622.145581-1-daire.mcnamara@microchip.c... Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver") Signed-off-by: Daire McNamara daire.mcnamara@microchip.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-microchip-host.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/pci/controller/pcie-microchip-host.c b/drivers/pci/controller/pcie-microchip-host.c index 8175abed0f05..2c52a8cef726 100644 --- a/drivers/pci/controller/pcie-microchip-host.c +++ b/drivers/pci/controller/pcie-microchip-host.c @@ -419,6 +419,7 @@ static void mc_handle_msi(struct irq_desc *desc)
status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL); if (status & PM_MSI_INT_MSI_MASK) { + writel_relaxed(status & PM_MSI_INT_MSI_MASK, bridge_base_addr + ISTATUS_LOCAL); status = readl_relaxed(bridge_base_addr + ISTATUS_MSI); for_each_set_bit(bit, &status, msi->num_vectors) { ret = generic_handle_domain_irq(msi->dev_domain, bit); @@ -437,13 +438,8 @@ static void mc_msi_bottom_irq_ack(struct irq_data *data) void __iomem *bridge_base_addr = port->axi_base_addr + MC_PCIE_BRIDGE_ADDR; u32 bitpos = data->hwirq; - unsigned long status;
writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI); - status = readl_relaxed(bridge_base_addr + ISTATUS_MSI); - if (!status) - writel_relaxed(BIT(PM_MSI_INT_MSI_SHIFT), - bridge_base_addr + ISTATUS_LOCAL); }
static void mc_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 2bcf3bbd348fc10260aa6243ff6a22a1882b5b35 ]
Media ready is asserted by the device independent of whether mem_enabled was ever set. Drop this check to allow for dropping wait_for_media() in favor of ->wait_media_ready().
Fixes: 8dd2bc0f8e02 ("cxl/mem: Add the cxl_mem driver") Reviewed-by: Ira Weiny ira.weiny@intel.com Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Link: https://lore.kernel.org/r/165291685501.1426646.10372821863672431074.stgit@dw... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/mem.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/cxl/mem.c b/drivers/cxl/mem.c index 49a4b1c47299..44e899f06094 100644 --- a/drivers/cxl/mem.c +++ b/drivers/cxl/mem.c @@ -27,12 +27,8 @@ static int wait_for_media(struct cxl_memdev *cxlmd) { struct cxl_dev_state *cxlds = cxlmd->cxlds; - struct cxl_endpoint_dvsec_info *info = &cxlds->info; int rc;
- if (!info->mem_enabled) - return -EBUSY; - rc = cxlds->wait_media_ready(cxlds); if (rc) return rc;
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit e4e62bbc6aba49a5edb3156ec65f6698ff37d228 ]
'ddata->clk' is enabled by clk_prepare_enable(), it should be disabled by clk_disable_unprepare().
Fixes: 8d9d4bdc495f ("hwrng: omap3-rom - Use runtime PM instead of custom functions") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/omap3-rom-rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index e0d77fa048fb..f06e4f95114f 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -92,7 +92,7 @@ static int __maybe_unused omap_rom_rng_runtime_resume(struct device *dev)
r = ddata->rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT); if (r != 0) { - clk_disable(ddata->clk); + clk_disable_unprepare(ddata->clk); dev_err(dev, "HW init failed: %d\n", r);
return -EIO;
From: Ian Rogers irogers@google.com
[ Upstream commit d98079c05b5a5411c6030c47b6256cbeeeff77d0 ]
On Intel Icelake, topdown events must always be grouped with a slots event as leader. When a metric is parsed a weak group is formed and retried if perf_event_open fails. The retried events aren't grouped breaking the slots leader requirement. This change modifies the weak group "reset" behavior so that topdown events aren't broken from the group for the retry.
$ perf stat -e '{slots,topdown-bad-spec,topdown-be-bound,topdown-fe-bound,topdown-retiring,branch-instructions,branch-misses,bus-cycles,cache-misses,cache-references,cpu-cycles,instructions,mem-loads,mem-stores,ref-cycles,baclears.any,ARITH.DIVIDER_ACTIVE}:W' -a sleep 1
Performance counter stats for 'system wide':
47,867,188,483 slots (92.27%) <not supported> topdown-bad-spec <not supported> topdown-be-bound <not supported> topdown-fe-bound <not supported> topdown-retiring 2,173,346,937 branch-instructions (92.27%) 10,540,253 branch-misses # 0.48% of all branches (92.29%) 96,291,140 bus-cycles (92.29%) 6,214,202 cache-misses # 20.120 % of all cache refs (92.29%) 30,886,082 cache-references (76.91%) 11,773,726,641 cpu-cycles (84.62%) 11,807,585,307 instructions # 1.00 insn per cycle (92.31%) 0 mem-loads (92.32%) 2,212,928,573 mem-stores (84.69%) 10,024,403,118 ref-cycles (92.35%) 16,232,978 baclears.any (92.35%) 23,832,633 ARITH.DIVIDER_ACTIVE (84.59%)
0.981070734 seconds time elapsed
After:
$ perf stat -e '{slots,topdown-bad-spec,topdown-be-bound,topdown-fe-bound,topdown-retiring,branch-instructions,branch-misses,bus-cycles,cache-misses,cache-references,cpu-cycles,instructions,mem-loads,mem-stores,ref-cycles,baclears.any,ARITH.DIVIDER_ACTIVE}:W' -a sleep 1
Performance counter stats for 'system wide':
31040189283 slots (92.27%) 8997514811 topdown-bad-spec # 28.2% bad speculation (92.27%) 10997536028 topdown-be-bound # 34.5% backend bound (92.27%) 4778060526 topdown-fe-bound # 15.0% frontend bound (92.27%) 7086628768 topdown-retiring # 22.2% retiring (92.27%) 1417611942 branch-instructions (92.26%) 5285529 branch-misses # 0.37% of all branches (92.28%) 62922469 bus-cycles (92.29%) 1440708 cache-misses # 8.292 % of all cache refs (92.30%) 17374098 cache-references (76.94%) 8040889520 cpu-cycles (84.63%) 7709992319 instructions # 0.96 insn per cycle (92.32%) 0 mem-loads (92.32%) 1515669558 mem-stores (84.68%) 6542411177 ref-cycles (92.35%) 4154149 baclears.any (92.35%) 20556152 ARITH.DIVIDER_ACTIVE (84.59%)
1.010799593 seconds time elapsed
Reviewed-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Florian Fischer florian.fischer@muhq.space Cc: Ingo Molnar mingo@redhat.com Cc: James Clark james.clark@arm.com Cc: Jiri Olsa jolsa@kernel.org Cc: John Garry john.garry@huawei.com Cc: Kim Phillips kim.phillips@amd.com Cc: Madhavan Srinivasan maddy@linux.ibm.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Riccardo Mancini rickyman7@gmail.com Cc: Shunsuke Nakamura nakamura.shun@fujitsu.com Cc: Stephane Eranian eranian@google.com Cc: Xing Zhengjun zhengjun.xing@linux.intel.com Link: https://lore.kernel.org/r/20220517052724.283874-2-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/arch/x86/util/evsel.c | 12 ++++++++++++ tools/perf/util/evlist.c | 16 ++++++++++++++-- tools/perf/util/evsel.c | 10 ++++++++++ tools/perf/util/evsel.h | 3 +++ 4 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/tools/perf/arch/x86/util/evsel.c b/tools/perf/arch/x86/util/evsel.c index ac2899a25b7a..00cb4466b4ca 100644 --- a/tools/perf/arch/x86/util/evsel.c +++ b/tools/perf/arch/x86/util/evsel.c @@ -3,6 +3,7 @@ #include <stdlib.h> #include "util/evsel.h" #include "util/env.h" +#include "util/pmu.h" #include "linux/string.h"
void arch_evsel__set_sample_weight(struct evsel *evsel) @@ -29,3 +30,14 @@ void arch_evsel__fixup_new_cycles(struct perf_event_attr *attr)
free(env.cpuid); } + +bool arch_evsel__must_be_in_group(const struct evsel *evsel) +{ + if ((evsel->pmu_name && strcmp(evsel->pmu_name, "cpu")) || + !pmu_have_event("cpu", "slots")) + return false; + + return evsel->name && + (!strcasecmp(evsel->name, "slots") || + strcasestr(evsel->name, "topdown")); +} diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 52ea004ba01e..4804b52f2946 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1790,8 +1790,17 @@ struct evsel *evlist__reset_weak_group(struct evlist *evsel_list, struct evsel * if (evsel__has_leader(c2, leader)) { if (is_open && close) perf_evsel__close(&c2->core); - evsel__set_leader(c2, c2); - c2->core.nr_members = 0; + /* + * We want to close all members of the group and reopen + * them. Some events, like Intel topdown, require being + * in a group and so keep these in the group. + */ + if (!evsel__must_be_in_group(c2) && c2 != leader) { + evsel__set_leader(c2, c2); + c2->core.nr_members = 0; + leader->core.nr_members--; + } + /* * Set this for all former members of the group * to indicate they get reopened. @@ -1799,6 +1808,9 @@ struct evsel *evlist__reset_weak_group(struct evlist *evsel_list, struct evsel * c2->reset_group = true; } } + /* Reset the leader count if all entries were removed. */ + if (leader->core.nr_members == 1) + leader->core.nr_members = 0; return leader; }
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 2a1729e7aee4..b98882cbb286 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3077,3 +3077,13 @@ int evsel__source_count(const struct evsel *evsel) } return count; } + +bool __weak arch_evsel__must_be_in_group(const struct evsel *evsel __maybe_unused) +{ + return false; +} + +bool evsel__must_be_in_group(const struct evsel *evsel) +{ + return arch_evsel__must_be_in_group(evsel); +} diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 041b42d33bf5..a36172ed4cf6 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -483,6 +483,9 @@ bool evsel__has_leader(struct evsel *evsel, struct evsel *leader); bool evsel__is_leader(struct evsel *evsel); void evsel__set_leader(struct evsel *evsel, struct evsel *leader); int evsel__source_count(const struct evsel *evsel); +bool evsel__must_be_in_group(const struct evsel *evsel); + +bool arch_evsel__must_be_in_group(const struct evsel *evsel);
/* * Macro to swap the bit-field postition and size.
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit e8f4f794d7047dd36f090f44f12cd645fba204d2 ]
If any member in a group has a different cpu mask than the other members, the current perf stat disables group. when the perf metrics topdown events are part of the group, the below <not supported> error will be triggered.
$ perf stat -e "{slots,topdown-retiring,uncore_imc_free_running_0/dclk/}" -a sleep 1 WARNING: grouped events cpus do not match, disabling group: anon group { slots, topdown-retiring, uncore_imc_free_running_0/dclk/ }
Performance counter stats for 'system wide':
141,465,174 slots <not supported> topdown-retiring 1,605,330,334 uncore_imc_free_running_0/dclk/
The perf metrics topdown events must always be grouped with a slots event as leader.
Factor out evsel__remove_from_group() to only remove the regular events from the group.
Remove evsel__must_be_in_group(), since no one use it anymore.
With the patch, the topdown events aren't broken from the group for the splitting.
$ perf stat -e "{slots,topdown-retiring,uncore_imc_free_running_0/dclk/}" -a sleep 1 WARNING: grouped events cpus do not match, disabling group: anon group { slots, topdown-retiring, uncore_imc_free_running_0/dclk/ }
Performance counter stats for 'system wide':
346,110,588 slots 124,608,256 topdown-retiring 1,606,869,976 uncore_imc_free_running_0/dclk/
1.003877592 seconds time elapsed
Fixes: a9a1790247bdcf3b ("perf stat: Ensure group is defined on top of the same cpu mask") Signed-off-by: Kan Liang kan.liang@linux.intel.com Acked-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Jiri Olsa jolsa@redhat.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Stephane Eranian eranian@google.com Cc: Xing Zhengjun zhengjun.xing@linux.intel.com Link: https://lore.kernel.org/r/20220518143900.1493980-3-kan.liang@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-stat.c | 7 ++----- tools/perf/util/evlist.c | 6 +----- tools/perf/util/evsel.c | 13 +++++++++++-- tools/perf/util/evsel.h | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a96f106dc93a..f058e8cddfa8 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -271,11 +271,8 @@ static void evlist__check_cpu_maps(struct evlist *evlist) pr_warning(" %s: %s\n", evsel->name, buf); }
- for_each_group_evsel(pos, leader) { - evsel__set_leader(pos, pos); - pos->core.nr_members = 0; - } - evsel->core.leader->nr_members = 0; + for_each_group_evsel(pos, leader) + evsel__remove_from_group(pos, leader); } }
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4804b52f2946..3084ec7e9325 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1795,11 +1795,7 @@ struct evsel *evlist__reset_weak_group(struct evlist *evsel_list, struct evsel * * them. Some events, like Intel topdown, require being * in a group and so keep these in the group. */ - if (!evsel__must_be_in_group(c2) && c2 != leader) { - evsel__set_leader(c2, c2); - c2->core.nr_members = 0; - leader->core.nr_members--; - } + evsel__remove_from_group(c2, leader);
/* * Set this for all former members of the group diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b98882cbb286..deb428ee5e50 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -3083,7 +3083,16 @@ bool __weak arch_evsel__must_be_in_group(const struct evsel *evsel __maybe_unuse return false; }
-bool evsel__must_be_in_group(const struct evsel *evsel) +/* + * Remove an event from a given group (leader). + * Some events, e.g., perf metrics Topdown events, + * must always be grouped. Ignore the events. + */ +void evsel__remove_from_group(struct evsel *evsel, struct evsel *leader) { - return arch_evsel__must_be_in_group(evsel); + if (!arch_evsel__must_be_in_group(evsel) && evsel != leader) { + evsel__set_leader(evsel, evsel); + evsel->core.nr_members = 0; + leader->core.nr_members--; + } } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a36172ed4cf6..47f65f8e7c74 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -483,7 +483,7 @@ bool evsel__has_leader(struct evsel *evsel, struct evsel *leader); bool evsel__is_leader(struct evsel *evsel); void evsel__set_leader(struct evsel *evsel, struct evsel *leader); int evsel__source_count(const struct evsel *evsel); -bool evsel__must_be_in_group(const struct evsel *evsel); +void evsel__remove_from_group(struct evsel *evsel, struct evsel *leader);
bool arch_evsel__must_be_in_group(const struct evsel *evsel);
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 369e4ef87a8f5da7c348ec2c61ec5cd726e8337a ]
`pcc_mailbox_probe` doesn't initialize all memory that has been allocated before the first time that one of it's members `txdone_irq` may be accessed.
This leads to a an invalid load any time that this member is accessed: [ 2.429769] UBSAN: invalid-load in drivers/mailbox/pcc.c:684:22 [ 2.430324] UBSAN: invalid-load in drivers/mailbox/mailbox.c:486:12 [ 4.276782] UBSAN: invalid-load in drivers/acpi/cppc_acpi.c:314:45
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215587 Fixes: ce028702ddbc ("mailbox: pcc: Move bulk of PCCT parsing into pcc_mbox_probe") Signed-off-by: Mario Limonciello mario.limonciello@amd.com Reviewed-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/pcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index ed18936b8ce6..ebfa33a40fce 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -654,7 +654,7 @@ static int pcc_mbox_probe(struct platform_device *pdev) goto err; }
- pcc_mbox_ctrl = devm_kmalloc(dev, sizeof(*pcc_mbox_ctrl), GFP_KERNEL); + pcc_mbox_ctrl = devm_kzalloc(dev, sizeof(*pcc_mbox_ctrl), GFP_KERNEL); if (!pcc_mbox_ctrl) { rc = -ENOMEM; goto err;
From: Michael Ellerman mpe@ellerman.id.au
[ Upstream commit c4bce84d0bd3f396f702d69be2e92bbd8af97583 ]
We added checks to __pa() / __va() to ensure they're only called with appropriate addresses. But using BUG_ON() is too strong, it means virt_addr_valid() will BUG when DEBUG_VIRTUAL is enabled.
Instead switch them to warnings, arm64 does the same.
Fixes: 4dd7554a6456 ("powerpc/64: Add VIRTUAL_BUG_ON checks for __va and __pa addresses") Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220406145802.538416-5-mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/page.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index f2c5c26869f1..03ae544eb6cc 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -216,6 +216,9 @@ static inline bool pfn_valid(unsigned long pfn) #define __pa(x) ((phys_addr_t)(unsigned long)(x) - VIRT_PHYS_OFFSET) #else #ifdef CONFIG_PPC64 + +#define VIRTUAL_WARN_ON(x) WARN_ON(IS_ENABLED(CONFIG_DEBUG_VIRTUAL) && (x)) + /* * gcc miscompiles (unsigned long)(&static_var) - PAGE_OFFSET * with -mcmodel=medium, so we use & and | instead of - and + on 64-bit. @@ -223,13 +226,13 @@ static inline bool pfn_valid(unsigned long pfn) */ #define __va(x) \ ({ \ - VIRTUAL_BUG_ON((unsigned long)(x) >= PAGE_OFFSET); \ + VIRTUAL_WARN_ON((unsigned long)(x) >= PAGE_OFFSET); \ (void *)(unsigned long)((phys_addr_t)(x) | PAGE_OFFSET); \ })
#define __pa(x) \ ({ \ - VIRTUAL_BUG_ON((unsigned long)(x) < PAGE_OFFSET); \ + VIRTUAL_WARN_ON((unsigned long)(x) < PAGE_OFFSET); \ (unsigned long)(x) & 0x0fffffffffffffffUL; \ })
From: Russell Currey ruscur@russell.cc
[ Upstream commit 2efee6adb56159288bce9d1ab51fc9056d7007d4 ]
The device-tree properties no-need-l1d-flush-msr-pr-1-to-0 and no-need-l1d-flush-kernel-on-user-access are the equivalents of H_CPU_BEHAV_NO_L1D_FLUSH_ENTRY and H_CPU_BEHAV_NO_L1D_FLUSH_UACCESS from the H_GET_CPU_CHARACTERISTICS hcall on pseries respectively.
In commit d02fa40d759f ("powerpc/powernv: Remove POWER9 PVR version check for entry and uaccess flushes") the condition for disabling the L1D flush on kernel entry and user access was changed from any non-P9 CPU to only checking P7 and P8. Without the appropriate device-tree checks for newer processors on powernv, these flushes are unnecessarily enabled on those systems. This patch corrects this.
Fixes: d02fa40d759f ("powerpc/powernv: Remove POWER9 PVR version check for entry and uaccess flushes") Reported-by: Joel Stanley joel@jms.id.au Signed-off-by: Russell Currey ruscur@russell.cc Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220404101536.104794-1-ruscur@russell.cc Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/setup.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 105d889abd51..378f7e5f18d2 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -96,6 +96,12 @@ static void __init init_fw_feat_flags(struct device_node *np)
if (fw_feature_is("disabled", "needs-spec-barrier-for-bound-checks", np)) security_ftr_clear(SEC_FTR_BNDS_CHK_SPEC_BAR); + + if (fw_feature_is("enabled", "no-need-l1d-flush-msr-pr-1-to-0", np)) + security_ftr_clear(SEC_FTR_L1D_FLUSH_ENTRY); + + if (fw_feature_is("enabled", "no-need-l1d-flush-kernel-on-user-access", np)) + security_ftr_clear(SEC_FTR_L1D_FLUSH_UACCESS); }
static void __init pnv_setup_security_mitigations(void)
From: Russell Currey ruscur@russell.cc
[ Upstream commit d2a3c131981d4498571908df95c3c9393a00adf5 ]
The device-tree property no-need-store-drain-on-priv-state-switch is equivalent to H_CPU_BEHAV_NO_STF_BARRIER from the H_CPU_GET_CHARACTERISTICS hcall on pseries.
Since commit 84ed26fd00c5 ("powerpc/security: Add a security feature for STF barrier") powernv systems with this device-tree property have been enabling the STF barrier when they have no need for it. This patch fixes this by clearing the STF barrier feature on those systems.
Fixes: 84ed26fd00c5 ("powerpc/security: Add a security feature for STF barrier") Reported-by: Joel Stanley joel@jms.id.au Signed-off-by: Russell Currey ruscur@russell.cc Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220404101536.104794-2-ruscur@russell.cc Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/powernv/setup.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 378f7e5f18d2..824c3ad7a0fa 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -102,6 +102,9 @@ static void __init init_fw_feat_flags(struct device_node *np)
if (fw_feature_is("enabled", "no-need-l1d-flush-kernel-on-user-access", np)) security_ftr_clear(SEC_FTR_L1D_FLUSH_UACCESS); + + if (fw_feature_is("enabled", "no-need-store-drain-on-priv-state-switch", np)) + security_ftr_clear(SEC_FTR_STF_BARRIER); }
static void __init pnv_setup_security_mitigations(void)
From: Kajol Jain kjain@linux.ibm.com
[ Upstream commit 505d31650ba96d6032313480fdb566d289a4698c ]
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 8-18 bits for power10). When scheduling events as a group, all events in that group should match value in threshold bits. Otherwise event open for the sibling events should fail. But in the current code, incase thresh compare bits are not valid, we are not failing in group_constraint function which can result in invalid group schduling.
Fix the issue by returning -1 incase event is threshold and threshold compare value is not valid in group_constraint function.
Patch also fixes the p10_thresh_cmp_val function to return -1, incase threshold bits are not valid and changes corresponding check in is_thresh_cmp_valid function to return false only when the thresh_cmp value is less then 0.
Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). In below example, the scheduling of group events PM_MRK_INST_CMPL (3534401e0) and PM_THRESH_MET (34340101ec) is expected to fail as both event request different thresh control bits.
Result before the patch changes:
[command]# perf stat -e "{r35340401e0,r34340101ec}" sleep 1
Performance counter stats for 'sleep 1':
8,482 r35340401e0 0 r34340101ec
1.001474838 seconds time elapsed
0.001145000 seconds user 0.000000000 seconds sys
Result after the patch changes:
[command]# perf stat -e "{r35340401e0,r34340101ec}" sleep 1
Performance counter stats for 'sleep 1':
<not counted> r35340401e0 <not supported> r34340101ec
1.001499607 seconds time elapsed
0.000204000 seconds user 0.000760000 seconds sys
Fixes: 82d2c16b350f7 ("powerpc/perf: Adds support for programming of Thresholding in P10") Signed-off-by: Kajol Jain kjain@linux.ibm.com Reviewed-by: Athira Rajeev atrajeev@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220506061015.43916-1-kjain@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/perf/isa207-common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index a74d382ecbb7..013b06af6fe6 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -108,7 +108,7 @@ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) *mmcra |= MMCRA_SDAR_MODE_TLB; }
-static u64 p10_thresh_cmp_val(u64 value) +static int p10_thresh_cmp_val(u64 value) { int exp = 0; u64 result = value; @@ -139,7 +139,7 @@ static u64 p10_thresh_cmp_val(u64 value) * exponent is also zero. */ if (!(value & 0xC0) && exp) - result = 0; + result = -1; else result = (exp << 8) | value; } @@ -187,7 +187,7 @@ static bool is_thresh_cmp_valid(u64 event) unsigned int cmp, exp;
if (cpu_has_feature(CPU_FTR_ARCH_31)) - return p10_thresh_cmp_val(event) != 0; + return p10_thresh_cmp_val(event) >= 0;
/* * Check the mantissa upper two bits are not zero, unless the @@ -502,7 +502,8 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); mask |= p10_CNST_THRESH_CMP_MASK; value |= p10_CNST_THRESH_CMP_VAL(p10_thresh_cmp_val(event_config1)); - } + } else if (event_is_threshold(event)) + return -1; } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { mask |= CNST_THRESH_MASK;
From: Kajol Jain kjain@linux.ibm.com
[ Upstream commit ab0cc6bbf0c812731c703ec757fcc3fc3a457a34 ]
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 9-18 bits for power9). When scheduling events as a group, all events in that group should match value in threshold bits (like thresh compare, thresh control, thresh select). Otherwise event open for the sibling events should fail. But in the current code, incase thresh compare bits are not valid, we are not failing in group_constraint function which can result in invalid group schduling.
Fix the issue by returning -1 incase event is threshold and threshold compare value is not valid.
Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). In below example, the scheduling of group events PM_MRK_INST_CMPL (873534401e0) and PM_THRESH_MET (8734340101ec) is expected to fail as both event request different thresh control bits and invalid thresh compare value.
Result before the patch changes:
[command]# perf stat -e "{r8735340401e0,r8734340101ec}" sleep 1
Performance counter stats for 'sleep 1':
11,048 r8735340401e0 1,967 r8734340101ec
1.001354036 seconds time elapsed
0.001421000 seconds user 0.000000000 seconds sys
Result after the patch changes:
[command]# perf stat -e "{r8735340401e0,r8734340101ec}" sleep 1 Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (r8735340401e0). /bin/dmesg | grep -i perf may provide additional information.
Fixes: 78a16d9fc1206 ("powerpc/perf: Avoid FAB_*_MATCH checks for power9") Signed-off-by: Kajol Jain kjain@linux.ibm.com Reviewed-by: Athira Rajeev atrajeev@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220506061015.43916-2-kjain@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/perf/isa207-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 013b06af6fe6..bb5d64862bc9 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -508,7 +508,8 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { mask |= CNST_THRESH_MASK; value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); - } + } else if (event_is_threshold(event)) + return -1; } else { /* * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC,
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 9a9c5ff5fff87eb1a43db0d899473554e408fd7b ]
Fix build when RTC_LIB is not set/enabled. Eliminates these build errors:
m68k-linux-ld: drivers/macintosh/via-pmu.o: in function `pmu_set_rtc_time': drivers/macintosh/via-pmu.c:1769: undefined reference to `rtc_tm_to_time64' m68k-linux-ld: drivers/macintosh/via-cuda.o: in function `cuda_set_rtc_time': drivers/macintosh/via-cuda.c:797: undefined reference to `rtc_tm_to_time64'
Fixes: 0792a2c8e0bb ("macintosh: Use common code to access RTC") Reported-by: kernel test robot lkp@intel.com Suggested-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Randy Dunlap rdunlap@infradead.org Acked-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220410161035.592-1-rdunlap@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/macintosh/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 3942db15a2b8..539a2ed4e13d 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -44,6 +44,7 @@ config ADB_IOP config ADB_CUDA bool "Support for Cuda/Egret based Macs and PowerMacs" depends on (ADB || PPC_PMAC) && !PPC_PMAC64 + select RTC_LIB help This provides support for Cuda/Egret based Macintosh and Power Macintosh systems. This includes most m68k based Macs, @@ -57,6 +58,7 @@ config ADB_CUDA config ADB_PMU bool "Support for PMU based PowerMacs and PowerBooks" depends on PPC_PMAC || MAC + select RTC_LIB help On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the PMU is an embedded microprocessor whose primary function is to
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit 1d1fb9618bdd5a5fbf9a9eb75133da301d33721c ]
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: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller") Signed-off-by: Miaoqian Lin linmq006@gmail.com Reviewed-by: Cédric Le Goater clg@kaod.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220512090535.33397-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/sysdev/xive/spapr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 29456c255f9f..503f544d28e2 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -830,12 +830,12 @@ bool __init xive_spapr_init(void) /* Resource 1 is the OS ring TIMA */ if (of_address_to_resource(np, 1, &r)) { pr_err("Failed to get thread mgmnt area resource\n"); - return false; + goto err_put; } tima = ioremap(r.start, resource_size(&r)); if (!tima) { pr_err("Failed to map thread mgmnt area\n"); - return false; + goto err_put; }
if (!xive_get_max_prio(&max_prio)) @@ -871,6 +871,7 @@ bool __init xive_spapr_init(void) if (!xive_core_init(np, &xive_spapr_ops, tima, TM_QW1_OS, max_prio)) goto err_mem_free;
+ of_node_put(np); pr_info("Using %dkB queues\n", 1 << (xive_queue_shift - 10)); return true;
@@ -878,6 +879,8 @@ bool __init xive_spapr_init(void) xive_irq_bitmap_remove_all(); err_unmap: iounmap(tima); +err_put: + of_node_put(np); return false; }
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit fcee96924ba1596ca80a6770b2567ca546f9a482 ]
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: abc3aeae3aaa ("fsl-rio: Add two ports and rapidio message units support") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220512123724.62931-1-linmq006@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/sysdev/fsl_rio.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index ff7906b48ca1..1bfc9afa8a1a 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -505,8 +505,10 @@ int fsl_rio_setup(struct platform_device *dev) if (rc) { dev_err(&dev->dev, "Can't get %pOF property 'reg'\n", rmu_node); + of_node_put(rmu_node); goto err_rmu; } + of_node_put(rmu_node); rmu_regs_win = ioremap(rmu_regs.start, resource_size(&rmu_regs)); if (!rmu_regs_win) { dev_err(&dev->dev, "Unable to map rmu register window\n");
From: Vaibhav Jain vaibhav@linux.ibm.com
[ Upstream commit 0e0946e22f3665d27325d389ff45ade6e93f3678 ]
Right now 'char *' elements allocated for individual 'stat_id' in 'papr_scm_priv.nvdimm_events_map[]' during papr_scm_pmu_check_events(), get leaked in papr_scm_remove() and papr_scm_pmu_register(), papr_scm_pmu_check_events() error paths.
Also individual 'stat_id' arent NULL terminated 'char *' instead they are fixed 8-byte sized identifiers. However papr_scm_pmu_register() assumes it to be a NULL terminated 'char *' and at other places it assumes it to be a 'papr_scm_perf_stat.stat_id' sized string which is 8-byes in size.
Fix this by allocating the memory for papr_scm_priv.nvdimm_events_map to also include space for 'stat_id' entries. This is possible since number of available events/stat_ids are known upfront. This saves some memory and one extra level of indirection from 'nvdimm_events_map' to 'stat_id'. Also rest of the code can continue to call 'kfree(papr_scm_priv.nvdimm_events_map)' without needing to iterate over the array and free up individual elements.
Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support") Signed-off-by: Vaibhav Jain vaibhav@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20220511082637.646714-1-vaibhav@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/pseries/papr_scm.c | 54 ++++++++++------------- 1 file changed, 24 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 39962c905542..181b855b3050 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -125,8 +125,8 @@ struct papr_scm_priv { /* The bits which needs to be overridden */ u64 health_bitmap_inject_mask;
- /* array to have event_code and stat_id mappings */ - char **nvdimm_events_map; + /* array to have event_code and stat_id mappings */ + u8 *nvdimm_events_map; };
static int papr_scm_pmem_flush(struct nd_region *nd_region, @@ -370,7 +370,7 @@ static int papr_scm_pmu_get_value(struct perf_event *event, struct device *dev,
stat = &stats->scm_statistic[0]; memcpy(&stat->stat_id, - p->nvdimm_events_map[event->attr.config], + &p->nvdimm_events_map[event->attr.config * sizeof(stat->stat_id)], sizeof(stat->stat_id)); stat->stat_val = 0;
@@ -462,14 +462,13 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu { struct papr_scm_perf_stat *stat; struct papr_scm_perf_stats *stats; - int index, rc, count; u32 available_events; - - if (!p->stat_buffer_len) - return -ENOENT; + int index, rc = 0;
available_events = (p->stat_buffer_len - sizeof(struct papr_scm_perf_stats)) / sizeof(struct papr_scm_perf_stat); + if (available_events == 0) + return -EOPNOTSUPP;
/* Allocate the buffer for phyp where stats are written */ stats = kzalloc(p->stat_buffer_len, GFP_KERNEL); @@ -478,35 +477,30 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu return rc; }
- /* Allocate memory to nvdimm_event_map */ - p->nvdimm_events_map = kcalloc(available_events, sizeof(char *), GFP_KERNEL); - if (!p->nvdimm_events_map) { - rc = -ENOMEM; - goto out_stats; - } - /* Called to get list of events supported */ rc = drc_pmem_query_stats(p, stats, 0); if (rc) - goto out_nvdimm_events_map; - - for (index = 0, stat = stats->scm_statistic, count = 0; - index < available_events; index++, ++stat) { - p->nvdimm_events_map[count] = kmemdup_nul(stat->stat_id, 8, GFP_KERNEL); - if (!p->nvdimm_events_map[count]) { - rc = -ENOMEM; - goto out_nvdimm_events_map; - } + goto out;
- count++; + /* + * Allocate memory and populate nvdimm_event_map. + * Allocate an extra element for NULL entry + */ + p->nvdimm_events_map = kcalloc(available_events + 1, + sizeof(stat->stat_id), + GFP_KERNEL); + if (!p->nvdimm_events_map) { + rc = -ENOMEM; + goto out; } - p->nvdimm_events_map[count] = NULL; - kfree(stats); - return 0;
-out_nvdimm_events_map: - kfree(p->nvdimm_events_map); -out_stats: + /* Copy all stat_ids to event map */ + for (index = 0, stat = stats->scm_statistic; + index < available_events; index++, ++stat) { + memcpy(&p->nvdimm_events_map[index * sizeof(stat->stat_id)], + &stat->stat_id, sizeof(stat->stat_id)); + } +out: kfree(stats); return rc; }
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit ad91f66f5fa7c6f9346e721c3159ce818568028b ]
On fsl_book3e, rodata is set read-only at the same time as init text is set NX at the end of init. That's too early.
As both action are performed at the same time, delay both actions to the time rodata is expected to be made read-only.
It means we will have a small window with init mem freed but still executable. It shouldn't be an issue though, especially because the said memory gets poisoned and should therefore result to a bad instruction fault in case it gets executed.
mmu_mark_initmem_nx() is bailing out before doing anything when CONFIG_STRICT_KERNEL_RWX is not selected or rodata_enabled is false.
mmu_mark_rodata_ro() is called only when CONFIG_STRICT_KERNEL_RWX is selected and rodata_enabled is true so this is equivalent.
Move code from mmu_mark_initmem_nx() into mmu_mark_rodata_ro() and remove the call to strict_kernel_rwx_enabled() which is not needed anymore.
Fixes: d5970045cf9e ("powerpc/fsl_booke: Update of TLBCAMs after init") Reported-by: Guenter Roeck linux@roeck-us.net Tested-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/2e35f0fd649c83c5add17a99514ac040767be93a.165298104... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/nohash/fsl_book3e.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/mm/nohash/fsl_book3e.c b/arch/powerpc/mm/nohash/fsl_book3e.c index dfe715e0f70a..388f7c7dabd3 100644 --- a/arch/powerpc/mm/nohash/fsl_book3e.c +++ b/arch/powerpc/mm/nohash/fsl_book3e.c @@ -287,22 +287,19 @@ void __init adjust_total_lowmem(void)
#ifdef CONFIG_STRICT_KERNEL_RWX void mmu_mark_rodata_ro(void) -{ - /* Everything is done in mmu_mark_initmem_nx() */ -} -#endif - -void mmu_mark_initmem_nx(void) { unsigned long remapped;
- if (!strict_kernel_rwx_enabled()) - return; - remapped = map_mem_in_cams(__max_low_memory, CONFIG_LOWMEM_CAM_NUM, false, false);
WARN_ON(__max_low_memory != remapped); } +#endif + +void mmu_mark_initmem_nx(void) +{ + /* Everything is done in mmu_mark_rodata_ro() */ +}
void setup_initial_memory_limit(phys_addr_t first_memblock_base, phys_addr_t first_memblock_size)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit c680c6a814a2269427fad9ac417ab16756bceae9 ]
We should have 'n', then 'size', not the opposite. This is harmless because the 2 values are just multiplied, but having the correct order silence a (unpublished yet) smatch warning.
Fixes: cb8c474e79be ("gpio: sim: new testing module") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Bartosz Golaszewski brgl@bgdev.pl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpio-sim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 41c31b10ae84..98109839102f 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -314,8 +314,8 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)
for (i = 0; i < num_lines; i++) { attr_group = devm_kzalloc(dev, sizeof(*attr_group), GFP_KERNEL); - attrs = devm_kcalloc(dev, sizeof(*attrs), - GPIO_SIM_NUM_ATTRS, GFP_KERNEL); + attrs = devm_kcalloc(dev, GPIO_SIM_NUM_ATTRS, sizeof(*attrs), + GFP_KERNEL); val_attr = devm_kzalloc(dev, sizeof(*val_attr), GFP_KERNEL); pull_attr = devm_kzalloc(dev, sizeof(*pull_attr), GFP_KERNEL); if (!attr_group || !attrs || !val_attr || !pull_attr)
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 311242c7703df0da14c206260b7e855f69cb0264 ]
It will cause null-ptr-deref when using 'res', if platform_get_resource() returns NULL, so move using 'res' after devm_ioremap_resource() that will check it to avoid null-ptr-deref. And use devm_platform_get_and_ioremap_resource() to simplify code.
Fixes: b5e29aa880be ("mfd: davinci_voicecodec: Remove pointless #include") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20220426030857.3539336-1-yangyingliang@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/davinci_voicecodec.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index e5c8bc998eb4..965820481f1e 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c @@ -46,14 +46,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev) } clk_enable(davinci_vc->clk);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - fifo_base = (dma_addr_t)res->start; - davinci_vc->base = devm_ioremap_resource(&pdev->dev, res); + davinci_vc->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(davinci_vc->base)) { ret = PTR_ERR(davinci_vc->base); goto fail; } + fifo_base = (dma_addr_t)res->start;
davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev, davinci_vc->base,
From: Julian Schroeder jumaco@amazon.com
[ Upstream commit fd5e363eac77ef81542db77ddad0559fa0f9204e ]
Upon nfsd shutdown any pending DRC cache is freed. DRC cache use is tracked via a percpu counter. In the current code the percpu counter is destroyed before. If any pending cache is still present, percpu_counter_add is called with a percpu counter==NULL. This causes a kernel crash. The solution is to destroy the percpu counter after the cache is freed.
Fixes: e567b98ce9a4b (“nfsd: protect concurrent access to nfsd stats counters”) Signed-off-by: Julian Schroeder jumaco@amazon.com Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfsd/nfscache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 0b3f12aa37ff..7da88bdc0d6c 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -206,7 +206,6 @@ void nfsd_reply_cache_shutdown(struct nfsd_net *nn) struct svc_cacherep *rp; unsigned int i;
- nfsd_reply_cache_stats_destroy(nn); unregister_shrinker(&nn->nfsd_reply_cache_shrinker);
for (i = 0; i < nn->drc_hashsize; i++) { @@ -217,6 +216,7 @@ void nfsd_reply_cache_shutdown(struct nfsd_net *nn) rp, nn); } } + nfsd_reply_cache_stats_destroy(nn);
kvfree(nn->drc_hashtbl); nn->drc_hashtbl = NULL;
From: Björn Ardö bjorn.ardo@axis.com
[ Upstream commit bca1a1004615efe141fd78f360ecc48c60bc4ad5 ]
This reverts commit c7dacf5b0f32957b24ef29df1207dc2cd8307743, "mailbox: avoid timer start from callback"
The previous commit was reverted since it lead to a race that caused the hrtimer to not be started at all. The check for hrtimer_active() in msg_submit() will return true if the callback function txdone_hrtimer() is currently running. This function could return HRTIMER_NORESTART and then the timer will not be restarted, and also msg_submit() will not start the timer. This will lead to a message actually being submitted but no timer will start to check for its compleation.
The original fix that added checking hrtimer_active() was added to avoid a warning with hrtimer_forward. Looking in the kernel another solution to avoid this warning is to check hrtimer_is_queued() before calling hrtimer_forward_now() instead. This however requires a lock so the timer is not started by msg_submit() inbetween this check and the hrtimer_forward() call.
Fixes: c7dacf5b0f32 ("mailbox: avoid timer start from callback") Signed-off-by: Björn Ardö bjorn.ardo@axis.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mailbox.c | 19 +++++++++++++------ include/linux/mailbox_controller.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 3e7d4b20ab34..4229b9b5da98 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -82,11 +82,11 @@ static void msg_submit(struct mbox_chan *chan) exit: spin_unlock_irqrestore(&chan->lock, flags);
- /* kick start the timer immediately to avoid delays */ if (!err && (chan->txdone_method & TXDONE_BY_POLL)) { - /* but only if not already active */ - if (!hrtimer_active(&chan->mbox->poll_hrt)) - hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); + /* kick start the timer immediately to avoid delays */ + spin_lock_irqsave(&chan->mbox->poll_hrt_lock, flags); + hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); + spin_unlock_irqrestore(&chan->mbox->poll_hrt_lock, flags); } }
@@ -120,20 +120,26 @@ static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer) container_of(hrtimer, struct mbox_controller, poll_hrt); bool txdone, resched = false; int i; + unsigned long flags;
for (i = 0; i < mbox->num_chans; i++) { struct mbox_chan *chan = &mbox->chans[i];
if (chan->active_req && chan->cl) { - resched = true; txdone = chan->mbox->ops->last_tx_done(chan); if (txdone) tx_tick(chan, 0); + else + resched = true; } }
if (resched) { - hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); + spin_lock_irqsave(&mbox->poll_hrt_lock, flags); + if (!hrtimer_is_queued(hrtimer)) + hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); + spin_unlock_irqrestore(&mbox->poll_hrt_lock, flags); + return HRTIMER_RESTART; } return HRTIMER_NORESTART; @@ -500,6 +506,7 @@ int mbox_controller_register(struct mbox_controller *mbox) hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); mbox->poll_hrt.function = txdone_hrtimer; + spin_lock_init(&mbox->poll_hrt_lock); }
for (i = 0; i < mbox->num_chans; i++) { diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h index 36d6ce673503..6fee33cb52f5 100644 --- a/include/linux/mailbox_controller.h +++ b/include/linux/mailbox_controller.h @@ -83,6 +83,7 @@ struct mbox_controller { const struct of_phandle_args *sp); /* Internal to API */ struct hrtimer poll_hrt; + spinlock_t poll_hrt_lock; struct list_head node; };
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 7f60951ff4d1664dfa2c304d144d195989199ef3 ]
The commit in the Fixes tag has shuffled some code. Now 'mcg_num' is incremented before the kzalloc(). So if the memory allocation fails, this increment must be undone.
Fixes: a926a903b7dc ("RDMA/rxe: Do not call dev_mc_add/del() under a spinlock") Link: https://lore.kernel.org/r/fe137cd8b1f17593243aa73d59c18ea71ab9ee36.165322589... Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_mcast.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 873a9b10307c..86cc2e18a7fd 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -206,8 +206,10 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
/* speculative alloc of new mcg */ mcg = kzalloc(sizeof(*mcg), GFP_KERNEL); - if (!mcg) - return ERR_PTR(-ENOMEM); + if (!mcg) { + err = -ENOMEM; + goto err_dec; + }
spin_lock_bh(&rxe->mcg_lock); /* re-check to see if someone else just added it */
From: Douglas Miller doug.miller@cornelisnetworks.com
[ Upstream commit 05c03dfd09c069c4ffd783b47b2da5dcc9421f2c ]
If there is a failure during probe of hfi1 before the sdma_map_lock is initialized, the call to hfi1_free_devdata() will attempt to use a lock that has not been initialized. If the locking correctness validator is on then an INFO message and stack trace resembling the following may be seen:
INFO: trying to register non-static key. The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator. Call Trace: register_lock_class+0x11b/0x880 __lock_acquire+0xf3/0x7930 lock_acquire+0xff/0x2d0 _raw_spin_lock_irq+0x46/0x60 sdma_clean+0x42a/0x660 [hfi1] hfi1_free_devdata+0x3a7/0x420 [hfi1] init_one+0x867/0x11a0 [hfi1] pci_device_probe+0x40e/0x8d0
The use of sdma_map_lock in sdma_clean() is for freeing the sdma_map memory, and sdma_map is not allocated/initialized until after sdma_map_lock has been initialized. This code only needs to be run if sdma_map is not NULL, and so checking for that condition will avoid trying to use the lock before it is initialized.
Fixes: 473291b3ea0e ("IB/hfi1: Fix for early release of sdma context") Fixes: 7724105686e7 ("IB/hfi1: add driver files") Link: https://lore.kernel.org/r/20220520183701.48973.72434.stgit@awfm-01.cornelisn... Reported-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Douglas Miller doug.miller@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hfi1/sdma.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index f07d328689d3..a95b654f5254 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -1288,11 +1288,13 @@ void sdma_clean(struct hfi1_devdata *dd, size_t num_engines) kvfree(sde->tx_ring); sde->tx_ring = NULL; } - spin_lock_irq(&dd->sde_map_lock); - sdma_map_free(rcu_access_pointer(dd->sdma_map)); - RCU_INIT_POINTER(dd->sdma_map, NULL); - spin_unlock_irq(&dd->sde_map_lock); - synchronize_rcu(); + if (rcu_access_pointer(dd->sdma_map)) { + spin_lock_irq(&dd->sde_map_lock); + sdma_map_free(rcu_access_pointer(dd->sdma_map)); + RCU_INIT_POINTER(dd->sdma_map, NULL); + spin_unlock_irq(&dd->sde_map_lock); + synchronize_rcu(); + } kfree(dd->per_sdma); dd->per_sdma = NULL;
From: Hector Martin marcan@marcan.st
[ Upstream commit 83969805cc716a7dc6b296c3fb1bc7e5cd7ca321 ]
The irqchip ops are called with a raw spinlock held, so the subsequent regmap usage cannot use a plain spinlock.
spi-hid-apple-of spi0.0: spihid_apple_of_probe:74
============================= [ BUG: Invalid wait context ] 5.18.0-asahi-00176-g0fa3ab03bdea #1337 Not tainted ----------------------------- kworker/u20:3/86 is trying to lock: ffff8000166b5018 (pinctrl_apple_gpio:462:(®map_config)->lock){....}-{3:3}, at: regmap_lock_spinlock+0x18/0x30 other info that might help us debug this: context-{5:5} 7 locks held by kworker/u20:3/86: #0: ffff800017725d48 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work+0x1c8/0x670 #1: ffff80001e33bdd0 (deferred_probe_work){+.+.}-{0:0}, at: process_one_work+0x1c8/0x670 #2: ffff800017d629a0 (&dev->mutex){....}-{4:4}, at: __device_attach+0x30/0x17c #3: ffff80002414e618 (&ctlr->add_lock){+.+.}-{4:4}, at: spi_add_device+0x40/0x80 #4: ffff800024116990 (&dev->mutex){....}-{4:4}, at: __device_attach+0x30/0x17c #5: ffff800022d4be58 (request_class){+.+.}-{4:4}, at: __setup_irq+0xa8/0x720 #6: ffff800022d4bcc8 (lock_class){....}-{2:2}, at: __setup_irq+0xcc/0x720
Fixes: a0f160ffcb83 ("pinctrl: add pinctrl/GPIO driver for Apple SoCs") Signed-off-by: Hector Martin marcan@marcan.st Link: https://lore.kernel.org/r/20220524142206.18833-1-marcan@marcan.st Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-apple-gpio.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/pinctrl-apple-gpio.c b/drivers/pinctrl/pinctrl-apple-gpio.c index 72f4dd2466e1..6d1bff9588d9 100644 --- a/drivers/pinctrl/pinctrl-apple-gpio.c +++ b/drivers/pinctrl/pinctrl-apple-gpio.c @@ -72,6 +72,7 @@ struct regmap_config regmap_config = { .max_register = 512 * sizeof(u32), .num_reg_defaults_raw = 512, .use_relaxed_mmio = true, + .use_raw_spinlock = true, };
/* No locking needed to mask/unmask IRQs as the interrupt mode is per pin-register. */
From: Wanpeng Li wanpengli@tencent.com
[ Upstream commit 619f51da097952194a5d4d6a6c5f9ef3b9d1b25a ]
The timer is disarmed when switching between TSC deadline and other modes; however, the pending timer is still in-flight, so let's accurately remove any traces of the previous mode.
Fixes: 4427593258 ("KVM: x86: thoroughly disarm LAPIC timer around TSC deadline switch") Signed-off-by: Wanpeng Li wanpengli@tencent.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kvm/lapic.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 66b0eb0bda94..6268880c8eed 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1548,6 +1548,7 @@ static void cancel_apic_timer(struct kvm_lapic *apic) if (apic->lapic_timer.hv_timer_in_use) cancel_hv_timer(apic); preempt_enable(); + atomic_set(&apic->lapic_timer.pending, 0); }
static void apic_update_lvtt(struct kvm_lapic *apic)
From: Dmitry Torokhov dmitry.torokhov@gmail.com
[ Upstream commit 5f76955ab1e43e5795a9631b22ca4f918a0ae986 ]
The commit 26623eea0da3 attempted to deal with potential leak of runtime PM counter when opening the touchscreen device, however it ended up erroneously dropping the counter in the case of successfully enabling the device.
Let's address this by using pm_runtime_resume_and_get() and then executing pm_runtime_put_sync() only when we fail to send "sense on" command to the device.
Fixes: 26623eea0da3 ("Input: stmfts - fix reference leak in stmfts_input_open") Reported-by: Pavel Machek pavel@denx.de Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/touchscreen/stmfts.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index 72e0b767e1ba..c175d44c52f3 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -337,13 +337,15 @@ static int stmfts_input_open(struct input_dev *dev) struct stmfts_data *sdata = input_get_drvdata(dev); int err;
- err = pm_runtime_get_sync(&sdata->client->dev); - if (err < 0) - goto out; + err = pm_runtime_resume_and_get(&sdata->client->dev); + if (err) + return err;
err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON); - if (err) - goto out; + if (err) { + pm_runtime_put_sync(&sdata->client->dev); + return err; + }
mutex_lock(&sdata->mutex); sdata->running = true; @@ -366,9 +368,7 @@ static int stmfts_input_open(struct input_dev *dev) "failed to enable touchkey\n"); }
-out: - pm_runtime_put_noidle(&sdata->client->dev); - return err; + return 0; }
static void stmfts_input_close(struct input_dev *dev)
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 907ed123b9d096c73e9361f6cd4097f0691497f2 ]
This code does not call of_node_put(opp_np) if of_get_next_available_child() returns NULL. But it should.
Fixes: 45679f9b508f ("opp: Don't parse icc paths unnecessarily") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/opp/of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 440ab5a03df9..95b184fc3372 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -437,11 +437,11 @@ static int _bandwidth_supported(struct device *dev, struct opp_table *opp_table)
/* Checking only first OPP is sufficient */ np = of_get_next_available_child(opp_np, NULL); + of_node_put(opp_np); if (!np) { dev_err(dev, "OPP table empty\n"); return -EINVAL; } - of_node_put(opp_np);
prop = of_find_property(np, "opp-peak-kBps", NULL); of_node_put(np);
From: Jayesh Choudhary j-choudhary@ti.com
[ Upstream commit b21fe492a3a9831c315eb456cf5480c9490eaeef ]
Correct the RX PSIL thread for sa3ul.
Signed-off-by: Jayesh Choudhary j-choudhary@ti.com Fixes: 5ac6bfb587772 ("dmaengine: ti: k3-psil: Add AM62x PSIL and PDMA data") Link: https://lore.kernel.org/r/20220421065323.16378-1-j-choudhary@ti.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/ti/k3-psil-am62.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/ti/k3-psil-am62.c b/drivers/dma/ti/k3-psil-am62.c index d431e2033237..2b6fd6e37c61 100644 --- a/drivers/dma/ti/k3-psil-am62.c +++ b/drivers/dma/ti/k3-psil-am62.c @@ -70,10 +70,10 @@ /* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */ static struct psil_ep am62_src_ep_map[] = { /* SAUL */ - PSIL_SAUL(0x7500, 20, 35, 8, 35, 0), - PSIL_SAUL(0x7501, 21, 35, 8, 36, 0), - PSIL_SAUL(0x7502, 22, 43, 8, 43, 0), - PSIL_SAUL(0x7503, 23, 43, 8, 44, 0), + PSIL_SAUL(0x7504, 20, 35, 8, 35, 0), + PSIL_SAUL(0x7505, 21, 35, 8, 36, 0), + PSIL_SAUL(0x7506, 22, 43, 8, 43, 0), + PSIL_SAUL(0x7507, 23, 43, 8, 44, 0), /* PDMA_MAIN0 - SPI0-3 */ PSIL_PDMA_XY_PKT(0x4302), PSIL_PDMA_XY_PKT(0x4303),
From: Chao Yu chao@kernel.org
[ Upstream commit 12662d19467b391b5b509ac5e9ab4f583c6dde16 ]
As Wenqing reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215765
It will cause a kernel panic with steps: - mkdir mnt - mount tmp40.img mnt - ls mnt
folio_mark_dirty+0x33/0x50 f2fs_add_regular_entry+0x541/0xad0 [f2fs] f2fs_add_dentry+0x6c/0xb0 [f2fs] f2fs_do_add_link+0x182/0x230 [f2fs] __recover_dot_dentries+0x2d6/0x470 [f2fs] f2fs_lookup+0x5af/0x6a0 [f2fs] __lookup_slow+0xac/0x200 lookup_slow+0x45/0x70 walk_component+0x16c/0x250 path_lookupat+0x8b/0x1f0 filename_lookup+0xef/0x250 user_path_at_empty+0x46/0x70 vfs_statx+0x98/0x190 __do_sys_newlstat+0x41/0x90 __x64_sys_newlstat+0x1a/0x30 do_syscall_64+0x37/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
The root cause is for special file: e.g. character, block, fifo or socket file, f2fs doesn't assign address space operations pointer array for mapping->a_ops field, so, in a fuzzed image, if inline_dots flag was tagged in special file, during lookup(), when f2fs runs into __recover_dot_dentries(), it will cause NULL pointer access once f2fs_add_regular_entry() calls a_ops->set_dirty_page().
Fixes: 510022a85839 ("f2fs: add F2FS_INLINE_DOTS to recover missing dot dentries") Reported-by: Wenqing Liu wenqingliu0120@gmail.com Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/namei.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 5ed79b29999f..fffafd2aa438 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -461,6 +461,13 @@ static int __recover_dot_dentries(struct inode *dir, nid_t pino) return 0; }
+ if (!S_ISDIR(dir->i_mode)) { + f2fs_err(sbi, "inconsistent inode status, skip recovering inline_dots inode (ino:%lu, i_mode:%u, pino:%u)", + dir->i_ino, dir->i_mode, pino); + set_sbi_flag(sbi, SBI_NEED_FSCK); + return -ENOTDIR; + } + err = f2fs_dquot_initialize(dir); if (err) return err;
From: Jakob Koschel jakobkoschel@gmail.com
[ Upstream commit 2aaf51dd39afb6d01d13f1e6fe20b684733b37d5 ]
The list iterator variable will be a bogus pointer if no break was hit. Dereferencing it (cur->page in this case) could load an out-of-bounds/undefined value making it unsafe to use that in the comparision to determine if the specific element was found.
Since 'cur->page' *can* be out-ouf-bounds it cannot be guaranteed that by chance (or intention of an attacker) it matches the value of 'page' even though the correct element was not found.
This is fixed by using a separate list iterator variable for the loop and only setting the original variable if a suitable element was found. Then determing if the element was found is simply checking if the variable is set.
Fixes: 8c242db9b8c0 ("f2fs: fix stale ATOMIC_WRITTEN_PAGE private pointer") Signed-off-by: Jakob Koschel jakobkoschel@gmail.com Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index bd9731cdec56..9dd9f88b75e9 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -355,16 +355,19 @@ void f2fs_drop_inmem_page(struct inode *inode, struct page *page) struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct list_head *head = &fi->inmem_pages; struct inmem_pages *cur = NULL; + struct inmem_pages *tmp;
f2fs_bug_on(sbi, !page_private_atomic(page));
mutex_lock(&fi->inmem_lock); - list_for_each_entry(cur, head, list) { - if (cur->page == page) + list_for_each_entry(tmp, head, list) { + if (tmp->page == page) { + cur = tmp; break; + } }
- f2fs_bug_on(sbi, list_empty(head) || cur->page != page); + f2fs_bug_on(sbi, !cur); list_del(&cur->list); mutex_unlock(&fi->inmem_lock);
From: Guo Ren guoren@linux.alibaba.com
[ Upstream commit 72f045d19f25f19be6d7682d5b1d948e20580817 ]
Let's follow the origin patch's spirit:
The only difference between rv32_defconfig and defconfig is that rv32_defconfig has CONFIG_ARCH_RV32I=y.
This is helpful to compare rv64-compat-rv32 v.s. rv32-linux.
Fixes: 1b937e8faa87ccfb ("RISC-V: Add separate defconfig for 32bit systems") Signed-off-by: Guo Ren guoren@linux.alibaba.com Signed-off-by: Guo Ren guoren@kernel.org Reviewed-by: Arnd Bergmann arnd@arndb.de Tested-by: Heiko Stuebner heiko@sntech.de Link: https://lore.kernel.org/r/20220405071314.3225832-9-guoren@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/Makefile | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 7d81102cffd4..c6ca1b9cbf71 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -154,3 +154,7 @@ PHONY += rv64_randconfig rv64_randconfig: $(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/riscv/configs/64-bit.config \ -f $(srctree)/Makefile randconfig + +PHONY += rv32_defconfig +rv32_defconfig: + $(Q)$(MAKE) -f $(srctree)/Makefile defconfig 32-bit.config
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 121660bba631104154b7c15e88f208c48c8c3297 ]
Previously the AMD IOMMU would only enable SWIOTLB in certain circumstances: * IOMMU in passthrough mode * SME enabled
This logic however doesn't work when an untrusted device is plugged in that doesn't do page aligned DMA transactions. The expectation is that a bounce buffer is used for those transactions.
This fails like this:
swiotlb buffer is full (sz: 4096 bytes), total 0 (slots), used 0 (slots)
That happens because the bounce buffers have been allocated, followed by freed during startup but the bounce buffering code expects that all IOMMUs have left it enabled.
Remove the criteria to set up bounce buffers on AMD systems to ensure they're always available for supporting untrusted devices.
Fixes: 82612d66d51d ("iommu: Allow the dma-iommu api to use bounce buffers") Suggested-by: Christoph Hellwig hch@infradead.org Signed-off-by: Mario Limonciello mario.limonciello@amd.com Reviewed-by: Robin Murphy robin.murphy@arm.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220404204723.9767-2-mario.limonciello@amd.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd/iommu.c | 7 ------- 1 file changed, 7 deletions(-)
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index a1ada7bff44e..079694f894b8 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -1838,17 +1838,10 @@ void amd_iommu_domain_update(struct protection_domain *domain) amd_iommu_domain_flush_complete(domain); }
-static void __init amd_iommu_init_dma_ops(void) -{ - swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; -} - int __init amd_iommu_init_api(void) { int err;
- amd_iommu_init_dma_ops(); - err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops); if (err) return err;
From: Suravee Suthikulpanit suravee.suthikulpanit@amd.com
[ Upstream commit 5edde870d3283edeaa27ab62ac4fac5ee8cae35a ]
Smatch static checker warns: drivers/iommu/amd/iommu_v2.c:133 free_device_state() warn: sleeping in atomic context
Fixes by storing the list of struct device_state in a temporary list, and then free the memory after releasing the spinlock.
Reported-by: Dan Carpenter dan.carpenter@oracle.com Fixes: 9f968fc70d85 ("iommu/amd: Improve amd_iommu_v2_exit()") Signed-off-by: Suravee Suthikulpanit suravee.suthikulpanit@amd.com Link: https://lore.kernel.org/r/20220314024321.37411-1-suravee.suthikulpanit@amd.c... Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd/iommu_v2.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/amd/iommu_v2.c b/drivers/iommu/amd/iommu_v2.c index e56b137ceabd..afb3efd565b7 100644 --- a/drivers/iommu/amd/iommu_v2.c +++ b/drivers/iommu/amd/iommu_v2.c @@ -956,6 +956,7 @@ static void __exit amd_iommu_v2_exit(void) { struct device_state *dev_state, *next; unsigned long flags; + LIST_HEAD(freelist);
if (!amd_iommu_v2_supported()) return; @@ -975,11 +976,20 @@ static void __exit amd_iommu_v2_exit(void)
put_device_state(dev_state); list_del(&dev_state->list); - free_device_state(dev_state); + list_add_tail(&dev_state->list, &freelist); }
spin_unlock_irqrestore(&state_lock, flags);
+ /* + * Since free_device_state waits on the count to be zero, + * we need to free dev_state outside the spinlock. + */ + list_for_each_entry_safe(dev_state, next, &freelist, list) { + list_del(&dev_state->list); + free_device_state(dev_state); + } + destroy_workqueue(iommu_wq); }
From: Yong Wu yong.wu@mediatek.com
[ Upstream commit 645b87c190c959e9bb4f216b8c4add4ee880451a ]
In the commit 4f956c97d26b ("iommu/mediatek: Move domain_finalise into attach_device"), I overlooked the sharing pgtable case. After that commit, the "data" in the mtk_iommu_domain_finalise always is the data of the current IOMMU HW. Fix this for the sharing pgtable case.
Only affect mt2712 which is the only SoC that share pgtable currently.
Fixes: 4f956c97d26b ("iommu/mediatek: Move domain_finalise into attach_device") Signed-off-by: Yong Wu yong.wu@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/r/20220503071427.2285-5-yong.wu@mediatek.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/mtk_iommu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 6fd75a60abd6..95c82b8bcc35 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -446,7 +446,7 @@ static void mtk_iommu_domain_free(struct iommu_domain *domain) static int mtk_iommu_attach_device(struct iommu_domain *domain, struct device *dev) { - struct mtk_iommu_data *data = dev_iommu_priv_get(dev); + struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata; struct mtk_iommu_domain *dom = to_mtk_domain(domain); struct device *m4udev = data->dev; int ret, domid; @@ -456,7 +456,10 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, return domid;
if (!dom->data) { - if (mtk_iommu_domain_finalise(dom, data, domid)) + /* Data is in the frstdata in sharing pgtable case. */ + frstdata = mtk_iommu_get_m4u_data(); + + if (mtk_iommu_domain_finalise(dom, frstdata, domid)) return -ENODEV; dom->data = data; }
From: Yong Wu yong.wu@mediatek.com
[ Upstream commit ee55f75e4bcade81d253163641b63bef3e76cac4 ]
Lack the list_del in the mtk_iommu_remove, and remove bus_set_iommu(*, NULL) since there may be several iommu HWs. we can not bus_set_iommu null when one iommu driver unbind.
This could be a fix for mt2712 which support 2 M4U HW and list them.
Fixes: 7c3a2ec02806 ("iommu/mediatek: Merge 2 M4U HWs into one iommu domain") Signed-off-by: Yong Wu yong.wu@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/r/20220503071427.2285-6-yong.wu@mediatek.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/mtk_iommu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 95c82b8bcc35..e4b4ebbcb73f 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -955,8 +955,7 @@ static int mtk_iommu_remove(struct platform_device *pdev) iommu_device_sysfs_remove(&data->iommu); iommu_device_unregister(&data->iommu);
- if (iommu_present(&platform_bus_type)) - bus_set_iommu(&platform_bus_type, NULL); + list_del(&data->list);
clk_disable_unprepare(data->bclk); device_link_remove(data->smicomm_dev, &pdev->dev);
From: Yong Wu yong.wu@mediatek.com
[ Upstream commit 98df772bdd1c4ce717a26289efea15cbbe4b64ed ]
After the commit b34ea31fe013 ("iommu/mediatek: Always enable the clk on resume"), the iommu clock is controlled by the runtime callback. thus remove the clk control in the mtk_iommu_remove.
Otherwise, it will warning like:
echo 14018000.iommu > /sys/bus/platform/drivers/mtk-iommu/unbind
[ 51.413044] ------------[ cut here ]------------ [ 51.413648] vpp0_smi_iommu already disabled [ 51.414233] WARNING: CPU: 2 PID: 157 at */v5.15-rc1/kernel/mediatek/ drivers/clk/clk.c:952 clk_core_disable+0xb0/0xb8 [ 51.417174] Hardware name: MT8195V/C(ENG) (DT) [ 51.418635] pc : clk_core_disable+0xb0/0xb8 [ 51.419177] lr : clk_core_disable+0xb0/0xb8 ... [ 51.429375] Call trace: [ 51.429694] clk_core_disable+0xb0/0xb8 [ 51.430193] clk_core_disable_lock+0x24/0x40 [ 51.430745] clk_disable+0x20/0x30 [ 51.431189] mtk_iommu_remove+0x58/0x118 [ 51.431705] platform_remove+0x28/0x60 [ 51.432197] device_release_driver_internal+0x110/0x1f0 [ 51.432873] device_driver_detach+0x18/0x28 [ 51.433418] unbind_store+0xd4/0x108 [ 51.433886] drv_attr_store+0x24/0x38 [ 51.434363] sysfs_kf_write+0x40/0x58 [ 51.434843] kernfs_fop_write_iter+0x164/0x1e0
Fixes: b34ea31fe013 ("iommu/mediatek: Always enable the clk on resume") Reported-by: Hsin-Yi Wang hsinyi@chromium.org Signed-off-by: Yong Wu yong.wu@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/r/20220503071427.2285-7-yong.wu@mediatek.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/mtk_iommu.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index e4b4ebbcb73f..81b8db450eac 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -957,7 +957,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
list_del(&data->list);
- clk_disable_unprepare(data->bclk); device_link_remove(data->smicomm_dev, &pdev->dev); pm_runtime_disable(&pdev->dev); devm_free_irq(&pdev->dev, data->irq, data);
From: Yong Wu yong.wu@mediatek.com
[ Upstream commit 0e5a3f2e630b28e88e018655548212ef8eb4dfcb ]
Add a mutex to protect the data in the structure mtk_iommu_data, like ->"m4u_group" ->"m4u_dom". For the internal data, we should protect it in ourselves driver. Add a mutex for this. This could be a fix for the multi-groups support.
Fixes: c3045f39244e ("iommu/mediatek: Support for multi domains") Signed-off-by: Yunfei Wang yf.wang@mediatek.com Signed-off-by: Yong Wu yong.wu@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/r/20220503071427.2285-8-yong.wu@mediatek.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/mtk_iommu.c | 13 +++++++++++-- drivers/iommu/mtk_iommu.h | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 81b8db450eac..3413cc98e57e 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -464,15 +464,16 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, dom->data = data; }
+ mutex_lock(&data->mutex); if (!data->m4u_dom) { /* Initialize the M4U HW */ ret = pm_runtime_resume_and_get(m4udev); if (ret < 0) - return ret; + goto err_unlock;
ret = mtk_iommu_hw_init(data); if (ret) { pm_runtime_put(m4udev); - return ret; + goto err_unlock; } data->m4u_dom = dom; writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, @@ -480,9 +481,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
pm_runtime_put(m4udev); } + mutex_unlock(&data->mutex);
mtk_iommu_config(data, dev, true, domid); return 0; + +err_unlock: + mutex_unlock(&data->mutex); + return ret; }
static void mtk_iommu_detach_device(struct iommu_domain *domain, @@ -622,6 +628,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev) if (domid < 0) return ERR_PTR(domid);
+ mutex_lock(&data->mutex); group = data->m4u_group[domid]; if (!group) { group = iommu_group_alloc(); @@ -630,6 +637,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev) } else { iommu_group_ref_get(group); } + mutex_unlock(&data->mutex); return group; }
@@ -910,6 +918,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) }
platform_set_drvdata(pdev, data); + mutex_init(&data->mutex);
ret = iommu_device_sysfs_add(&data->iommu, dev, NULL, "mtk-iommu.%pa", &ioaddr); diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h index b742432220c5..5e8da947affc 100644 --- a/drivers/iommu/mtk_iommu.h +++ b/drivers/iommu/mtk_iommu.h @@ -80,6 +80,8 @@ struct mtk_iommu_data {
struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */
+ struct mutex mutex; /* Protect m4u_group/m4u_dom above */ + struct list_head list; struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; };
From: Michael Walle michael@walle.cc
[ Upstream commit 03fbb903c8bf7e53e101e8d9a7b261264317c411 ]
The supplied buffer might be on the stack and we get the following error message: [ 3.312058] at91_i2c e0070600.i2c: rejecting DMA map of vmalloc memory
Use i2c_{get,put}_dma_safe_msg_buf() to get a DMA-able memory region if necessary.
Fixes: 60937b2cdbf9 ("i2c: at91: add dma support") Signed-off-by: Michael Walle michael@walle.cc Reviewed-by: Codrin Ciubotariu codrin.ciubotariu@microchip.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-at91-master.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c index b0eae94909f4..5eca3b3bb609 100644 --- a/drivers/i2c/busses/i2c-at91-master.c +++ b/drivers/i2c/busses/i2c-at91-master.c @@ -656,6 +656,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) unsigned int_addr_flag = 0; struct i2c_msg *m_start = msg; bool is_read; + u8 *dma_buf;
dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
@@ -703,7 +704,17 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) dev->msg = m_start; dev->recv_len_abort = false;
+ if (dev->use_dma) { + dma_buf = i2c_get_dma_safe_msg_buf(m_start, 1); + if (!dma_buf) { + ret = -ENOMEM; + goto out; + } + dev->buf = dma_buf; + } + ret = at91_do_twi_transfer(dev); + i2c_put_dma_safe_msg_buf(dma_buf, m_start, !ret);
ret = (ret < 0) ? ret : num; out:
From: Jia-Wei Chang jia-wei.chang@mediatek.com
[ Upstream commit b7070187c81cb90549d7561c0e750d7c7eb751f4 ]
- Use module_init instead of device_initcall. - Add a function for module_exit to unregister driver.
Signed-off-by: Jia-Wei Chang jia-wei.chang@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/mediatek-cpufreq.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 866163883b48..9d7d9c8dc184 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -580,7 +580,13 @@ static int __init mtk_cpufreq_driver_init(void)
return 0; } -device_initcall(mtk_cpufreq_driver_init); +module_init(mtk_cpufreq_driver_init) + +static void __exit mtk_cpufreq_driver_exit(void) +{ + platform_driver_unregister(&mtk_cpufreq_platdrv); +} +module_exit(mtk_cpufreq_driver_exit)
MODULE_DESCRIPTION("MediaTek CPUFreq driver"); MODULE_AUTHOR("Pi-Cheng Chen pi-cheng.chen@linaro.org");
From: Rex-BC Chen rex-bc.chen@mediatek.com
[ Upstream commit f126fbadce92b92c3a7be41e4abc1fbae93ae2ef ]
We register the platform device when driver inits. However, we do not unregister it when driver exits.
To resolve this, we declare the platform data to be a global static variable and rename it to be "cpufreq_pdev". With this global variable, we can do platform_device_unregister() when driver exits.
Fixes: 501c574f4e3a ("cpufreq: mediatek: Add support of cpufreq to MT2701/MT7623 SoC") Signed-off-by: Rex-BC Chen rex-bc.chen@mediatek.com [ Viresh: Commit log and Subject ] Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/mediatek-cpufreq.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 9d7d9c8dc184..bfe240c726e3 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -44,6 +44,8 @@ struct mtk_cpu_dvfs_info { bool need_voltage_tracking; };
+static struct platform_device *cpufreq_pdev; + static LIST_HEAD(dvfs_info_list);
static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu) @@ -547,7 +549,6 @@ static int __init mtk_cpufreq_driver_init(void) { struct device_node *np; const struct of_device_id *match; - struct platform_device *pdev; int err;
np = of_find_node_by_path("/"); @@ -571,11 +572,11 @@ static int __init mtk_cpufreq_driver_init(void) * and the device registration codes are put here to handle defer * probing. */ - pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0); - if (IS_ERR(pdev)) { + cpufreq_pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0); + if (IS_ERR(cpufreq_pdev)) { pr_err("failed to register mtk-cpufreq platform device\n"); platform_driver_unregister(&mtk_cpufreq_platdrv); - return PTR_ERR(pdev); + return PTR_ERR(cpufreq_pdev); }
return 0; @@ -584,6 +585,7 @@ module_init(mtk_cpufreq_driver_init)
static void __exit mtk_cpufreq_driver_exit(void) { + platform_device_unregister(cpufreq_pdev); platform_driver_unregister(&mtk_cpufreq_platdrv); } module_exit(mtk_cpufreq_driver_exit)
From: Jean-Philippe Brucker jean-philippe@linaro.org
[ Upstream commit cbd23144f7662b00bcde32a938c4a4057e476d68 ]
We currently call arm64_mm_context_put() without holding a reference to the mm, which can result in use-after-free. Call mmgrab()/mmdrop() to ensure the mm only gets freed after we unpinned the ASID.
Fixes: 32784a9562fb ("iommu/arm-smmu-v3: Implement iommu_sva_bind/unbind()") Signed-off-by: Jean-Philippe Brucker jean-philippe@linaro.org Tested-by: Zhangfei Gao zhangfei.gao@linaro.org Link: https://lore.kernel.org/r/20220426130444.300556-1-jean-philippe@linaro.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c index c623dae1e115..1ef7bbb4acf3 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c @@ -6,6 +6,7 @@ #include <linux/mm.h> #include <linux/mmu_context.h> #include <linux/mmu_notifier.h> +#include <linux/sched/mm.h> #include <linux/slab.h>
#include "arm-smmu-v3.h" @@ -96,9 +97,14 @@ static struct arm_smmu_ctx_desc *arm_smmu_alloc_shared_cd(struct mm_struct *mm) struct arm_smmu_ctx_desc *cd; struct arm_smmu_ctx_desc *ret = NULL;
+ /* Don't free the mm until we release the ASID */ + mmgrab(mm); + asid = arm64_mm_context_get(mm); - if (!asid) - return ERR_PTR(-ESRCH); + if (!asid) { + err = -ESRCH; + goto out_drop_mm; + }
cd = kzalloc(sizeof(*cd), GFP_KERNEL); if (!cd) { @@ -165,6 +171,8 @@ static struct arm_smmu_ctx_desc *arm_smmu_alloc_shared_cd(struct mm_struct *mm) kfree(cd); out_put_context: arm64_mm_context_put(mm); +out_drop_mm: + mmdrop(mm); return err < 0 ? ERR_PTR(err) : ret; }
@@ -173,6 +181,7 @@ static void arm_smmu_free_shared_cd(struct arm_smmu_ctx_desc *cd) if (arm_smmu_free_asid(cd)) { /* Unpin ASID */ arm64_mm_context_put(cd->mm); + mmdrop(cd->mm); kfree(cd); } }
From: Guenter Roeck linux@roeck-us.net
[ Upstream commit abae018a03821be2b65c01ebe2bef06fd7d85a4c ]
Calling hwmon_device_register_with_info() with NULL dev and/or chip information parameters is an ABI abuse and not a real conversion to the new API. Also, the code creates sysfs attributes _after_ creating the hwmon device, which is racy and unsupported to start with. On top of that, the removal code tries to remove the name attribute which is owned by the hwmon core.
Use hwmon_device_register_with_groups() to register the hwmon device instead.
In the future, the hwmon subsystem will reject calls to hwmon_device_register_with_info with NULL dev or chip/info parameters. Without this patch, the hwmon device will fail to register.
Fixes: f59dc5119192 ("MIPS: Loongson: Fix boot warning about hwmon_device_register()") Cc: Zhi Li lizhi01@loongson.cn Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/mips/cpu_hwmon.c | 127 ++++++++++-------------------- 1 file changed, 41 insertions(+), 86 deletions(-)
diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c index 386389ffec41..d8c5f9195f85 100644 --- a/drivers/platform/mips/cpu_hwmon.c +++ b/drivers/platform/mips/cpu_hwmon.c @@ -55,55 +55,6 @@ int loongson3_cpu_temp(int cpu) static int nr_packages; static struct device *cpu_hwmon_dev;
-static SENSOR_DEVICE_ATTR(name, 0444, NULL, NULL, 0); - -static struct attribute *cpu_hwmon_attributes[] = { - &sensor_dev_attr_name.dev_attr.attr, - NULL -}; - -/* Hwmon device attribute group */ -static struct attribute_group cpu_hwmon_attribute_group = { - .attrs = cpu_hwmon_attributes, -}; - -static ssize_t get_cpu_temp(struct device *dev, - struct device_attribute *attr, char *buf); -static ssize_t cpu_temp_label(struct device *dev, - struct device_attribute *attr, char *buf); - -static SENSOR_DEVICE_ATTR(temp1_input, 0444, get_cpu_temp, NULL, 1); -static SENSOR_DEVICE_ATTR(temp1_label, 0444, cpu_temp_label, NULL, 1); -static SENSOR_DEVICE_ATTR(temp2_input, 0444, get_cpu_temp, NULL, 2); -static SENSOR_DEVICE_ATTR(temp2_label, 0444, cpu_temp_label, NULL, 2); -static SENSOR_DEVICE_ATTR(temp3_input, 0444, get_cpu_temp, NULL, 3); -static SENSOR_DEVICE_ATTR(temp3_label, 0444, cpu_temp_label, NULL, 3); -static SENSOR_DEVICE_ATTR(temp4_input, 0444, get_cpu_temp, NULL, 4); -static SENSOR_DEVICE_ATTR(temp4_label, 0444, cpu_temp_label, NULL, 4); - -static const struct attribute *hwmon_cputemp[4][3] = { - { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_label.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp2_label.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp3_label.dev_attr.attr, - NULL - }, - { - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp4_label.dev_attr.attr, - NULL - } -}; - static ssize_t cpu_temp_label(struct device *dev, struct device_attribute *attr, char *buf) { @@ -121,24 +72,47 @@ static ssize_t get_cpu_temp(struct device *dev, return sprintf(buf, "%d\n", value); }
-static int create_sysfs_cputemp_files(struct kobject *kobj) -{ - int i, ret = 0; - - for (i = 0; i < nr_packages; i++) - ret = sysfs_create_files(kobj, hwmon_cputemp[i]); +static SENSOR_DEVICE_ATTR(temp1_input, 0444, get_cpu_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp1_label, 0444, cpu_temp_label, NULL, 1); +static SENSOR_DEVICE_ATTR(temp2_input, 0444, get_cpu_temp, NULL, 2); +static SENSOR_DEVICE_ATTR(temp2_label, 0444, cpu_temp_label, NULL, 2); +static SENSOR_DEVICE_ATTR(temp3_input, 0444, get_cpu_temp, NULL, 3); +static SENSOR_DEVICE_ATTR(temp3_label, 0444, cpu_temp_label, NULL, 3); +static SENSOR_DEVICE_ATTR(temp4_input, 0444, get_cpu_temp, NULL, 4); +static SENSOR_DEVICE_ATTR(temp4_label, 0444, cpu_temp_label, NULL, 4);
- return ret; -} +static struct attribute *cpu_hwmon_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_label.dev_attr.attr, + &sensor_dev_attr_temp2_input.dev_attr.attr, + &sensor_dev_attr_temp2_label.dev_attr.attr, + &sensor_dev_attr_temp3_input.dev_attr.attr, + &sensor_dev_attr_temp3_label.dev_attr.attr, + &sensor_dev_attr_temp4_input.dev_attr.attr, + &sensor_dev_attr_temp4_label.dev_attr.attr, + NULL +};
-static void remove_sysfs_cputemp_files(struct kobject *kobj) +static umode_t cpu_hwmon_is_visible(struct kobject *kobj, + struct attribute *attr, int i) { - int i; + int id = i / 2;
- for (i = 0; i < nr_packages; i++) - sysfs_remove_files(kobj, hwmon_cputemp[i]); + if (id < nr_packages) + return attr->mode; + return 0; }
+static struct attribute_group cpu_hwmon_group = { + .attrs = cpu_hwmon_attributes, + .is_visible = cpu_hwmon_is_visible, +}; + +static const struct attribute_group *cpu_hwmon_groups[] = { + &cpu_hwmon_group, + NULL +}; + #define CPU_THERMAL_THRESHOLD 90000 static struct delayed_work thermal_work;
@@ -159,50 +133,31 @@ static void do_thermal_timer(struct work_struct *work)
static int __init loongson_hwmon_init(void) { - int ret; - pr_info("Loongson Hwmon Enter...\n");
if (cpu_has_csr()) csr_temp_enable = csr_readl(LOONGSON_CSR_FEATURES) & LOONGSON_CSRF_TEMP;
- cpu_hwmon_dev = hwmon_device_register_with_info(NULL, "cpu_hwmon", NULL, NULL, NULL); - if (IS_ERR(cpu_hwmon_dev)) { - ret = PTR_ERR(cpu_hwmon_dev); - pr_err("hwmon_device_register fail!\n"); - goto fail_hwmon_device_register; - } - nr_packages = loongson_sysconf.nr_cpus / loongson_sysconf.cores_per_package;
- ret = create_sysfs_cputemp_files(&cpu_hwmon_dev->kobj); - if (ret) { - pr_err("fail to create cpu temperature interface!\n"); - goto fail_create_sysfs_cputemp_files; + cpu_hwmon_dev = hwmon_device_register_with_groups(NULL, "cpu_hwmon", + NULL, cpu_hwmon_groups); + if (IS_ERR(cpu_hwmon_dev)) { + pr_err("hwmon_device_register fail!\n"); + return PTR_ERR(cpu_hwmon_dev); }
INIT_DEFERRABLE_WORK(&thermal_work, do_thermal_timer); schedule_delayed_work(&thermal_work, msecs_to_jiffies(20000));
- return ret; - -fail_create_sysfs_cputemp_files: - sysfs_remove_group(&cpu_hwmon_dev->kobj, - &cpu_hwmon_attribute_group); - hwmon_device_unregister(cpu_hwmon_dev); - -fail_hwmon_device_register: - return ret; + return 0; }
static void __exit loongson_hwmon_exit(void) { cancel_delayed_work_sync(&thermal_work); - remove_sysfs_cputemp_files(&cpu_hwmon_dev->kobj); - sysfs_remove_group(&cpu_hwmon_dev->kobj, - &cpu_hwmon_attribute_group); hwmon_device_unregister(cpu_hwmon_dev); }
From: Miles Chen miles.chen@mediatek.com
[ Upstream commit de78657e16f41417da9332f09c2d67d100096939 ]
When larbdev is NULL (in the case I hit, the node is incorrectly set iommus = <&iommu NUM>), it will cause device_link_add() fail and kernel crashes when we try to print dev_name(larbdev).
Let's fail the probe if a larbdev is NULL to avoid invalid inputs from dts.
It should work for normal correct setting and avoid the crash caused by my incorrect setting.
Error log: [ 18.189042][ T301] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050 ... [ 18.344519][ T301] pstate: a0400005 (NzCv daif +PAN -UAO) [ 18.345213][ T301] pc : mtk_iommu_probe_device+0xf8/0x118 [mtk_iommu] [ 18.346050][ T301] lr : mtk_iommu_probe_device+0xd0/0x118 [mtk_iommu] [ 18.346884][ T301] sp : ffffffc00a5635e0 [ 18.347392][ T301] x29: ffffffc00a5635e0 x28: ffffffd44a46c1d8 [ 18.348156][ T301] x27: ffffff80c39a8000 x26: ffffffd44a80cc38 [ 18.348917][ T301] x25: 0000000000000000 x24: ffffffd44a80cc38 [ 18.349677][ T301] x23: ffffffd44e4da4c6 x22: ffffffd44a80cc38 [ 18.350438][ T301] x21: ffffff80cecd1880 x20: 0000000000000000 [ 18.351198][ T301] x19: ffffff80c439f010 x18: ffffffc00a50d0c0 [ 18.351959][ T301] x17: ffffffffffffffff x16: 0000000000000004 [ 18.352719][ T301] x15: 0000000000000004 x14: ffffffd44eb5d420 [ 18.353480][ T301] x13: 0000000000000ad2 x12: 0000000000000003 [ 18.354241][ T301] x11: 00000000fffffad2 x10: c0000000fffffad2 [ 18.355003][ T301] x9 : a0d288d8d7142d00 x8 : a0d288d8d7142d00 [ 18.355763][ T301] x7 : ffffffd44c2bc640 x6 : 0000000000000000 [ 18.356524][ T301] x5 : 0000000000000080 x4 : 0000000000000001 [ 18.357284][ T301] x3 : 0000000000000000 x2 : 0000000000000005 [ 18.358045][ T301] x1 : 0000000000000000 x0 : 0000000000000000 [ 18.360208][ T301] Hardware name: MT6873 (DT) [ 18.360771][ T301] Call trace: [ 18.361168][ T301] dump_backtrace+0xf8/0x1f0 [ 18.361737][ T301] dump_stack_lvl+0xa8/0x11c [ 18.362305][ T301] dump_stack+0x1c/0x2c [ 18.362816][ T301] mrdump_common_die+0x184/0x40c [mrdump] [ 18.363575][ T301] ipanic_die+0x24/0x38 [mrdump] [ 18.364230][ T301] atomic_notifier_call_chain+0x128/0x2b8 [ 18.364937][ T301] die+0x16c/0x568 [ 18.365394][ T301] __do_kernel_fault+0x1e8/0x214 [ 18.365402][ T301] do_page_fault+0xb8/0x678 [ 18.366934][ T301] do_translation_fault+0x48/0x64 [ 18.368645][ T301] do_mem_abort+0x68/0x148 [ 18.368652][ T301] el1_abort+0x40/0x64 [ 18.368660][ T301] el1h_64_sync_handler+0x54/0x88 [ 18.368668][ T301] el1h_64_sync+0x68/0x6c [ 18.368673][ T301] mtk_iommu_probe_device+0xf8/0x118 [mtk_iommu] ...
Cc: Robin Murphy robin.murphy@arm.com Cc: Yong Wu yong.wu@mediatek.com Reported-by: kernel test robot lkp@intel.com Fixes: 635319a4a744 ("media: iommu/mediatek: Add device_link between the consumer and the larb devices") Signed-off-by: Miles Chen miles.chen@mediatek.com Reviewed-by: Yong Wu yong.wu@mediatek.com Reviewed-by: AngeloGioacchino Del Regno angelogioacchino.delregno@collabora.com Link: https://lore.kernel.org/r/20220505132731.21628-1-miles.chen@mediatek.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/mtk_iommu.c | 6 ++++++ drivers/iommu/mtk_iommu_v1.c | 7 +++++++ 2 files changed, 13 insertions(+)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 3413cc98e57e..1a31f4707222 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -581,6 +581,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) * All the ports in each a device should be in the same larbs. */ larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); + if (larbid >= MTK_LARB_NR_MAX) + return ERR_PTR(-EINVAL); + for (i = 1; i < fwspec->num_ids; i++) { larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]); if (larbid != larbidx) { @@ -590,6 +593,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) } } larbdev = data->larb_imu[larbid].dev; + if (!larbdev) + return ERR_PTR(-EINVAL); + link = device_link_add(dev, larbdev, DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); if (!link) diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index ecff800656e6..74563f689fbd 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -80,6 +80,7 @@ /* MTK generation one iommu HW only support 4K size mapping */ #define MT2701_IOMMU_PAGE_SHIFT 12 #define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) +#define MT2701_LARB_NR_MAX 3
/* * MTK m4u support 4GB iova address space, and only support 4K page @@ -457,6 +458,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
/* Link the consumer device with the smi-larb device(supplier) */ larbid = mt2701_m4u_to_larb(fwspec->ids[0]); + if (larbid >= MT2701_LARB_NR_MAX) + return ERR_PTR(-EINVAL); + for (idx = 1; idx < fwspec->num_ids; idx++) { larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]); if (larbid != larbidx) { @@ -467,6 +471,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) }
larbdev = data->larb_imu[larbid].dev; + if (!larbdev) + return ERR_PTR(-EINVAL); + link = device_link_add(dev, larbdev, DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); if (!link)
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 6977262c2eee111645668fe9e235ef2f5694abf7 ]
Clang warns:
drivers/i2c/busses/i2c-at91-master.c:707:6: warning: variable 'dma_buf' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] if (dev->use_dma) { ^~~~~~~~~~~~ drivers/i2c/busses/i2c-at91-master.c:717:27: note: uninitialized use occurs here i2c_put_dma_safe_msg_buf(dma_buf, m_start, !ret); ^~~~~~~
Initialize dma_buf to NULL, as i2c_put_dma_safe_msg_buf() is a no-op when the first argument is NULL, which will work for the !dev->use_dma case.
Fixes: 03fbb903c8bf ("i2c: at91: use dma safe buffers") Link: https://github.com/ClangBuiltLinux/linux/issues/1629 Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Michael Walle michael@walle.cc Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-at91-master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c index 5eca3b3bb609..c0c35785a0dc 100644 --- a/drivers/i2c/busses/i2c-at91-master.c +++ b/drivers/i2c/busses/i2c-at91-master.c @@ -656,7 +656,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) unsigned int_addr_flag = 0; struct i2c_msg *m_start = msg; bool is_read; - u8 *dma_buf; + u8 *dma_buf = NULL;
dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit aab08c1aac01097815fbcf10fce7021d2396a31f ]
If a call to alloc_chrdev_region() fails, the already allocated resources are leaking.
Add the needed error handling path to fix the leak.
Fixes: 42d279f9137a ("dmaengine: idxd: add char driver to expose submission portal to userland") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/1b5033dcc87b5f2a953c413f0306e883e6114542.165052159... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/idxd/cdev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index b9b2b4a4124e..033df43db0ce 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -369,10 +369,16 @@ int idxd_cdev_register(void) rc = alloc_chrdev_region(&ictx[i].devt, 0, MINORMASK, ictx[i].name); if (rc) - return rc; + goto err_free_chrdev_region; }
return 0; + +err_free_chrdev_region: + for (i--; i >= 0; i--) + unregister_chrdev_region(ictx[i].devt, MINORMASK); + + return rc; }
void idxd_cdev_remove(void)
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit cea9ba7239dcc84175041174304c6cdeae3226e5 ]
If the attempt to flush data was interrupted due to a local signal, then just requeue the writes back for I/O.
Fixes: 6fbda89b257f ("NFS: Replace custom error reporting mechanism with generic one") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/write.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index f00d45cf80ef..e437db1791ba 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1444,7 +1444,7 @@ static void nfs_async_write_error(struct list_head *head, int error) while (!list_empty(head)) { req = nfs_list_entry(head->next); nfs_list_remove_request(req); - if (nfs_error_is_fatal(error)) + if (nfs_error_is_fatal_on_server(error)) nfs_write_error(req, error); else nfs_redirty_request(req);
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 9641d9bc9b75f11f70646f5c6ee9f5f519a1012e ]
If the commit to disk is interrupted, we should still first check for filesystem errors so that we can report them in preference to the error due to the signal.
Fixes: 2197e9b06c22 ("NFS: Fix up fsync() when the server rebooted") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/file.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 150b7fa8f0a7..7c380e555224 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -204,15 +204,16 @@ static int nfs_file_fsync_commit(struct file *file, int datasync) { struct inode *inode = file_inode(file); - int ret; + int ret, ret2;
dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
nfs_inc_stats(inode, NFSIOS_VFSFSYNC); ret = nfs_commit_inode(inode, FLUSH_SYNC); - if (ret < 0) - return ret; - return file_check_and_advance_wb_err(file); + ret2 = file_check_and_advance_wb_err(file); + if (ret2 < 0) + return ret2; + return ret; }
int
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit e6005436f6cc9ed13288f936903f0151e5543485 ]
Any errors reported by the write() system call need to be cleared from the file descriptor's error tracking. The current call to nfs_wb_all() causes the error to be reported, but since it doesn't call file_check_and_advance_wb_err(), we can end up reporting the same error a second time when the application calls fsync().
Note that since Linux 4.13, the rule is that EIO may be reported for write(), but it must be reported by a subsequent fsync(), so let's just drop reporting it in write.
The check for nfs_ctx_key_to_expire() is just a duplicate to the one already in nfs_write_end(), so let's drop that too.
Reported-by: ChenXiaoSong chenxiaosong2@huawei.com Fixes: ce368536dd61 ("nfs: nfs_file_write() should check for writeback errors") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/file.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 7c380e555224..87e4cd5e8fe2 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -598,18 +598,6 @@ static const struct vm_operations_struct nfs_file_vm_ops = { .page_mkwrite = nfs_vm_page_mkwrite, };
-static int nfs_need_check_write(struct file *filp, struct inode *inode, - int error) -{ - struct nfs_open_context *ctx; - - ctx = nfs_file_open_context(filp); - if (nfs_error_is_fatal_on_server(error) || - nfs_ctx_key_to_expire(ctx, inode)) - return 1; - return 0; -} - ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; @@ -637,7 +625,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) if (iocb->ki_flags & IOCB_APPEND || iocb->ki_pos > i_size_read(inode)) { result = nfs_revalidate_file_size(inode, file); if (result) - goto out; + return result; }
nfs_clear_invalid_mapping(file->f_mapping); @@ -656,6 +644,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
written = result; iocb->ki_pos += written; + nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
if (mntflags & NFS_MOUNT_WRITE_EAGER) { result = filemap_fdatawrite_range(file->f_mapping, @@ -673,17 +662,22 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from) } result = generic_write_sync(iocb, written); if (result < 0) - goto out; + return result;
+out: /* Return error values */ error = filemap_check_wb_err(file->f_mapping, since); - if (nfs_need_check_write(file, inode, error)) { - int err = nfs_wb_all(inode); - if (err < 0) - result = err; + switch (error) { + default: + break; + case -EDQUOT: + case -EFBIG: + case -ENOSPC: + nfs_wb_all(inode); + error = file_check_and_advance_wb_err(file); + if (error < 0) + result = error; } - nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written); -out: return result;
out_swapfile:
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit d95b26650e86175e4a97698d89bc1626cd1df0c6 ]
If we do flush cached writebacks in nfs_write_end() due to the imminent expiration of an RPCSEC_GSS session, then we should defer reporting any resulting errors until the calls to file_check_and_advance_wb_err() in nfs_file_write() and nfs_file_fsync().
Fixes: 6fbda89b257f ("NFS: Replace custom error reporting mechanism with generic one") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/file.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 87e4cd5e8fe2..3f17748eaf29 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -386,11 +386,8 @@ static int nfs_write_end(struct file *file, struct address_space *mapping, return status; NFS_I(mapping->host)->write_io += copied;
- if (nfs_ctx_key_to_expire(ctx, mapping->host)) { - status = nfs_wb_all(mapping->host); - if (status < 0) - return status; - } + if (nfs_ctx_key_to_expire(ctx, mapping->host)) + nfs_wb_all(mapping->host);
return copied; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit c5e483b77cc2edb318da152abe07e33006b975fd ]
Since errors from nfs_pageio_complete() are already being reported through nfs_async_write_error(), we should not be returning them to the callers of do_writepages() as well. They will end up being reported through the generic mechanism instead.
Fixes: 6fbda89b257f ("NFS: Replace custom error reporting mechanism with generic one") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/write.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e437db1791ba..4925d11849cd 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -681,11 +681,7 @@ static int nfs_writepage_locked(struct page *page, err = nfs_do_writepage(page, wbc, &pgio); pgio.pg_error = 0; nfs_pageio_complete(&pgio); - if (err < 0) - return err; - if (nfs_error_is_fatal(pgio.pg_error)) - return pgio.pg_error; - return 0; + return err; }
int nfs_writepage(struct page *page, struct writeback_control *wbc) @@ -747,9 +743,6 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
if (err < 0) goto out_err; - err = pgio.pg_error; - if (nfs_error_is_fatal(err)) - goto out_err; return 0; out_err: return err;
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 3764a17e31d579cf9b4bd0a69894b577e8d75702 ]
Commit 587f03deb69b caused pnfs_update_layout() to stop returning ENOMEM when the memory allocation fails, and hence causes it to fall back to trying to do I/O through the MDS. There is no guarantee that this will fare any better. If we're failing the pNFS layout allocation, then we should just redirty the page and retry later.
Reported-by: Olga Kornievskaia aglo@umich.edu Fixes: 587f03deb69b ("pnfs: refactor send_layoutget") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/pnfs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 856c962273c7..68a87be3e6f9 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -2000,6 +2000,7 @@ pnfs_update_layout(struct inode *ino, lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags); if (lo == NULL) { spin_unlock(&ino->i_lock); + lseg = ERR_PTR(-ENOMEM); trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg, PNFS_UPDATE_LAYOUT_NOMEM); goto out; @@ -2128,6 +2129,7 @@ pnfs_update_layout(struct inode *ino,
lgp = pnfs_alloc_init_layoutget_args(ino, ctx, &stateid, &arg, gfp_flags); if (!lgp) { + lseg = ERR_PTR(-ENOMEM); trace_pnfs_update_layout(ino, pos, count, iomode, lo, NULL, PNFS_UPDATE_LAYOUT_NOMEM); nfs_layoutget_end(lo);
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit c6fd3511c3397dd9cbc6dc5d105bbedb69bf4061 ]
When we handle an error by redirtying the page, we're not corrupting the mapping, so we don't want the error to be recorded in the mapping. If the caller has specified a sync_mode of WB_SYNC_NONE, we can just return AOP_WRITEPAGE_ACTIVATE. However if we're dealing with WB_SYNC_ALL, we need to ensure that retries happen when the errors are non-fatal.
Reported-by: Olga Kornievskaia aglo@umich.edu Fixes: 8fc75bed96bb ("NFS: Fix up return value on fatal errors in nfs_page_async_flush()") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/write.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 4925d11849cd..2f41659e232e 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -603,8 +603,9 @@ static void nfs_write_error(struct nfs_page *req, int error) * Find an associated nfs write request, and prepare to flush it out * May return an error if the user signalled nfs_wait_on_request(). */ -static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, - struct page *page) +static int nfs_page_async_flush(struct page *page, + struct writeback_control *wbc, + struct nfs_pageio_descriptor *pgio) { struct nfs_page *req; int ret = 0; @@ -630,11 +631,11 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, /* * Remove the problematic req upon fatal errors on the server */ - if (nfs_error_is_fatal(ret)) { - if (nfs_error_is_fatal_on_server(ret)) - goto out_launder; - } else - ret = -EAGAIN; + if (nfs_error_is_fatal_on_server(ret)) + goto out_launder; + if (wbc->sync_mode == WB_SYNC_NONE) + ret = AOP_WRITEPAGE_ACTIVATE; + redirty_page_for_writepage(wbc, page); nfs_redirty_request(req); pgio->pg_error = 0; } else @@ -650,15 +651,8 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio) { - int ret; - nfs_pageio_cond_complete(pgio, page_index(page)); - ret = nfs_page_async_flush(pgio, page); - if (ret == -EAGAIN) { - redirty_page_for_writepage(wbc, page); - ret = AOP_WRITEPAGE_ACTIVATE; - } - return ret; + return nfs_page_async_flush(page, wbc, pgio); }
/* @@ -733,12 +727,15 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) priority = wb_priority(wbc); }
- nfs_pageio_init_write(&pgio, inode, priority, false, - &nfs_async_write_completion_ops); - pgio.pg_io_completion = ioc; - err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio); - pgio.pg_error = 0; - nfs_pageio_complete(&pgio); + do { + nfs_pageio_init_write(&pgio, inode, priority, false, + &nfs_async_write_completion_ops); + pgio.pg_io_completion = ioc; + err = write_cache_pages(mapping, wbc, nfs_writepages_callback, + &pgio); + pgio.pg_error = 0; + nfs_pageio_complete(&pgio); + } while (err < 0 && !nfs_error_is_fatal(err)); nfs_io_completion_put(ioc);
if (err < 0)
From: Dave Wysochanski dwysocha@redhat.com
[ Upstream commit 9c4a5c75a62e83963083efd4eea5d5bd1583193c ]
Pass updated i_size in fscache_unuse_cookie() when called from nfs_fscache_release_file(), which ensures the size of an fscache object gets written to the cache storage. Failing to do so results in unnessary reads from the NFS server, even when the data is cached, due to a cachefiles object coherency check failing with a trace similar to the following: cachefiles_coherency: o=0000000e BAD osiz B=afbb3 c=0
This problem can be reproduced as follows: #!/bin/bash v=4.2; NFS_SERVER=127.0.0.1 set -e; trap cleanup EXIT; rc=1 function cleanup { umount /mnt/nfs > /dev/null 2>&1 RC_STR="TEST PASS" [ $rc -eq 1 ] && RC_STR="TEST FAIL" echo "$RC_STR on $(uname -r) with NFSv$v and server $NFS_SERVER" } mount -o vers=$v,fsc $NFS_SERVER:/export /mnt/nfs rm -f /mnt/nfs/file1.bin > /dev/null 2>&1 dd if=/dev/zero of=/mnt/nfs/file1.bin bs=4096 count=1 > /dev/null 2>&1 echo 3 > /proc/sys/vm/drop_caches echo Read file 1st time from NFS server into fscache dd if=/mnt/nfs/file1.bin of=/dev/null > /dev/null 2>&1 umount /mnt/nfs && mount -o vers=$v,fsc $NFS_SERVER:/export /mnt/nfs echo 3 > /proc/sys/vm/drop_caches echo Read file 2nd time from fscache dd if=/mnt/nfs/file1.bin of=/dev/null > /dev/null 2>&1 echo Check mountstats for NFS read grep -q "READ: 0" /proc/self/mountstats # (1st number) == 0 [ $? -eq 0 ] && rc=0
Fixes: a6b5a28eb56c "nfs: Convert to new fscache volume/cookie API" Signed-off-by: Dave Wysochanski dwysocha@redhat.com Tested-by: Daire Byrne daire@dneg.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/fscache.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index f73c09a9cf0a..e861d7bae305 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -231,11 +231,10 @@ void nfs_fscache_release_file(struct inode *inode, struct file *filp) { struct nfs_fscache_inode_auxdata auxdata; struct fscache_cookie *cookie = nfs_i_fscache(inode); + loff_t i_size = i_size_read(inode);
- if (fscache_cookie_valid(cookie)) { - nfs_fscache_update_auxdata(&auxdata, inode); - fscache_unuse_cookie(cookie, &auxdata, NULL); - } + nfs_fscache_update_auxdata(&auxdata, inode); + fscache_unuse_cookie(cookie, &auxdata, &i_size); }
/*
From: Miaoqian Lin linmq006@gmail.com
[ Upstream commit b23789a59fa6f00e98a319291819f91fbba0deb8 ]
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: d10715be03bd ("video: ARM CLCD: Add DT support") Signed-off-by: Miaoqian Lin linmq006@gmail.com Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/amba-clcd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 9ec969e136bf..8080116aea84 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -758,12 +758,15 @@ static int clcdfb_of_vram_setup(struct clcd_fb *fb) return -ENODEV;
fb->fb.screen_base = of_iomap(memory, 0); - if (!fb->fb.screen_base) + if (!fb->fb.screen_base) { + of_node_put(memory); return -ENOMEM; + }
fb->fb.fix.smem_start = of_translate_address(memory, of_get_address(memory, 0, &size, NULL)); fb->fb.fix.smem_len = size; + of_node_put(memory);
return 0; }
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit 9d6a2d92e450926c483e45eaf426080a19219f4e ]
GISR1 was described in a not up-to-date documentation when the stm32-mdma driver has been developed. This register has not been added in reference manual of STM32 SoC with MDMA, which have only 32 MDMA channels. So remove it from stm32-mdma driver.
Fixes: a4ffb13c8946 ("dmaengine: Add STM32 MDMA driver") Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20220504155322.121431-2-amelie.delaunay@foss.st.co... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/stm32-mdma.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-)
diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index 6f57ff0e7b37..1e6bc22ddae9 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -34,7 +34,6 @@ #include "virt-dma.h"
#define STM32_MDMA_GISR0 0x0000 /* MDMA Int Status Reg 1 */ -#define STM32_MDMA_GISR1 0x0004 /* MDMA Int Status Reg 2 */
/* MDMA Channel x interrupt/status register */ #define STM32_MDMA_CISR(x) (0x40 + 0x40 * (x)) /* x = 0..62 */ @@ -168,7 +167,7 @@
#define STM32_MDMA_MAX_BUF_LEN 128 #define STM32_MDMA_MAX_BLOCK_LEN 65536 -#define STM32_MDMA_MAX_CHANNELS 63 +#define STM32_MDMA_MAX_CHANNELS 32 #define STM32_MDMA_MAX_REQUESTS 256 #define STM32_MDMA_MAX_BURST 128 #define STM32_MDMA_VERY_HIGH_PRIORITY 0x3 @@ -1322,21 +1321,11 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid)
/* Find out which channel generates the interrupt */ status = readl_relaxed(dmadev->base + STM32_MDMA_GISR0); - if (status) { - id = __ffs(status); - } else { - status = readl_relaxed(dmadev->base + STM32_MDMA_GISR1); - if (!status) { - dev_dbg(mdma2dev(dmadev), "spurious it\n"); - return IRQ_NONE; - } - id = __ffs(status); - /* - * As GISR0 provides status for channel id from 0 to 31, - * so GISR1 provides status for channel id from 32 to 62 - */ - id += 32; + if (!status) { + dev_dbg(mdma2dev(dmadev), "spurious it\n"); + return IRQ_NONE; } + id = __ffs(status);
chan = &dmadev->chan[id]; if (!chan) {
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit da3b8ddb464bd49b6248d00ca888ad751c9e44fd ]
The parameter to pass back to the handler function when irq has been requested is a struct stm32_mdma_device pointer, not a struct stm32_mdma_chan pointer. Even if chan is reinit later in the function, remove this wrong initialization.
Fixes: a4ffb13c8946 ("dmaengine: Add STM32 MDMA driver") Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20220504155322.121431-3-amelie.delaunay@foss.st.co... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/stm32-mdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index 1e6bc22ddae9..f8c8b9d76aad 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -1316,7 +1316,7 @@ static void stm32_mdma_xfer_end(struct stm32_mdma_chan *chan) static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) { struct stm32_mdma_device *dmadev = devid; - struct stm32_mdma_chan *chan = devid; + struct stm32_mdma_chan *chan; u32 reg, id, ccr, ien, status;
/* Find out which channel generates the interrupt */
From: Joerg Roedel jroedel@suse.de
[ Upstream commit 42bb5aa043382f09bef2cc33b8431be867c70f8e ]
On some systems it can take a long time for the hardware to enable the GA log of the AMD IOMMU. The current wait time is only 0.1ms, but testing showed that it can take up to 14ms for the GA log to enter running state after it has been enabled.
Sometimes the long delay happens when booting the system, sometimes only on resume. Adjust the timeout accordingly to not print a warning when hardware takes a longer than usual.
There has already been an attempt to fix this with commit
9b45a7738eec ("iommu/amd: Fix loop timeout issue in iommu_ga_log_enable()")
But that commit was based on some wrong math and did not fix the issue in all cases.
Cc: "D. Ziegfeld" dzigg@posteo.de Cc: Jörg-Volker Peetz jvpeetz@web.de Fixes: 8bda0cfbdc1a ("iommu/amd: Detect and initialize guest vAPIC log") Signed-off-by: Joerg Roedel jroedel@suse.de Link: https://lore.kernel.org/r/20220520102214.12563-1-joro@8bytes.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index b4a798c7b347..d8060503ba51 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -84,7 +84,7 @@ #define ACPI_DEVFLAG_LINT1 0x80 #define ACPI_DEVFLAG_ATSDIS 0x10000000
-#define LOOP_TIMEOUT 100000 +#define LOOP_TIMEOUT 2000000 /* * ACPI table definitions *
From: Tali Perry tali.perry1@gmail.com
[ Upstream commit 288b204492fddf28889cea6dc95a23976632c7a0 ]
Use adap.timeout for timeout calculation instead of hard-coded value of 35ms.
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 Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-npcm7xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 71aad029425d..635ebba52b08 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -2047,7 +2047,7 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, u16 nwrite, nread; u8 *write_data, *read_data; u8 slave_addr; - int timeout; + unsigned long timeout; int ret = 0; bool read_block = false; bool read_PEC = false; @@ -2099,13 +2099,13 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, * 9: bits per transaction (including the ack/nack) */ timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite); - timeout = max(msecs_to_jiffies(35), usecs_to_jiffies(timeout_usec)); + timeout = max_t(unsigned long, bus->adap.timeout, usecs_to_jiffies(timeout_usec)); if (nwrite >= 32 * 1024 || nread >= 32 * 1024) { dev_err(bus->dev, "i2c%d buffer too big\n", bus->num); return -EINVAL; }
- time_left = jiffies + msecs_to_jiffies(DEFAULT_STALL_COUNT) + 1; + time_left = jiffies + timeout + 1; do { /* * we must clear slave address immediately when the bus is not @@ -2269,7 +2269,7 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) adap = &bus->adap; adap->owner = THIS_MODULE; adap->retries = 3; - adap->timeout = HZ; + adap->timeout = msecs_to_jiffies(35); adap->algo = &npcm_i2c_algo; adap->quirks = &npcm_i2c_quirks; adap->algo_data = bus;
From: Tyrone Ting kfting@nuvoton.com
[ Upstream commit ea9f8426d17620214ee345ffb77ee6cc196ff14f ]
The SMBnCTL3 register is 8-bit wide and the 32-bit access was always incorrect, but simply didn't cause a visible error on the 32-bit machine.
On the 64-bit machine, the kernel message reports that ESR value is 0x96000021. Checking Arm Architecture Reference Manual Armv8 suggests that it's the alignment fault.
SMBnCTL3's address is 0xE.
Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver") Signed-off-by: Tyrone Ting kfting@nuvoton.com Reviewed-by: Jonathan Neuschäfer j.neuschaefer@gmx.net Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-npcm7xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 635ebba52b08..2e466cd6cdfc 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -359,14 +359,14 @@ static int npcm_i2c_get_SCL(struct i2c_adapter *_adap) { struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
- return !!(I2CCTL3_SCL_LVL & ioread32(bus->reg + NPCM_I2CCTL3)); + return !!(I2CCTL3_SCL_LVL & ioread8(bus->reg + NPCM_I2CCTL3)); }
static int npcm_i2c_get_SDA(struct i2c_adapter *_adap) { struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap);
- return !!(I2CCTL3_SDA_LVL & ioread32(bus->reg + NPCM_I2CCTL3)); + return !!(I2CCTL3_SDA_LVL & ioread8(bus->reg + NPCM_I2CCTL3)); }
static inline u16 npcm_i2c_get_index(struct npcm_i2c *bus)
From: Tali Perry tali.perry1@gmail.com
[ Upstream commit e5222d408de2a88e6b206c38217b48d092184553 ]
On some platforms in rare cases (1 to 100,000 transactions), the i2c gets a spurious interrupt which means that we enter an interrupt but in the interrupt handler we don't find any status bit that points to the reason we got this interrupt.
This may be a case of a rare HW issue or signal integrity issue that is still under investigation.
In order to overcome this we are doing the following: 1. Disable incoming interrupts in master mode only when slave mode is not enabled. 2. Clear end of busy (EOB) after every interrupt. 3. Clear other status bits (just in case since we found them cleared) 4. Return correct status during the interrupt that will finish the transaction.
On next xmit transaction if the bus is still busy the master will issue a recovery process before issuing the new transaction.
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 Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-npcm7xx.c | 91 ++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 29 deletions(-)
diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 2e466cd6cdfc..c638f2efb97c 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -563,6 +563,15 @@ static inline void npcm_i2c_nack(struct npcm_i2c *bus) iowrite8(val, bus->reg + NPCM_I2CCTL1); }
+static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus) +{ + u8 val; + + /* Clear NEGACK, STASTR and BER bits */ + val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR; + iowrite8(val, bus->reg + NPCM_I2CST); +} + #if IS_ENABLED(CONFIG_I2C_SLAVE) static void npcm_i2c_slave_int_enable(struct npcm_i2c *bus, bool enable) { @@ -642,8 +651,8 @@ static void npcm_i2c_reset(struct npcm_i2c *bus) iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST); iowrite8(0xFF, bus->reg + NPCM_I2CST);
- /* Clear EOB bit */ - iowrite8(NPCM_I2CCST3_EO_BUSY, bus->reg + NPCM_I2CCST3); + /* Clear and disable EOB */ + npcm_i2c_eob_int(bus, false);
/* Clear all fifo bits: */ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS); @@ -655,6 +664,9 @@ static void npcm_i2c_reset(struct npcm_i2c *bus) } #endif
+ /* clear status bits for spurious interrupts */ + npcm_i2c_clear_master_status(bus); + bus->state = I2C_IDLE; }
@@ -815,15 +827,6 @@ static void npcm_i2c_read_fifo(struct npcm_i2c *bus, u8 bytes_in_fifo) } }
-static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus) -{ - u8 val; - - /* Clear NEGACK, STASTR and BER bits */ - val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR; - iowrite8(val, bus->reg + NPCM_I2CST); -} - static void npcm_i2c_master_abort(struct npcm_i2c *bus) { /* Only current master is allowed to issue a stop condition */ @@ -1231,7 +1234,16 @@ static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus) ret = IRQ_HANDLED; } /* SDAST */
- return ret; + /* + * if irq is not one of the above, make sure EOB is disabled and all + * status bits are cleared. + */ + if (ret == IRQ_NONE) { + npcm_i2c_eob_int(bus, false); + npcm_i2c_clear_master_status(bus); + } + + return IRQ_HANDLED; }
static int npcm_i2c_reg_slave(struct i2c_client *client) @@ -1467,6 +1479,9 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus) npcm_i2c_eob_int(bus, false); npcm_i2c_master_stop(bus);
+ /* Clear SDA Status bit (by reading dummy byte) */ + npcm_i2c_rd_byte(bus); + /* * The bus is released from stall only after the SW clears * NEGACK bit. Then a Stop condition is sent. @@ -1474,6 +1489,8 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus) npcm_i2c_clear_master_status(bus); readx_poll_timeout_atomic(ioread8, bus->reg + NPCM_I2CCST, val, !(val & NPCM_I2CCST_BUSY), 10, 200); + /* verify no status bits are still set after bus is released */ + npcm_i2c_clear_master_status(bus); } bus->state = I2C_IDLE;
@@ -1672,10 +1689,10 @@ static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap) int iter = 27;
if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1)) { - dev_dbg(bus->dev, "bus%d recovery skipped, bus not stuck", - bus->num); + dev_dbg(bus->dev, "bus%d-0x%x recovery skipped, bus not stuck", + bus->num, bus->dest_addr); npcm_i2c_reset(bus); - return status; + return 0; }
npcm_i2c_int_enable(bus, false); @@ -1909,6 +1926,7 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode, bus_freq_hz < I2C_FREQ_MIN_HZ || bus_freq_hz > I2C_FREQ_MAX_HZ) return -EINVAL;
+ npcm_i2c_int_enable(bus, false); npcm_i2c_disable(bus);
/* Configure FIFO mode : */ @@ -1937,10 +1955,17 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode, val = (val | NPCM_I2CCTL1_NMINTE) & ~NPCM_I2CCTL1_RWS; iowrite8(val, bus->reg + NPCM_I2CCTL1);
- npcm_i2c_int_enable(bus, true); - npcm_i2c_reset(bus);
+ /* check HW is OK: SDA and SCL should be high at this point. */ + if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) { + dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num); + dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap), + npcm_i2c_get_SCL(&bus->adap)); + return -ENXIO; + } + + npcm_i2c_int_enable(bus, true); return 0; }
@@ -1988,10 +2013,14 @@ static irqreturn_t npcm_i2c_bus_irq(int irq, void *dev_id) #if IS_ENABLED(CONFIG_I2C_SLAVE) if (bus->slave) { bus->master_or_slave = I2C_SLAVE; - return npcm_i2c_int_slave_handler(bus); + if (npcm_i2c_int_slave_handler(bus)) + return IRQ_HANDLED; } #endif - return IRQ_NONE; + /* clear status bits for spurious interrupts */ + npcm_i2c_clear_master_status(bus); + + return IRQ_HANDLED; }
static bool npcm_i2c_master_start_xmit(struct npcm_i2c *bus, @@ -2048,7 +2077,6 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, u8 *write_data, *read_data; u8 slave_addr; unsigned long timeout; - int ret = 0; bool read_block = false; bool read_PEC = false; u8 bus_busy; @@ -2138,12 +2166,12 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, bus->read_block_use = read_block;
reinit_completion(&bus->cmd_complete); - if (!npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread, - write_data, read_data, read_PEC, - read_block)) - ret = -EBUSY;
- if (ret != -EBUSY) { + npcm_i2c_int_enable(bus, true); + + if (npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread, + write_data, read_data, read_PEC, + read_block)) { time_left = wait_for_completion_timeout(&bus->cmd_complete, timeout);
@@ -2157,26 +2185,31 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, } } } - ret = bus->cmd_err;
/* if there was BER, check if need to recover the bus: */ if (bus->cmd_err == -EAGAIN) - ret = i2c_recover_bus(adap); + bus->cmd_err = i2c_recover_bus(adap);
/* * After any type of error, check if LAST bit is still set, * due to a HW issue. * It cannot be cleared without resetting the module. */ - if (bus->cmd_err && - (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL))) + else if (bus->cmd_err && + (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL))) npcm_i2c_reset(bus);
+ /* after any xfer, successful or not, stall and EOB must be disabled */ + npcm_i2c_stall_after_start(bus, false); + npcm_i2c_eob_int(bus, false); + #if IS_ENABLED(CONFIG_I2C_SLAVE) /* reenable slave if it was enabled */ if (bus->slave) iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN, bus->reg + NPCM_I2CADDR1); +#else + npcm_i2c_int_enable(bus, false); #endif return bus->cmd_err; }
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
[ Upstream commit 3fe2ec59db1a7569e18594b9c0cf1f4f1afd498e ]
We have to take care of ID_P_PM_BLOCKED when bailing out during probe.
Fixes: 7ee24eb508d6 ("i2c: rcar: disable PM in multi-master mode") Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-rcar.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 0db3d7559066..0064c632af5c 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -1063,8 +1063,10 @@ static int rcar_i2c_probe(struct platform_device *pdev) pm_runtime_enable(dev); pm_runtime_get_sync(dev); ret = rcar_i2c_clock_calculate(priv); - if (ret < 0) - goto out_pm_put; + if (ret < 0) { + pm_runtime_put(dev); + goto out_pm_disable; + }
rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
@@ -1093,19 +1095,19 @@ static int rcar_i2c_probe(struct platform_device *pdev)
ret = platform_get_irq(pdev, 0); if (ret < 0) - goto out_pm_disable; + goto out_pm_put; priv->irq = ret; ret = devm_request_irq(dev, priv->irq, irqhandler, irqflags, dev_name(dev), priv); if (ret < 0) { dev_err(dev, "cannot get irq %d\n", priv->irq); - goto out_pm_disable; + goto out_pm_put; }
platform_set_drvdata(pdev, priv);
ret = i2c_add_numbered_adapter(adap); if (ret < 0) - goto out_pm_disable; + goto out_pm_put;
if (priv->flags & ID_P_HOST_NOTIFY) { priv->host_notify_client = i2c_new_slave_host_notify_device(adap); @@ -1122,7 +1124,8 @@ static int rcar_i2c_probe(struct platform_device *pdev) out_del_device: i2c_del_adapter(&priv->adap); out_pm_put: - pm_runtime_put(dev); + if (priv->flags & ID_P_PM_BLOCKED) + pm_runtime_put(dev); out_pm_disable: pm_runtime_disable(dev); return ret;
From: Li Huafei lihuafei1@huawei.com
[ Upstream commit e35c2d8e22745751cf304ec3fe39616643db2e0a ]
The direct trampoline and graph coexistence test sets global_ops to trace only 'trace_selftest_dynamic_test_func', but does not reset it after the test is completed, resulting in the function filter being set already after the system starts. Although it can be reset through the tracefs interface, it is more or less confusing to the user, and we should reset it to trace all functions after the trampoline/graph test completes.
Link: https://lkml.kernel.org/r/20220427034119.24668-1-lihuafei1@huawei.com Link: https://lore.kernel.org/all/20220418073958.104029-1-lihuafei1@huawei.com/
Fixes: 130c08065848 ("tracing: Add trampoline/graph selftest") Signed-off-by: Li Huafei lihuafei1@huawei.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/trace_selftest.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index abcadbe933bb..a2d301f58ced 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -895,6 +895,9 @@ trace_selftest_startup_function_graph(struct tracer *trace, ret = -1; goto out; } + + /* Enable tracing on all functions again */ + ftrace_set_global_filter(NULL, 0, 1); #endif
/* Don't test dynamic tracing, the function tracer already did */
From: Palmer Dabbelt palmer@rivosinc.com
[ Upstream commit e7681beba992d5a196476d5d79dfcb48f2a2c477 ]
This was broken by the original refactoring (as the XIP definitions depend on <asm/pgtable.h>) and then more broken by the merge (as I accidentally took the old version). This fixes both breakages, while also pulling this out of <asm/asm.h> to avoid polluting most assembly files with the XIP fixups.
Fixes: bee7fbc38579 ("RISC-V CPU Idle Support") Fixes: 63b13e64a829 ("RISC-V: Add arch functions for non-retentive suspend entry/exit") Link: https://lore.kernel.org/r/20220420184056.7886-4-palmer@rivosinc.com Reviewed-by: Guo Ren guoren@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/asm.h | 26 ------------------------- arch/riscv/include/asm/xip_fixup.h | 31 ++++++++++++++++++++++++++++++ arch/riscv/kernel/head.S | 1 + arch/riscv/kernel/suspend_entry.S | 1 + 4 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 arch/riscv/include/asm/xip_fixup.h
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h index 8c2549b16ac0..618d7c5af1a2 100644 --- a/arch/riscv/include/asm/asm.h +++ b/arch/riscv/include/asm/asm.h @@ -67,30 +67,4 @@ #error "Unexpected __SIZEOF_SHORT__" #endif
-#ifdef __ASSEMBLY__ - -/* Common assembly source macros */ - -#ifdef CONFIG_XIP_KERNEL -.macro XIP_FIXUP_OFFSET reg - REG_L t0, _xip_fixup - add \reg, \reg, t0 -.endm -.macro XIP_FIXUP_FLASH_OFFSET reg - la t1, __data_loc - REG_L t1, _xip_phys_offset - sub \reg, \reg, t1 - add \reg, \reg, t0 -.endm -_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET -_xip_phys_offset: .dword CONFIG_XIP_PHYS_ADDR + XIP_OFFSET -#else -.macro XIP_FIXUP_OFFSET reg -.endm -.macro XIP_FIXUP_FLASH_OFFSET reg -.endm -#endif /* CONFIG_XIP_KERNEL */ - -#endif /* __ASSEMBLY__ */ - #endif /* _ASM_RISCV_ASM_H */ diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h new file mode 100644 index 000000000000..d4ffc3c37649 --- /dev/null +++ b/arch/riscv/include/asm/xip_fixup.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * XIP fixup macros, only useful in assembly. + */ +#ifndef _ASM_RISCV_XIP_FIXUP_H +#define _ASM_RISCV_XIP_FIXUP_H + +#include <linux/pgtable.h> + +#ifdef CONFIG_XIP_KERNEL +.macro XIP_FIXUP_OFFSET reg + REG_L t0, _xip_fixup + add \reg, \reg, t0 +.endm +.macro XIP_FIXUP_FLASH_OFFSET reg + la t1, __data_loc + REG_L t1, _xip_phys_offset + sub \reg, \reg, t1 + add \reg, \reg, t0 +.endm + +_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET +_xip_phys_offset: .dword CONFIG_XIP_PHYS_ADDR + XIP_OFFSET +#else +.macro XIP_FIXUP_OFFSET reg +.endm +.macro XIP_FIXUP_FLASH_OFFSET reg +.endm +#endif /* CONFIG_XIP_KERNEL */ + +#endif diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index b605fb1e6a9c..b865046e4dbb 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -14,6 +14,7 @@ #include <asm/cpu_ops_sbi.h> #include <asm/hwcap.h> #include <asm/image.h> +#include <asm/xip_fixup.h> #include "efi-header.S"
__HEAD diff --git a/arch/riscv/kernel/suspend_entry.S b/arch/riscv/kernel/suspend_entry.S index 4b07b809a2b8..aafcca58c19d 100644 --- a/arch/riscv/kernel/suspend_entry.S +++ b/arch/riscv/kernel/suspend_entry.S @@ -8,6 +8,7 @@ #include <asm/asm.h> #include <asm/asm-offsets.h> #include <asm/csr.h> +#include <asm/xip_fixup.h>
.text .altmacro
From: Palmer Dabbelt palmer@rivosinc.com
[ Upstream commit d9e418d0ca1c464fe361468b772d4aa870d54e63 ]
A handful of functions unused functions were enabled during XIP builds, which themselves didn't build correctly. This just disables the functions entirely.
Fixes: e8a62cc26ddf ("riscv: Implement sv48 support") Reviewed-by: Guo Ren guoren@kernel.org Link: https://lore.kernel.org/r/20220420184056.7886-5-palmer@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/mm/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 05ed641a1134..39e2e1d0e94f 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -677,7 +677,7 @@ static __init pgprot_t pgprot_from_va(uintptr_t va) } #endif /* CONFIG_STRICT_KERNEL_RWX */
-#ifdef CONFIG_64BIT +#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL) static void __init disable_pgtable_l5(void) { pgtable_l5_enabled = false;
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit 7e4fd16b38923028b01d3dbadf4ca973d885c53e ]
kernel test robot reports a build error used with clang compiler and mips-randconfig [1]:
ld.lld: error: undefined symbol: pci_remap_iospace
we can see the following configs in the mips-randconfig file:
CONFIG_RALINK=y CONFIG_SOC_MT7620=y CONFIG_PCI_DRIVERS_LEGACY=y CONFIG_PCI=y
CONFIG_RALINK is set, so pci_remap_iospace is defined in the related arch/mips/include/asm/mach-ralink/spaces.h header file:
#define pci_remap_iospace pci_remap_iospace
CONFIG_PCI is set, so pci_remap_iospace() in drivers/pci/pci.c is not built due to pci_remap_iospace is defined under CONFIG_RALINK.
#ifndef pci_remap_iospace int pci_remap_iospace(const struct resource *res, ...)
$ objdump -d drivers/pci/pci.o | grep pci_remap_iospace 00004cc8 <devm_pci_remap_iospace>: 4d18: 10400008 beqz v0,4d3c <devm_pci_remap_iospace+0x74> 4d2c: 1040000c beqz v0,4d60 <devm_pci_remap_iospace+0x98> 4d70: 1000fff3 b 4d40 <devm_pci_remap_iospace+0x78>
In addition, CONFIG_PCI_DRIVERS_GENERIC is not set, so pci_remap_iospace() in arch/mips/pci/pci-generic.c is not built too.
#ifdef pci_remap_iospace int pci_remap_iospace(const struct resource *res, ...)
For the above reasons, undefined reference pci_remap_iospace() looks like reasonable.
Here are simple steps to reproduce used with gcc and defconfig:
cd mips.git make vocore2_defconfig # set RALINK, SOC_MT7620, PCI_DRIVERS_LEGACY make menuconfig # set PCI make
there exists the following build error:
LD vmlinux.o MODPOST vmlinux.symvers MODINFO modules.builtin.modinfo GEN modules.builtin LD .tmp_vmlinux.kallsyms1 drivers/pci/pci.o: In function `devm_pci_remap_iospace': pci.c:(.text+0x4d24): undefined reference to `pci_remap_iospace' Makefile:1158: recipe for target 'vmlinux' failed make: *** [vmlinux] Error 1
Define pci_remap_iospace under CONFIG_PCI_DRIVERS_GENERIC can fix the build error, with this patch, no build error remains. This patch is similar with commit e538e8649892 ("MIPS: asm: pci: define arch-specific 'pci_remap_iospace()' dependent on 'CONFIG_PCI_DRIVERS_GENERIC'").
[1] https://lore.kernel.org/lkml/202205251247.nQ5cxSV6-lkp@intel.com/
Fixes: 09d97da660ff ("MIPS: Only define pci_remap_iospace() for Ralink") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Acked-by: Sergio Paracuellos sergio.paracuellos@gmail.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/mach-ralink/spaces.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/mips/include/asm/mach-ralink/spaces.h b/arch/mips/include/asm/mach-ralink/spaces.h index f7af11ea2d61..a9f0570d0f04 100644 --- a/arch/mips/include/asm/mach-ralink/spaces.h +++ b/arch/mips/include/asm/mach-ralink/spaces.h @@ -6,7 +6,9 @@ #define PCI_IOSIZE SZ_64K #define IO_SPACE_LIMIT (PCI_IOSIZE - 1)
+#ifdef CONFIG_PCI_DRIVERS_GENERIC #define pci_remap_iospace pci_remap_iospace +#endif
#include <asm/mach-generic/spaces.h> #endif
From: Jiri Olsa jolsa@kernel.org
[ Upstream commit 73534617dfa3c4cd95fe5ffaeff5315e9ffc2de6 ]
The btf__load_from_kernel_by_id() only takes one arg, not two.
Committer notes:
I tested it just with an older libbpf, one where btf__load_from_kernel_by_id() wasn't introduced yet.
A test with a newer dynamic libbpf would fail because the btf__load_from_kernel_by_id() is there, but takes just one arg.
Fixes: 0ae065a5d265bc5a ("perf build: Fix check for btf__load_from_kernel_by_id() in libbpf") Signed-off-by: Jiri Olsa jolsa@kernel.org Cc: Heiko Carstens hca@linux.ibm.com Cc: Ian Rogers irogers@google.com Cc: Ilya Leoshkevich iii@linux.ibm.com Cc: Sumanth Korikkar sumanthk@linux.ibm.com Cc: Sven Schnelle svens@linux.ibm.com Cc: Thomas Richter tmricht@linux.ibm.com Cc: Vasily Gorbik gor@linux.ibm.com Link: http://lore.kernel.org/linux-perf-users/YozLKby7ITEtchC9@krava Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../build/feature/test-libbpf-btf__load_from_kernel_by_id.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/build/feature/test-libbpf-btf__load_from_kernel_by_id.c b/tools/build/feature/test-libbpf-btf__load_from_kernel_by_id.c index f7c084428735..a17647f7d5a4 100644 --- a/tools/build/feature/test-libbpf-btf__load_from_kernel_by_id.c +++ b/tools/build/feature/test-libbpf-btf__load_from_kernel_by_id.c @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 -#include <bpf/libbpf.h> +#include <bpf/btf.h>
int main(void) { - return btf__load_from_kernel_by_id(20151128, NULL); + btf__load_from_kernel_by_id(20151128); + return 0; }
From: Leo Yan leo.yan@linaro.org
[ Upstream commit c4040212bc97d16040712a410335f93bc94d2262 ]
If the slang lib is not installed on the system, perf c2c tool disables TUI mode and roll back to use stdio mode; but the flag 'c2c.use_stdio' is missed to set true and thus it wrongly applies UI quirks in the function ui_quirks().
This commit forces to use stdio interface if slang is not supported, and it can avoid to apply the UI quirks and show the correct metric header.
Before:
================================================= Shared Cache Line Distribution Pareto ================================================= ------------------------------------------------------------------------------- 0 0 0 99 0 0 0 0xaaaac17d6000 ------------------------------------------------------------------------------- 0.00% 0.00% 6.06% 0.00% 0.00% 0.00% 0x20 N/A 0 0xaaaac17c25ac 0 0 43 375 18469 2 [.] 0x00000000000025ac memstress memstress[25ac] 0 0.00% 0.00% 93.94% 0.00% 0.00% 0.00% 0x29 N/A 0 0xaaaac17c3e88 0 0 173 180 135 2 [.] 0x0000000000003e88 memstress memstress[3e88] 0
After:
================================================= Shared Cache Line Distribution Pareto ================================================= ------------------------------------------------------------------------------- 0 0 0 99 0 0 0 0xaaaac17d6000 ------------------------------------------------------------------------------- 0.00% 0.00% 6.06% 0.00% 0.00% 0.00% 0x20 N/A 0 0xaaaac17c25ac 0 0 43 375 18469 2 [.] 0x00000000000025ac memstress memstress[25ac] 0 0.00% 0.00% 93.94% 0.00% 0.00% 0.00% 0x29 N/A 0 0xaaaac17c3e88 0 0 173 180 135 2 [.] 0x0000000000003e88 memstress memstress[3e88] 0
Fixes: 5a1a99cd2e4e1557 ("perf c2c report: Add main TUI browser") Reported-by: Joe Mario jmario@redhat.com Signed-off-by: Leo Yan leo.yan@linaro.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Jiri Olsa jolsa@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: http://lore.kernel.org/lkml/20220526145400.611249-1-leo.yan@linaro.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/builtin-c2c.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index fbbed434014f..8c9ffacbdd28 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -2735,9 +2735,7 @@ static int perf_c2c__report(int argc, const char **argv) "the input file to process"), OPT_INCR('N', "node-info", &c2c.node_info, "show extra node info in report (repeat for more info)"), -#ifdef HAVE_SLANG_SUPPORT OPT_BOOLEAN(0, "stdio", &c2c.use_stdio, "Use the stdio interface"), -#endif OPT_BOOLEAN(0, "stats", &c2c.stats_only, "Display only statistic tables (implies --stdio)"), OPT_BOOLEAN(0, "full-symbols", &c2c.symbol_full, @@ -2767,6 +2765,10 @@ static int perf_c2c__report(int argc, const char **argv) if (argc) usage_with_options(report_c2c_usage, options);
+#ifndef HAVE_SLANG_SUPPORT + c2c.use_stdio = true; +#endif + if (c2c.stats_only) c2c.use_stdio = true;
From: Wan Jiabing wanjiabing@vivo.com
[ Upstream commit 2a6b52ed72c822b5ee146a6a00ea66614fe02653 ]
Fix the following null/deref_null.cocci errors: ./tools/tracing/rtla/src/osnoise_hist.c:870:31-36: ERROR: record is NULL but dereferenced. ./tools/tracing/rtla/src/osnoise_top.c:650:31-36: ERROR: record is NULL but dereferenced. ./tools/tracing/rtla/src/timerlat_hist.c:905:31-36: ERROR: record is NULL but dereferenced. ./tools/tracing/rtla/src/timerlat_top.c:700:31-36: ERROR: record is NULL but dereferenced.
"record" is NULL before calling osnoise_init_trace_tool. Add a tag "out_free" to avoid dereferring a NULL pointer.
Link: https://lkml.kernel.org/r/ae0e4500d383db0884eb2820286afe34ca303778.165124771... Link: https://lore.kernel.org/r/20220408151406.34823-1-wanjiabing@vivo.com/
Cc: kael_w@yeah.net Cc: Daniel Bristot de Oliveira bristot@kernel.org Fixes: 51d64c3a1819 ("rtla: Add -e/--event support") Acked-by: Daniel Bristot de Oliveira bristot@kernel.org Signed-off-by: Wan Jiabing wanjiabing@vivo.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/src/osnoise_hist.c | 5 +++-- tools/tracing/rtla/src/osnoise_top.c | 9 +++++---- tools/tracing/rtla/src/timerlat_hist.c | 11 ++++++----- tools/tracing/rtla/src/timerlat_top.c | 11 ++++++----- 4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c index b4380d45cacd..5d7ea479ac89 100644 --- a/tools/tracing/rtla/src/osnoise_hist.c +++ b/tools/tracing/rtla/src/osnoise_hist.c @@ -809,7 +809,7 @@ int osnoise_hist_main(int argc, char *argv[]) retval = set_comm_sched_attr("osnoise/", ¶ms->sched_param); if (retval) { err_msg("Failed to set sched parameters\n"); - goto out_hist; + goto out_free; } }
@@ -819,7 +819,7 @@ int osnoise_hist_main(int argc, char *argv[]) record = osnoise_init_trace_tool("osnoise"); if (!record) { err_msg("Failed to enable the trace instance\n"); - goto out_hist; + goto out_free; }
if (params->events) { @@ -869,6 +869,7 @@ int osnoise_hist_main(int argc, char *argv[]) out_hist: trace_events_destroy(&record->trace, params->events); params->events = NULL; +out_free: osnoise_free_histogram(tool->data); out_destroy: osnoise_destroy_tool(record); diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c index 72c2fd6ce005..76479bfb2922 100644 --- a/tools/tracing/rtla/src/osnoise_top.c +++ b/tools/tracing/rtla/src/osnoise_top.c @@ -572,7 +572,7 @@ int osnoise_top_main(int argc, char **argv) retval = osnoise_top_apply_config(tool, params); if (retval) { err_msg("Could not apply config\n"); - goto out_top; + goto out_free; }
trace = &tool->trace; @@ -580,14 +580,14 @@ int osnoise_top_main(int argc, char **argv) retval = enable_osnoise(trace); if (retval) { err_msg("Failed to enable osnoise tracer\n"); - goto out_top; + goto out_free; }
if (params->set_sched) { retval = set_comm_sched_attr("osnoise/", ¶ms->sched_param); if (retval) { err_msg("Failed to set sched parameters\n"); - goto out_top; + goto out_free; } }
@@ -597,7 +597,7 @@ int osnoise_top_main(int argc, char **argv) record = osnoise_init_trace_tool("osnoise"); if (!record) { err_msg("Failed to enable the trace instance\n"); - goto out_top; + goto out_free; }
if (params->events) { @@ -649,6 +649,7 @@ int osnoise_top_main(int argc, char **argv) out_top: trace_events_destroy(&record->trace, params->events); params->events = NULL; +out_free: osnoise_free_top(tool->data); osnoise_destroy_tool(record); osnoise_destroy_tool(tool); diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c index dc908126c610..f3ec628f5e51 100644 --- a/tools/tracing/rtla/src/timerlat_hist.c +++ b/tools/tracing/rtla/src/timerlat_hist.c @@ -821,7 +821,7 @@ int timerlat_hist_main(int argc, char *argv[]) retval = timerlat_hist_apply_config(tool, params); if (retval) { err_msg("Could not apply config\n"); - goto out_hist; + goto out_free; }
trace = &tool->trace; @@ -829,14 +829,14 @@ int timerlat_hist_main(int argc, char *argv[]) retval = enable_timerlat(trace); if (retval) { err_msg("Failed to enable timerlat tracer\n"); - goto out_hist; + goto out_free; }
if (params->set_sched) { retval = set_comm_sched_attr("timerlat/", ¶ms->sched_param); if (retval) { err_msg("Failed to set sched parameters\n"); - goto out_hist; + goto out_free; } }
@@ -844,7 +844,7 @@ int timerlat_hist_main(int argc, char *argv[]) dma_latency_fd = set_cpu_dma_latency(params->dma_latency); if (dma_latency_fd < 0) { err_msg("Could not set /dev/cpu_dma_latency.\n"); - goto out_hist; + goto out_free; } }
@@ -854,7 +854,7 @@ int timerlat_hist_main(int argc, char *argv[]) record = osnoise_init_trace_tool("timerlat"); if (!record) { err_msg("Failed to enable the trace instance\n"); - goto out_hist; + goto out_free; }
if (params->events) { @@ -904,6 +904,7 @@ int timerlat_hist_main(int argc, char *argv[]) close(dma_latency_fd); trace_events_destroy(&record->trace, params->events); params->events = NULL; +out_free: timerlat_free_histogram(tool->data); osnoise_destroy_tool(record); osnoise_destroy_tool(tool); diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c index 1f754c3df53f..35452a1d45e9 100644 --- a/tools/tracing/rtla/src/timerlat_top.c +++ b/tools/tracing/rtla/src/timerlat_top.c @@ -612,7 +612,7 @@ int timerlat_top_main(int argc, char *argv[]) retval = timerlat_top_apply_config(top, params); if (retval) { err_msg("Could not apply config\n"); - goto out_top; + goto out_free; }
trace = &top->trace; @@ -620,14 +620,14 @@ int timerlat_top_main(int argc, char *argv[]) retval = enable_timerlat(trace); if (retval) { err_msg("Failed to enable timerlat tracer\n"); - goto out_top; + goto out_free; }
if (params->set_sched) { retval = set_comm_sched_attr("timerlat/", ¶ms->sched_param); if (retval) { err_msg("Failed to set sched parameters\n"); - goto out_top; + goto out_free; } }
@@ -635,7 +635,7 @@ int timerlat_top_main(int argc, char *argv[]) dma_latency_fd = set_cpu_dma_latency(params->dma_latency); if (dma_latency_fd < 0) { err_msg("Could not set /dev/cpu_dma_latency.\n"); - goto out_top; + goto out_free; } }
@@ -645,7 +645,7 @@ int timerlat_top_main(int argc, char *argv[]) record = osnoise_init_trace_tool("timerlat"); if (!record) { err_msg("Failed to enable the trace instance\n"); - goto out_top; + goto out_free; }
if (params->events) { @@ -699,6 +699,7 @@ int timerlat_top_main(int argc, char *argv[]) close(dma_latency_fd); trace_events_destroy(&record->trace, params->events); params->events = NULL; +out_free: timerlat_free_top(top->data); osnoise_destroy_tool(record); osnoise_destroy_tool(top);
From: John Kacur jkacur@redhat.com
[ Upstream commit 39c3d84cb5b52792a7323a338334d8d65b2dbe3f ]
The mode on /usr/bin is often 555 these days, but make install on rtla overwrites this with 755
Fix this by preserving the current directory if it exists.
Link: https://lkml.kernel.org/r/8c294a6961080a1970fd8b73f7bcf1e3984579e2.165124771... Link: https://lore.kernel.org/r/20220402043939.6962-1-jkacur@redhat.com
Cc: Daniel Bristot de Oliveria bristot@redhat.com Fixes: 79ce8f43ac5a ("rtla: Real-Time Linux Analysis tool") Acked-by: Daniel Bristot de Oliveira bristot@kernel.org Signed-off-by: John Kacur jkacur@redhat.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 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile index 11fb417abb42..5a3226e436ef 100644 --- a/tools/tracing/rtla/Makefile +++ b/tools/tracing/rtla/Makefile @@ -23,6 +23,7 @@ $(call allow-override,LD_SO_CONF_PATH,/etc/ld.so.conf.d/) $(call allow-override,LDCONFIG,ldconfig)
INSTALL = install +MKDIR = mkdir FOPTS := -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \ -fasynchronous-unwind-tables -fstack-clash-protection WOPTS := -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized @@ -68,7 +69,7 @@ static: $(OBJ)
.PHONY: install install: doc_install - $(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) + $(MKDIR) -p $(DESTDIR)$(BINDIR) $(INSTALL) rtla -m 755 $(DESTDIR)$(BINDIR) $(STRIP) $(DESTDIR)$(BINDIR)/rtla @test ! -f $(DESTDIR)$(BINDIR)/osnoise || rm $(DESTDIR)$(BINDIR)/osnoise
From: John Kacur jkacur@redhat.com
[ Upstream commit 22d146f7c1e97f4870e4497c0202939a031f740c ]
- Change to "The rtla meta-tool includes" - Remove an unnecessary "But, " - Adjust the formatting of the paragraph resulting from the changes. - Simplify the wording for the libraries and tools.
Link: https://lkml.kernel.org/r/437f0accdde53713ab3cce46f3564be00487e031.165124771... Link: https://lore.kernel.org/r/20220408161012.10544-1-jkacur@redhat.com/
Cc: Daniel Bristot de Oliveria bristot@kernel.org Fixes: 79ce8f43ac5a ("rtla: Real-Time Linux Analysis tool") Acked-by: Daniel Bristot de Oliveira bristot@kernel.org Signed-off-by: John Kacur jkacur@redhat.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/README.txt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/tools/tracing/rtla/README.txt b/tools/tracing/rtla/README.txt index 6c88446f7e74..0fbad2640b8c 100644 --- a/tools/tracing/rtla/README.txt +++ b/tools/tracing/rtla/README.txt @@ -1,15 +1,13 @@ RTLA: Real-Time Linux Analysis tools
-The rtla is a meta-tool that includes a set of commands that -aims to analyze the real-time properties of Linux. But, instead of -testing Linux as a black box, rtla leverages kernel tracing -capabilities to provide precise information about the properties -and root causes of unexpected results. +The rtla meta-tool includes a set of commands that aims to analyze +the real-time properties of Linux. Instead of testing Linux as a black box, +rtla leverages kernel tracing capabilities to provide precise information +about the properties and root causes of unexpected results.
Installing RTLA
-RTLA depends on some libraries and tools. More precisely, it depends on the -following libraries: +RTLA depends on the following libraries and tools:
- libtracefs - libtraceevent
From: Daniel Bristot de Oliveira bristot@kernel.org
[ Upstream commit 941a53c39a151e9aceef153cdfaed0f166ba01b7 ]
rtla's function __set_sched_attr() was borrowed from stalld, but I forgot to update the error message to something meaningful for rtla.
Update the error message from: boost_with_deadline failed to boost pid PID: STRERROR to a proper one: Failed to set sched attributes to the pid PID: STRERROR
Link: https://lkml.kernel.org/r/a2d19b2c53f6512aefd1ee7f8c1bd19d4fc8b99d.165124771... Link: https://lore.kernel.org/r/eeded730413e7feaa13f946924bcf2cbf7dd9561.165061757...
Fixes: b1696371d865 ("rtla: Helper functions for rtla") 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/src/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c index da2b590edaed..3bd6f64780cf 100644 --- a/tools/tracing/rtla/src/utils.c +++ b/tools/tracing/rtla/src/utils.c @@ -255,7 +255,7 @@ int __set_sched_attr(int pid, struct sched_attr *attr)
retval = sched_setattr(pid, attr, flags); if (retval < 0) { - err_msg("boost_with_deadline failed to boost pid %d: %s\n", + err_msg("Failed to set sched attributes to the pid %d: %s\n", pid, strerror(errno)); return 1; }
From: Daniel Bristot de Oliveira bristot@kernel.org
[ Upstream commit dada03db9bb1984826e61cfcf1418ac73848324d ]
Daniel Wagner reported to me that readproc.h got deprecated. Also, while the procps-ng library was available on Fedora, it was not available on RHEL, which is a piece of evidence that it was not that used.
rtla uses procps-ng only to find the PID of the tracers' workload.
I used the procps-ng library to avoid reinventing the wheel. But in this case, reinventing the wheel took me less time than the time we already took trying to work around problems.
Implement a function that reads /proc/ entries, checking if: - the entry is a directory - the directory name is composed only of digits (PID) - the directory contains the comm file - the comm file contains a comm that matches the tracers' workload prefix. - then return true; otherwise, return false.
And use it instead of procps-ng.
Link: https://lkml.kernel.org/r/e8276e122ee9eb2c5a0ba8e673fb6488b924b825.165242357...
Cc: John Kacur jkacur@redhat.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Tao Zhou tao.zhou@linux.dev Fixes: b1696371d865 ("rtla: Helper functions for rtla") Reported-by: Daniel Wagner dwagner@suse.de Reviewed-by: Daniel Wagner dwagner@suse.de 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 +- tools/tracing/rtla/README.txt | 1 - tools/tracing/rtla/src/utils.c | 106 ++++++++++++++++++++++++++------- tools/tracing/rtla/src/utils.h | 3 +- 4 files changed, 88 insertions(+), 24 deletions(-)
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile index 5a3226e436ef..523f0a8c38c2 100644 --- a/tools/tracing/rtla/Makefile +++ b/tools/tracing/rtla/Makefile @@ -32,7 +32,7 @@ TRACEFS_HEADERS := $$($(PKG_CONFIG) --cflags libtracefs)
CFLAGS := -O -g -DVERSION="$(VERSION)" $(FOPTS) $(MOPTS) $(WOPTS) $(TRACEFS_HEADERS) LDFLAGS := -ggdb -LIBS := $$($(PKG_CONFIG) --libs libtracefs) -lprocps +LIBS := $$($(PKG_CONFIG) --libs libtracefs)
SRC := $(wildcard src/*.c) HDR := $(wildcard src/*.h) diff --git a/tools/tracing/rtla/README.txt b/tools/tracing/rtla/README.txt index 0fbad2640b8c..4af3fd40f171 100644 --- a/tools/tracing/rtla/README.txt +++ b/tools/tracing/rtla/README.txt @@ -11,7 +11,6 @@ RTLA depends on the following libraries and tools:
- libtracefs - libtraceevent - - procps
It also depends on python3-docutils to compile man pages.
diff --git a/tools/tracing/rtla/src/utils.c b/tools/tracing/rtla/src/utils.c index 3bd6f64780cf..5352167a1e75 100644 --- a/tools/tracing/rtla/src/utils.c +++ b/tools/tracing/rtla/src/utils.c @@ -3,7 +3,7 @@ * Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira bristot@kernel.org */
-#include <proc/readproc.h> +#include <dirent.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> @@ -262,43 +262,107 @@ int __set_sched_attr(int pid, struct sched_attr *attr)
return 0; } + +/* + * procfs_is_workload_pid - check if a procfs entry contains a comm_prefix* comm + * + * Check if the procfs entry is a directory of a process, and then check if the + * process has a comm with the prefix set in char *comm_prefix. As the + * current users of this function only check for kernel threads, there is no + * need to check for the threads for the process. + * + * Return: True if the proc_entry contains a comm file with comm_prefix*. + * Otherwise returns false. + */ +static int procfs_is_workload_pid(const char *comm_prefix, struct dirent *proc_entry) +{ + char buffer[MAX_PATH]; + int comm_fd, retval; + char *t_name; + + if (proc_entry->d_type != DT_DIR) + return 0; + + if (*proc_entry->d_name == '.') + return 0; + + /* check if the string is a pid */ + for (t_name = proc_entry->d_name; t_name; t_name++) { + if (!isdigit(*t_name)) + break; + } + + if (*t_name != '\0') + return 0; + + snprintf(buffer, MAX_PATH, "/proc/%s/comm", proc_entry->d_name); + comm_fd = open(buffer, O_RDONLY); + if (comm_fd < 0) + return 0; + + memset(buffer, 0, MAX_PATH); + retval = read(comm_fd, buffer, MAX_PATH); + + close(comm_fd); + + if (retval <= 0) + return 0; + + retval = strncmp(comm_prefix, buffer, strlen(comm_prefix)); + if (retval) + return 0; + + /* comm already have \n */ + debug_msg("Found workload pid:%s comm:%s", proc_entry->d_name, buffer); + + return 1; +} + /* - * set_comm_sched_attr - set sched params to threads starting with char *comm + * set_comm_sched_attr - set sched params to threads starting with char *comm_prefix * - * This function uses procps to list the currently running threads and then - * set the sched_attr *attr to the threads that start with char *comm. It is + * This function uses procfs to list the currently running threads and then set the + * sched_attr *attr to the threads that start with char *comm_prefix. It is * mainly used to set the priority to the kernel threads created by the * tracers. */ -int set_comm_sched_attr(const char *comm, struct sched_attr *attr) +int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr) { - int flags = PROC_FILLCOM | PROC_FILLSTAT; - PROCTAB *ptp; - proc_t task; + struct dirent *proc_entry; + DIR *procfs; int retval;
- ptp = openproc(flags); - if (!ptp) { - err_msg("error openproc()\n"); - return -ENOENT; + if (strlen(comm_prefix) >= MAX_PATH) { + err_msg("Command prefix is too long: %d < strlen(%s)\n", + MAX_PATH, comm_prefix); + return 1; }
- memset(&task, 0, sizeof(task)); + procfs = opendir("/proc"); + if (!procfs) { + err_msg("Could not open procfs\n"); + return 1; + }
- while (readproc(ptp, &task)) { - retval = strncmp(comm, task.cmd, strlen(comm)); - if (retval) + while ((proc_entry = readdir(procfs))) { + + retval = procfs_is_workload_pid(comm_prefix, proc_entry); + if (!retval) continue; - retval = __set_sched_attr(task.tid, attr); - if (retval) + + /* procfs_is_workload_pid confirmed it is a pid */ + retval = __set_sched_attr(atoi(proc_entry->d_name), attr); + if (retval) { + err_msg("Error setting sched attributes for pid:%s\n", proc_entry->d_name); goto out_err; - } + }
- closeproc(ptp); + debug_msg("Set sched attributes for pid:%s\n", proc_entry->d_name); + } return 0;
out_err: - closeproc(ptp); + closedir(procfs); return 1; }
diff --git a/tools/tracing/rtla/src/utils.h b/tools/tracing/rtla/src/utils.h index fa08e374870a..5571afd3b549 100644 --- a/tools/tracing/rtla/src/utils.h +++ b/tools/tracing/rtla/src/utils.h @@ -6,6 +6,7 @@ * '18446744073709551615\0' */ #define BUFF_U64_STR_SIZE 24 +#define MAX_PATH 1024
#define container_of(ptr, type, member)({ \ const typeof(((type *)0)->member) *__mptr = (ptr); \ @@ -53,5 +54,5 @@ struct sched_attr { };
int parse_prio(char *arg, struct sched_attr *sched_param); -int set_comm_sched_attr(const char *comm, struct sched_attr *attr); +int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr); int set_cpu_dma_latency(int32_t latency);
From: Daniel Bristot de Oliveira bristot@kernel.org
[ Upstream commit aa748949b4e665f473bc5abdc5f66029cb5f5522 ]
Currently, the notification of a new max latency is sent from timerlat's IRQ handler anytime a new max latency is found.
While this behavior is not wrong, the send IPI overhead itself will increase the thread latency and that is not the desired effect (tracing overhead).
Moreover, the thread will notify a new max latency again because the thread latency as it is always higher than the IRQ latency that woke it up.
The only case in which it is helpful to notify a new max latency from IRQ is when stop tracing (for the IRQ) is set, as in this case, the thread will not be dispatched.
Notify a new max latency from the IRQ handler only if stop tracing is set for the IRQ handler.
Link: https://lkml.kernel.org/r/2c2d9a56c0886c8402ba320de32856cbbb10c2bb.165217563...
Cc: Juri Lelli juri.lelli@redhat.com Cc: Ingo Molnar mingo@redhat.com Reported-by: Clark Williams williams@redhat.com Fixes: a955d7eac177 ("trace: Add timerlat tracer") 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 --- kernel/trace/trace_osnoise.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index afb92e2f0aea..d8e8167a079f 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -1578,11 +1578,12 @@ static enum hrtimer_restart timerlat_irq(struct hrtimer *timer)
trace_timerlat_sample(&s);
- notify_new_max_latency(diff); - - if (osnoise_data.stop_tracing) - if (time_to_us(diff) >= osnoise_data.stop_tracing) + if (osnoise_data.stop_tracing) { + if (time_to_us(diff) >= osnoise_data.stop_tracing) { osnoise_stop_tracing(); + notify_new_max_latency(diff); + } + }
wake_up_process(tlat->kthread);
From: Zhengjun Xing zhengjun.xing@linux.intel.com
[ Upstream commit f4df0dbbe62ee8e4405a57b27ccd54393971c773 ]
In the origin code, when "ExtSel" is 1, the eventcode will change to "eventcode |= 1 << 21”. For event “UNC_Q_RxL_CREDITS_CONSUMED_VN0.DRS", its "ExtSel" is "1", its eventcode will change from 0x1E to 0x20001E, but in fact the eventcode should <=0x1FF, so this will cause the parse fail:
# perf stat -e "UNC_Q_RxL_CREDITS_CONSUMED_VN0.DRS" -a sleep 0.1 event syntax error: '.._RxL_CREDITS_CONSUMED_VN0.DRS' ___ value too big for format, maximum is 511
On the perf kernel side, the kernel assumes the valid bits are continuous. It will adjust the 0x100 (bit 8 for perf tool) to bit 21 in HW.
DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
So the perf tool follows the kernel side and just set bit8 other than bit21.
Fixes: fedb2b518239cbc0 ("perf jevents: Add support for parsing uncore json files") Reviewed-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Xing Zhengjun zhengjun.xing@linux.intel.com Acked-by: Ian Rogers irogers@google.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: Alexander Shishkin alexander.shishkin@intel.com Cc: Andi Kleen ak@linux.intel.com Cc: Ingo Molnar mingo@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Peter Zijlstra peterz@infradead.org Link: https://lore.kernel.org/r/20220525140410.1706851-1-zhengjun.xing@linux.intel... Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/pmu-events/jevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c index 159d9eab6e79..b1eb68c861e7 100644 --- a/tools/perf/pmu-events/jevents.c +++ b/tools/perf/pmu-events/jevents.c @@ -612,7 +612,7 @@ static int json_events(const char *fn, } else if (json_streq(map, field, "ExtSel")) { char *code = NULL; addfield(map, &code, "", "", val); - eventcode |= strtoul(code, NULL, 0) << 21; + eventcode |= strtoul(code, NULL, 0) << 8; free(code); } else if (json_streq(map, field, "EventName")) { addfield(map, &je.name, "", "", val);
From: Javier Martinez Canillas javierm@redhat.com
[ Upstream commit acde4003efc16480375543638484d8f13f2e99a3 ]
Commit b3c9a924aab6 ("fbdev: vesafb: Cleanup fb_info in .fb_destroy rather than .remove") fixed a use-after-free error due the vesafb driver freeing the fb_info in the .remove handler instead of doing it in .fb_destroy.
This can happen if the .fb_destroy callback is executed after the .remove callback, since the former tries to access a pointer freed by the latter.
But that change didn't take into account that another possible scenario is that .fb_destroy is called before the .remove callback. For example, if no process has the fbdev chardev opened by the time the driver is removed.
If that's the case, fb_info will be freed when unregister_framebuffer() is called, making the fb_info pointer accessed in vesafb_remove() after that to no longer be valid.
To prevent that, move the expression containing the info->par to happen before the unregister_framebuffer() function call.
Fixes: b3c9a924aab6 ("fbdev: vesafb: Cleanup fb_info in .fb_destroy rather than .remove") Reported-by: Pascal Ernster dri-devel@hardfalcon.net Signed-off-by: Javier Martinez Canillas javierm@redhat.com Tested-by: Pascal Ernster dri-devel@hardfalcon.net Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/vesafb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c index e25e8de5ff67..929d4775cb4b 100644 --- a/drivers/video/fbdev/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -490,11 +490,12 @@ static int vesafb_remove(struct platform_device *pdev) { struct fb_info *info = platform_get_drvdata(pdev);
- /* vesafb_destroy takes care of info cleanup */ - unregister_framebuffer(info); if (((struct vesafb_par *)(info->par))->region) release_region(0x3c0, 32);
+ /* vesafb_destroy takes care of info cleanup */ + unregister_framebuffer(info); + return 0; }
From: Benjamin Coddington bcodding@redhat.com
[ Upstream commit c3ed222745d9ad7b69299b349a64ba533c64a34f ]
Send along the already-allocated fattr along with nfs4_fs_locations, and drop the memcpy of fattr. We end up growing two more allocations, but this fixes up a crash as:
PID: 790 TASK: ffff88811b43c000 CPU: 0 COMMAND: "ls" #0 [ffffc90000857920] panic at ffffffff81b9bfde #1 [ffffc900008579c0] do_trap at ffffffff81023a9b #2 [ffffc90000857a10] do_error_trap at ffffffff81023b78 #3 [ffffc90000857a58] exc_stack_segment at ffffffff81be1f45 #4 [ffffc90000857a80] asm_exc_stack_segment at ffffffff81c009de #5 [ffffc90000857b08] nfs_lookup at ffffffffa0302322 [nfs] #6 [ffffc90000857b70] __lookup_slow at ffffffff813a4a5f #7 [ffffc90000857c60] walk_component at ffffffff813a86c4 #8 [ffffc90000857cb8] path_lookupat at ffffffff813a9553 #9 [ffffc90000857cf0] filename_lookup at ffffffff813ab86b
Suggested-by: Trond Myklebust trondmy@hammerspace.com Fixes: 9558a007dbc3 ("NFS: Remove the label from the nfs4_lookup_res struct") Signed-off-by: Benjamin Coddington bcodding@redhat.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4namespace.c | 9 +++++++-- fs/nfs/nfs4proc.c | 15 +++++++-------- fs/nfs/nfs4state.c | 9 ++++++++- fs/nfs/nfs4xdr.c | 4 ++-- include/linux/nfs_xdr.h | 2 +- 5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 3680c8da510c..f2dbf904c598 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -417,6 +417,9 @@ static int nfs_do_refmount(struct fs_context *fc, struct rpc_clnt *client) fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); if (!fs_locations) goto out_free; + fs_locations->fattr = nfs_alloc_fattr(); + if (!fs_locations->fattr) + goto out_free_2;
/* Get locations */ dentry = ctx->clone_data.dentry; @@ -427,14 +430,16 @@ static int nfs_do_refmount(struct fs_context *fc, struct rpc_clnt *client) err = nfs4_proc_fs_locations(client, d_inode(parent), &dentry->d_name, fs_locations, page); dput(parent); if (err != 0) - goto out_free_2; + goto out_free_3;
err = -ENOENT; if (fs_locations->nlocations <= 0 || fs_locations->fs_path.ncomponents <= 0) - goto out_free_2; + goto out_free_3;
err = nfs_follow_referral(fc, fs_locations); +out_free_3: + kfree(fs_locations->fattr); out_free_2: kfree(fs_locations); out_free: diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a79f66432bd3..0600f85b6016 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4243,6 +4243,8 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, if (locations == NULL) goto out;
+ locations->fattr = fattr; + status = nfs4_proc_fs_locations(client, dir, name, locations, page); if (status != 0) goto out; @@ -4252,17 +4254,14 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, * referral. Cause us to drop into the exception handler, which * will kick off migration recovery. */ - if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { + if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &fattr->fsid)) { dprintk("%s: server did not return a different fsid for" " a referral at %s\n", __func__, name->name); status = -NFS4ERR_MOVED; goto out; } /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ - nfs_fixup_referral_attributes(&locations->fattr); - - /* replace the lookup nfs_fattr with the locations nfs_fattr */ - memcpy(fattr, &locations->fattr, sizeof(struct nfs_fattr)); + nfs_fixup_referral_attributes(fattr); memset(fhandle, 0, sizeof(struct nfs_fh)); out: if (page) @@ -7902,7 +7901,7 @@ static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, else bitmask[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
- nfs_fattr_init(&fs_locations->fattr); + nfs_fattr_init(fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations = 0; status = nfs4_call_sync(client, server, &msg, &args.seq_args, &res.seq_res, 0); @@ -7967,7 +7966,7 @@ static int _nfs40_proc_get_locations(struct nfs_server *server, unsigned long now = jiffies; int status;
- nfs_fattr_init(&locations->fattr); + nfs_fattr_init(locations->fattr); locations->server = server; locations->nlocations = 0;
@@ -8032,7 +8031,7 @@ static int _nfs41_proc_get_locations(struct nfs_server *server, }; int status;
- nfs_fattr_init(&locations->fattr); + nfs_fattr_init(locations->fattr); locations->server = server; locations->nlocations = 0;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 9e1c987c81e7..9656d40bb488 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -2106,6 +2106,11 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred dprintk("<-- %s: no memory\n", __func__); goto out; } + locations->fattr = nfs_alloc_fattr(); + if (locations->fattr == NULL) { + dprintk("<-- %s: no memory\n", __func__); + goto out; + }
inode = d_inode(server->super->s_root); result = nfs4_proc_get_locations(server, NFS_FH(inode), locations, @@ -2120,7 +2125,7 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred if (!locations->nlocations) goto out;
- if (!(locations->fattr.valid & NFS_ATTR_FATTR_V4_LOCATIONS)) { + if (!(locations->fattr->valid & NFS_ATTR_FATTR_V4_LOCATIONS)) { dprintk("<-- %s: No fs_locations data, migration skipped\n", __func__); goto out; @@ -2145,6 +2150,8 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred out: if (page != NULL) __free_page(page); + if (locations != NULL) + kfree(locations->fattr); kfree(locations); if (result) { pr_err("NFS: migration recovery failed (server %s)\n", diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 86a5f6516928..5d822594336d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -7051,7 +7051,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, if (res->migration) { xdr_enter_page(xdr, PAGE_SIZE); status = decode_getfattr_generic(xdr, - &res->fs_locations->fattr, + res->fs_locations->fattr, NULL, res->fs_locations, res->fs_locations->server); if (status) @@ -7064,7 +7064,7 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, goto out; xdr_enter_page(xdr, PAGE_SIZE); status = decode_getfattr_generic(xdr, - &res->fs_locations->fattr, + res->fs_locations->fattr, NULL, res->fs_locations, res->fs_locations->server); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 2863e5a69c6a..20e97329fe46 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1212,7 +1212,7 @@ struct nfs4_fs_location {
#define NFS4_FS_LOCATIONS_MAXENTRIES 10 struct nfs4_fs_locations { - struct nfs_fattr fattr; + struct nfs_fattr *fattr; const struct nfs_server *server; struct nfs4_pathname fs_path; int nlocations;
From: Olga Kornievskaia kolga@netapp.com
[ Upstream commit 118f09eda21d392e1eeb9f8a4bee044958cccf20 ]
Mark async operations such as RENAME, REMOVE, COMMIT MOVEABLE for the nfsv4.1+ sessions.
Fixes: 85e39feead948 ("NFSv4.1 identify and mark RPC tasks that can move between transports") Signed-off-by: Olga Kornievskaia kolga@netapp.com Signed-off-by: Anna Schumaker Anna.Schumaker@Netapp.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 26 ++++++++++++++------------ fs/nfs/pagelist.c | 3 +++ fs/nfs/unlink.c | 8 ++++++++ fs/nfs/write.c | 4 ++++ include/linux/nfs_fs_sb.h | 1 + 5 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0600f85b6016..8c5907287c16 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1162,7 +1162,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, { unsigned short task_flags = 0;
- if (server->nfs_client->cl_minorversion) + if (server->caps & NFS_CAP_MOVEABLE) task_flags = RPC_TASK_MOVEABLE; return nfs4_do_call_sync(clnt, server, msg, args, res, task_flags); } @@ -2568,7 +2568,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, }; int status;
- if (server->nfs_client->cl_minorversion) + if (nfs_server_capable(dir, NFS_CAP_MOVEABLE)) task_setup_data.flags |= RPC_TASK_MOVEABLE;
kref_get(&data->kref); @@ -3733,7 +3733,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait) }; int status = -ENOMEM;
- if (server->nfs_client->cl_minorversion) + if (nfs_server_capable(state->inode, NFS_CAP_MOVEABLE)) task_setup_data.flags |= RPC_TASK_MOVEABLE;
nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP, @@ -4403,7 +4403,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, }; unsigned short task_flags = 0;
- if (server->nfs_client->cl_minorversion) + if (nfs_server_capable(dir, NFS_CAP_MOVEABLE)) task_flags = RPC_TASK_MOVEABLE;
/* Is this is an attribute revalidation, subject to softreval? */ @@ -6611,10 +6611,13 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, .rpc_client = server->client, .rpc_message = &msg, .callback_ops = &nfs4_delegreturn_ops, - .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT | RPC_TASK_MOVEABLE, + .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT, }; int status = 0;
+ if (nfs_server_capable(inode, NFS_CAP_MOVEABLE)) + task_setup_data.flags |= RPC_TASK_MOVEABLE; + data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -6928,10 +6931,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, .workqueue = nfsiod_workqueue, .flags = RPC_TASK_ASYNC, }; - struct nfs_client *client = - NFS_SERVER(lsp->ls_state->inode)->nfs_client;
- if (client->cl_minorversion) + if (nfs_server_capable(lsp->ls_state->inode, NFS_CAP_MOVEABLE)) task_setup_data.flags |= RPC_TASK_MOVEABLE;
nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client, @@ -7202,9 +7203,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF, }; int ret; - struct nfs_client *client = NFS_SERVER(state->inode)->nfs_client;
- if (client->cl_minorversion) + if (nfs_server_capable(state->inode, NFS_CAP_MOVEABLE)) task_setup_data.flags |= RPC_TASK_MOVEABLE;
data = nfs4_alloc_lockdata(fl, nfs_file_open_context(fl->fl_file), @@ -10390,7 +10390,8 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = { | NFS_CAP_POSIX_LOCK | NFS_CAP_STATEID_NFSV41 | NFS_CAP_ATOMIC_OPEN_V1 - | NFS_CAP_LGOPEN, + | NFS_CAP_LGOPEN + | NFS_CAP_MOVEABLE, .init_client = nfs41_init_client, .shutdown_client = nfs41_shutdown_client, .match_stateid = nfs41_match_stateid, @@ -10425,7 +10426,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { | NFS_CAP_LAYOUTSTATS | NFS_CAP_CLONE | NFS_CAP_LAYOUTERROR - | NFS_CAP_READ_PLUS, + | NFS_CAP_READ_PLUS + | NFS_CAP_MOVEABLE, .init_client = nfs41_init_client, .shutdown_client = nfs41_shutdown_client, .match_stateid = nfs41_match_stateid, diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 9157dd19b8b4..317cedfa52bf 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -767,6 +767,9 @@ int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr, .flags = RPC_TASK_ASYNC | flags, };
+ if (nfs_server_capable(hdr->inode, NFS_CAP_MOVEABLE)) + task_setup_data.flags |= RPC_TASK_MOVEABLE; + hdr->rw_ops->rw_initiate(hdr, &msg, rpc_ops, &task_setup_data, how);
dprintk("NFS: initiated pgio call " diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 6f325e10056c..9697cd5d2561 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -102,6 +102,10 @@ static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data) }; struct rpc_task *task; struct inode *dir = d_inode(data->dentry->d_parent); + + if (nfs_server_capable(inode, NFS_CAP_MOVEABLE)) + task_setup_data.flags |= RPC_TASK_MOVEABLE; + nfs_sb_active(dir->i_sb); data->args.fh = NFS_FH(dir); nfs_fattr_init(data->res.dir_attr); @@ -344,6 +348,10 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF, };
+ if (nfs_server_capable(old_dir, NFS_CAP_MOVEABLE) && + nfs_server_capable(new_dir, NFS_CAP_MOVEABLE)) + task_setup_data.flags |= RPC_TASK_MOVEABLE; + data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return ERR_PTR(-ENOMEM); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 2f41659e232e..1c706465d090 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1709,6 +1709,10 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data, .flags = RPC_TASK_ASYNC | flags, .priority = priority, }; + + if (nfs_server_capable(data->inode, NFS_CAP_MOVEABLE)) + task_setup_data.flags |= RPC_TASK_MOVEABLE; + /* Set up the initial task struct. */ nfs_ops->commit_setup(data, &msg, &task_setup_data.rpc_client); trace_nfs_initiate_commit(data); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 157d2bd6b241..ea2f7e6b1b0b 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -287,4 +287,5 @@ struct nfs_server { #define NFS_CAP_XATTR (1U << 28) #define NFS_CAP_READ_PLUS (1U << 29) #define NFS_CAP_FS_LOCATIONS (1U << 30) +#define NFS_CAP_MOVEABLE (1U << 31) #endif
From: Chao Yu chao@kernel.org
commit 4d17e6fe9293d57081ffdc11e1cf313e25e8fd9e upstream.
As Yanming reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215897
I have encountered a bug in F2FS file system in kernel v5.17.
The kernel should enable CONFIG_KASAN=y and CONFIG_KASAN_INLINE=y. You can reproduce the bug by running the following commands:
The kernel message is shown below:
kernel BUG at fs/f2fs/f2fs.h:2511! Call Trace: f2fs_remove_inode_page+0x2a2/0x830 f2fs_evict_inode+0x9b7/0x1510 evict+0x282/0x4e0 do_unlinkat+0x33a/0x540 __x64_sys_unlinkat+0x8e/0xd0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
The root cause is: .total_valid_block_count or .total_valid_node_count could fuzzed to zero, then once dec_valid_node_count() was called, it will cause BUG_ON(), this patch fixes to print warning info and set SBI_NEED_FSCK into CP instead of panic.
Cc: stable@vger.kernel.org Reported-by: Ming Yan yanming@tju.edu.cn Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/f2fs.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
--- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2605,11 +2605,17 @@ static inline void dec_valid_node_count( { spin_lock(&sbi->stat_lock);
- f2fs_bug_on(sbi, !sbi->total_valid_block_count); - f2fs_bug_on(sbi, !sbi->total_valid_node_count); + if (unlikely(!sbi->total_valid_block_count || + !sbi->total_valid_node_count)) { + f2fs_warn(sbi, "dec_valid_node_count: inconsistent block counts, total_valid_block:%u, total_valid_node:%u", + sbi->total_valid_block_count, + sbi->total_valid_node_count); + set_sbi_flag(sbi, SBI_NEED_FSCK); + } else { + sbi->total_valid_block_count--; + sbi->total_valid_node_count--; + }
- sbi->total_valid_node_count--; - sbi->total_valid_block_count--; if (sbi->reserved_blocks && sbi->current_reserved_blocks < sbi->reserved_blocks) sbi->current_reserved_blocks++;
From: Chao Yu chao@kernel.org
commit 25f8236213a91efdf708b9d77e9e51b6fc3e141c upstream.
As Yanming reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215894
I have encountered a bug in F2FS file system in kernel v5.17.
I have uploaded the system call sequence as case.c, and a fuzzed image can be found in google net disk
The kernel should enable CONFIG_KASAN=y and CONFIG_KASAN_INLINE=y. You can reproduce the bug by running the following commands:
kernel BUG at fs/f2fs/segment.c:2291! Call Trace: f2fs_invalidate_blocks+0x193/0x2d0 f2fs_fallocate+0x2593/0x4a70 vfs_fallocate+0x2a5/0xac0 ksys_fallocate+0x35/0x70 __x64_sys_fallocate+0x8e/0xf0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
The root cause is, after image was fuzzed, block mapping info in inode will be inconsistent with SIT table, so in f2fs_fallocate(), it will cause panic when updating SIT with invalid blkaddr.
Let's fix the issue by adding sanity check on block address before updating SIT table with it.
Cc: stable@vger.kernel.org Reported-by: Ming Yan yanming@tju.edu.cn Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/file.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
--- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1437,11 +1437,19 @@ static int f2fs_do_zero_range(struct dno ret = -ENOSPC; break; } - if (dn->data_blkaddr != NEW_ADDR) { - f2fs_invalidate_blocks(sbi, dn->data_blkaddr); - dn->data_blkaddr = NEW_ADDR; - f2fs_set_data_blkaddr(dn); + + if (dn->data_blkaddr == NEW_ADDR) + continue; + + if (!f2fs_is_valid_blkaddr(sbi, dn->data_blkaddr, + DATA_GENERIC_ENHANCE)) { + ret = -EFSCORRUPTED; + break; } + + f2fs_invalidate_blocks(sbi, dn->data_blkaddr); + dn->data_blkaddr = NEW_ADDR; + f2fs_set_data_blkaddr(dn); }
f2fs_update_extent_cache_range(dn, start, 0, index - start);
From: Chao Yu chao@kernel.org
commit f2db71053dc0409fae785096ad19cce4c8a95af7 upstream.
As Yanming reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215904
The kernel message is shown below:
kernel BUG at fs/f2fs/inode.c:825! Call Trace: evict+0x282/0x4e0 __dentry_kill+0x2b2/0x4d0 shrink_dentry_list+0x17c/0x4f0 shrink_dcache_parent+0x143/0x1e0 do_one_tree+0x9/0x30 shrink_dcache_for_umount+0x51/0x120 generic_shutdown_super+0x5c/0x3a0 kill_block_super+0x90/0xd0 kill_f2fs_super+0x225/0x310 deactivate_locked_super+0x78/0xc0 cleanup_mnt+0x2b7/0x480 task_work_run+0xc8/0x150 exit_to_user_mode_prepare+0x14a/0x150 syscall_exit_to_user_mode+0x1d/0x40 do_syscall_64+0x48/0x90
The root cause is: inode node and dnode node share the same nid, so during f2fs_evict_inode(), dnode node truncation will invalidate its NAT entry, so when truncating inode node, it fails due to invalid NAT entry, result in inode is still marked as dirty, fix this issue by clearing dirty for inode and setting SBI_NEED_FSCK flag in filesystem.
output from dump.f2fs: [print_node_info: 354] Node ID [0xf:15] is inode i_nid[0] [0x f : 15]
Cc: stable@vger.kernel.org Reported-by: Ming Yan yanming@tju.edu.cn Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/inode.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
--- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -796,8 +796,22 @@ retry: f2fs_lock_op(sbi); err = f2fs_remove_inode_page(inode); f2fs_unlock_op(sbi); - if (err == -ENOENT) + if (err == -ENOENT) { err = 0; + + /* + * in fuzzed image, another node may has the same + * block address as inode's, if it was truncated + * previously, truncation of inode node will fail. + */ + if (is_inode_flag_set(inode, FI_DIRTY_INODE)) { + f2fs_warn(F2FS_I_SB(inode), + "f2fs_evict_inode: inconsistent node id, ino:%lu", + inode->i_ino); + f2fs_inode_synced(inode); + set_sbi_flag(sbi, SBI_NEED_FSCK); + } + } }
/* give more chances, if ENOMEM case */
From: Chao Yu chao@kernel.org
commit cfd66bb715fd11fde3338d0660cffa1396adc27d upstream.
As Yanming reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215914
The root cause is: in a very small sized image, it's very easy to exceed threshold of foreground GC, if we calculate free space and dirty data based on section granularity, in corner case, has_not_enough_free_secs() will always return true, result in deadloop in f2fs_gc().
So this patch refactors has_not_enough_free_secs() as below to fix this issue: 1. calculate needed space based on block granularity, and separate all blocks to two parts, section part, and block part, comparing section part to free section, and comparing block part to free space in openned log. 2. account F2FS_DIRTY_NODES, F2FS_DIRTY_IMETA and F2FS_DIRTY_DENTS as node block consumer; 3. account F2FS_DIRTY_DENTS as data block consumer;
Cc: stable@vger.kernel.org Reported-by: Ming Yan yanming@tju.edu.cn Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/segment.h | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
--- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -572,11 +572,10 @@ static inline int reserved_sections(stru return GET_SEC_FROM_SEG(sbi, reserved_segments(sbi)); }
-static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi) +static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi, + unsigned int node_blocks, unsigned int dent_blocks) { - unsigned int node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) + - get_pages(sbi, F2FS_DIRTY_DENTS); - unsigned int dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS); + unsigned int segno, left_blocks; int i;
@@ -602,19 +601,28 @@ static inline bool has_curseg_enough_spa static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed, int needed) { - int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES); - int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS); - int imeta_secs = get_blocktype_secs(sbi, F2FS_DIRTY_IMETA); + unsigned int total_node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) + + get_pages(sbi, F2FS_DIRTY_DENTS) + + get_pages(sbi, F2FS_DIRTY_IMETA); + unsigned int total_dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS); + unsigned int node_secs = total_node_blocks / BLKS_PER_SEC(sbi); + unsigned int dent_secs = total_dent_blocks / BLKS_PER_SEC(sbi); + unsigned int node_blocks = total_node_blocks % BLKS_PER_SEC(sbi); + unsigned int dent_blocks = total_dent_blocks % BLKS_PER_SEC(sbi); + unsigned int free, need_lower, need_upper;
if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) return false;
- if (free_sections(sbi) + freed == reserved_sections(sbi) + needed && - has_curseg_enough_space(sbi)) + free = free_sections(sbi) + freed; + need_lower = node_secs + dent_secs + reserved_sections(sbi) + needed; + need_upper = need_lower + (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0); + + if (free > need_upper) return false; - return (free_sections(sbi) + freed) <= - (node_secs + 2 * dent_secs + imeta_secs + - reserved_sections(sbi) + needed); + else if (free <= need_lower) + return true; + return !has_curseg_enough_space(sbi, node_blocks, dent_blocks); }
static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)
From: Jaegeuk Kim jaegeuk@kernel.org
commit 6213f5d4d23c50d393a31dc8e351e63a1fd10dbe upstream.
Let's avoid false-alarmed lockdep warning.
[ 58.914674] [T1501146] -> #2 (&sb->s_type->i_mutex_key#20){+.+.}-{3:3}: [ 58.915975] [T1501146] system_server: down_write+0x7c/0xe0 [ 58.916738] [T1501146] system_server: f2fs_quota_sync+0x60/0x1a8 [ 58.917563] [T1501146] system_server: block_operations+0x16c/0x43c [ 58.918410] [T1501146] system_server: f2fs_write_checkpoint+0x114/0x318 [ 58.919312] [T1501146] system_server: f2fs_issue_checkpoint+0x178/0x21c [ 58.920214] [T1501146] system_server: f2fs_sync_fs+0x48/0x6c [ 58.920999] [T1501146] system_server: f2fs_do_sync_file+0x334/0x738 [ 58.921862] [T1501146] system_server: f2fs_sync_file+0x30/0x48 [ 58.922667] [T1501146] system_server: __arm64_sys_fsync+0x84/0xf8 [ 58.923506] [T1501146] system_server: el0_svc_common.llvm.12821150825140585682+0xd8/0x20c [ 58.924604] [T1501146] system_server: do_el0_svc+0x28/0xa0 [ 58.925366] [T1501146] system_server: el0_svc+0x24/0x38 [ 58.926094] [T1501146] system_server: el0_sync_handler+0x88/0xec [ 58.926920] [T1501146] system_server: el0_sync+0x1b4/0x1c0
[ 58.927681] [T1501146] -> #1 (&sbi->cp_global_sem){+.+.}-{3:3}: [ 58.928889] [T1501146] system_server: down_write+0x7c/0xe0 [ 58.929650] [T1501146] system_server: f2fs_write_checkpoint+0xbc/0x318 [ 58.930541] [T1501146] system_server: f2fs_issue_checkpoint+0x178/0x21c [ 58.931443] [T1501146] system_server: f2fs_sync_fs+0x48/0x6c [ 58.932226] [T1501146] system_server: sync_filesystem+0xac/0x130 [ 58.933053] [T1501146] system_server: generic_shutdown_super+0x38/0x150 [ 58.933958] [T1501146] system_server: kill_block_super+0x24/0x58 [ 58.934791] [T1501146] system_server: kill_f2fs_super+0xcc/0x124 [ 58.935618] [T1501146] system_server: deactivate_locked_super+0x90/0x120 [ 58.936529] [T1501146] system_server: deactivate_super+0x74/0xac [ 58.937356] [T1501146] system_server: cleanup_mnt+0x128/0x168 [ 58.938150] [T1501146] system_server: __cleanup_mnt+0x18/0x28 [ 58.938944] [T1501146] system_server: task_work_run+0xb8/0x14c [ 58.939749] [T1501146] system_server: do_notify_resume+0x114/0x1e8 [ 58.940595] [T1501146] system_server: work_pending+0xc/0x5f0
[ 58.941375] [T1501146] -> #0 (&sbi->gc_lock){+.+.}-{3:3}: [ 58.942519] [T1501146] system_server: __lock_acquire+0x1270/0x2868 [ 58.943366] [T1501146] system_server: lock_acquire+0x114/0x294 [ 58.944169] [T1501146] system_server: down_write+0x7c/0xe0 [ 58.944930] [T1501146] system_server: f2fs_issue_checkpoint+0x13c/0x21c [ 58.945831] [T1501146] system_server: f2fs_sync_fs+0x48/0x6c [ 58.946614] [T1501146] system_server: f2fs_do_sync_file+0x334/0x738 [ 58.947472] [T1501146] system_server: f2fs_ioc_commit_atomic_write+0xc8/0x14c [ 58.948439] [T1501146] system_server: __f2fs_ioctl+0x674/0x154c [ 58.949253] [T1501146] system_server: f2fs_ioctl+0x54/0x88 [ 58.950018] [T1501146] system_server: __arm64_sys_ioctl+0xa8/0x110 [ 58.950865] [T1501146] system_server: el0_svc_common.llvm.12821150825140585682+0xd8/0x20c [ 58.951965] [T1501146] system_server: do_el0_svc+0x28/0xa0 [ 58.952727] [T1501146] system_server: el0_svc+0x24/0x38 [ 58.953454] [T1501146] system_server: el0_sync_handler+0x88/0xec [ 58.954279] [T1501146] system_server: el0_sync+0x1b4/0x1c0
Cc: stable@vger.kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2684,7 +2684,8 @@ int f2fs_quota_sync(struct super_block * if (!sb_has_quota_active(sb, cnt)) continue;
- inode_lock(dqopt->files[cnt]); + if (!f2fs_sb_has_quota_ino(sbi)) + inode_lock(dqopt->files[cnt]);
/* * do_quotactl @@ -2703,7 +2704,8 @@ int f2fs_quota_sync(struct super_block * f2fs_up_read(&sbi->quota_sem); f2fs_unlock_op(sbi);
- inode_unlock(dqopt->files[cnt]); + if (!f2fs_sb_has_quota_ino(sbi)) + inode_unlock(dqopt->files[cnt]);
if (ret) break;
From: Chao Yu chao@kernel.org
commit 6b8beca0edd32075a769bfe4178ca00c0dcd22a9 upstream.
As Yanming reported in bugzilla:
https://bugzilla.kernel.org/show_bug.cgi?id=215916
The kernel message is shown below:
kernel BUG at fs/f2fs/segment.c:2560! Call Trace: allocate_segment_by_default+0x228/0x440 f2fs_allocate_data_block+0x13d1/0x31f0 do_write_page+0x18d/0x710 f2fs_outplace_write_data+0x151/0x250 f2fs_do_write_data_page+0xef9/0x1980 move_data_page+0x6af/0xbc0 do_garbage_collect+0x312f/0x46f0 f2fs_gc+0x6b0/0x3bc0 f2fs_balance_fs+0x921/0x2260 f2fs_write_single_data_page+0x16be/0x2370 f2fs_write_cache_pages+0x428/0xd00 f2fs_write_data_pages+0x96e/0xd50 do_writepages+0x168/0x550 __writeback_single_inode+0x9f/0x870 writeback_sb_inodes+0x47d/0xb20 __writeback_inodes_wb+0xb2/0x200 wb_writeback+0x4bd/0x660 wb_workfn+0x5f3/0xab0 process_one_work+0x79f/0x13e0 worker_thread+0x89/0xf60 kthread+0x26a/0x300 ret_from_fork+0x22/0x30 RIP: 0010:new_curseg+0xe8d/0x15f0
The root cause is: ckpt.valid_block_count is inconsistent with SIT table, stat info indicates filesystem has free blocks, but SIT table indicates filesystem has no free segment.
So that during garbage colloection, it triggers panic when LFS allocator fails to find free segment.
This patch tries to fix this issue by checking consistency in between ckpt.valid_block_count and block accounted from SIT.
Cc: stable@vger.kernel.org Reported-by: Ming Yan yanming@tju.edu.cn Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/f2fs.h | 4 ++-- fs/f2fs/segment.c | 33 ++++++++++++++++++++++----------- fs/f2fs/segment.h | 1 + 3 files changed, 25 insertions(+), 13 deletions(-)
--- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1117,8 +1117,8 @@ enum count_type { */ #define PAGE_TYPE_OF_BIO(type) ((type) > META ? META : (type)) enum page_type { - DATA, - NODE, + DATA = 0, + NODE = 1, /* should not change this */ META, NR_PAGE_TYPE, META_FLUSH, --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -4460,7 +4460,7 @@ static int build_sit_entries(struct f2fs unsigned int i, start, end; unsigned int readed, start_blk = 0; int err = 0; - block_t total_node_blocks = 0; + block_t sit_valid_blocks[2] = {0, 0};
do { readed = f2fs_ra_meta_pages(sbi, start_blk, BIO_MAX_VECS, @@ -4485,8 +4485,8 @@ static int build_sit_entries(struct f2fs if (err) return err; seg_info_from_raw_sit(se, &sit); - if (IS_NODESEG(se->type)) - total_node_blocks += se->valid_blocks; + + sit_valid_blocks[SE_PAGETYPE(se)] += se->valid_blocks;
if (f2fs_block_unit_discard(sbi)) { /* build discard map only one time */ @@ -4526,15 +4526,15 @@ static int build_sit_entries(struct f2fs sit = sit_in_journal(journal, i);
old_valid_blocks = se->valid_blocks; - if (IS_NODESEG(se->type)) - total_node_blocks -= old_valid_blocks; + + sit_valid_blocks[SE_PAGETYPE(se)] -= old_valid_blocks;
err = check_block_count(sbi, start, &sit); if (err) break; seg_info_from_raw_sit(se, &sit); - if (IS_NODESEG(se->type)) - total_node_blocks += se->valid_blocks; + + sit_valid_blocks[SE_PAGETYPE(se)] += se->valid_blocks;
if (f2fs_block_unit_discard(sbi)) { if (is_set_ckpt_flags(sbi, CP_TRIMMED_FLAG)) { @@ -4556,13 +4556,24 @@ static int build_sit_entries(struct f2fs } up_read(&curseg->journal_rwsem);
- if (!err && total_node_blocks != valid_node_count(sbi)) { + if (err) + return err; + + if (sit_valid_blocks[NODE] != valid_node_count(sbi)) { f2fs_err(sbi, "SIT is corrupted node# %u vs %u", - total_node_blocks, valid_node_count(sbi)); - err = -EFSCORRUPTED; + sit_valid_blocks[NODE], valid_node_count(sbi)); + return -EFSCORRUPTED; + } + + if (sit_valid_blocks[DATA] + sit_valid_blocks[NODE] > + valid_user_blocks(sbi)) { + f2fs_err(sbi, "SIT is corrupted data# %u %u vs %u", + sit_valid_blocks[DATA], sit_valid_blocks[NODE], + valid_user_blocks(sbi)); + return -EFSCORRUPTED; }
- return err; + return 0; }
static void init_free_segmap(struct f2fs_sb_info *sbi) --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -24,6 +24,7 @@
#define IS_DATASEG(t) ((t) <= CURSEG_COLD_DATA) #define IS_NODESEG(t) ((t) >= CURSEG_HOT_NODE && (t) <= CURSEG_COLD_NODE) +#define SE_PAGETYPE(se) ((IS_NODESEG((se)->type) ? NODE : DATA))
static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, unsigned short seg_type)
From: Eric Biggers ebiggers@google.com
commit b5639bb4313b9d455fc9fc4768d23a5e4ca8cb9d upstream.
Tryng to rename a directory that has all following properties fails with EINVAL and triggers the 'WARN_ON_ONCE(!fscrypt_has_encryption_key(dir))' in f2fs_match_ci_name():
- The directory is casefolded - The directory is encrypted - The directory's encryption key is not yet set up - The parent directory is *not* encrypted
The problem is incorrect handling of the lookup of ".." to get the parent reference to update. fscrypt_setup_filename() treats ".." (and ".") specially, as it's never encrypted. It's passed through as-is, and setting up the directory's key is not attempted. As the name isn't a no-key name, f2fs treats it as a "normal" name and attempts a casefolded comparison. That breaks the assumption of the WARN_ON_ONCE() in f2fs_match_ci_name() which assumes that for encrypted directories, casefolded comparisons only happen when the directory's key is set up.
We could just remove this WARN_ON_ONCE(). However, since casefolding is always a no-op on "." and ".." anyway, let's instead just not casefold these names. This results in the standard bytewise comparison.
Fixes: 7ad08a58bf67 ("f2fs: Handle casefolding with Encryption") Cc: stable@vger.kernel.org # v5.11+ Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Gabriel Krisman Bertazi krisman@collabora.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/dir.c | 3 ++- fs/f2fs/f2fs.h | 10 +++++----- fs/f2fs/hash.c | 11 ++++++----- 3 files changed, 13 insertions(+), 11 deletions(-)
--- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -82,7 +82,8 @@ int f2fs_init_casefolded_name(const stru #if IS_ENABLED(CONFIG_UNICODE) struct super_block *sb = dir->i_sb;
- if (IS_CASEFOLDED(dir)) { + if (IS_CASEFOLDED(dir) && + !is_dot_dotdot(fname->usr_fname->name, fname->usr_fname->len)) { fname->cf_name.name = f2fs_kmem_cache_alloc(f2fs_cf_name_slab, GFP_NOFS, false, F2FS_SB(sb)); if (!fname->cf_name.name) --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -508,11 +508,11 @@ struct f2fs_filename { #if IS_ENABLED(CONFIG_UNICODE) /* * For casefolded directories: the casefolded name, but it's left NULL - * if the original name is not valid Unicode, if the directory is both - * casefolded and encrypted and its encryption key is unavailable, or if - * the filesystem is doing an internal operation where usr_fname is also - * NULL. In all these cases we fall back to treating the name as an - * opaque byte sequence. + * if the original name is not valid Unicode, if the original name is + * "." or "..", if the directory is both casefolded and encrypted and + * its encryption key is unavailable, or if the filesystem is doing an + * internal operation where usr_fname is also NULL. In all these cases + * we fall back to treating the name as an opaque byte sequence. */ struct fscrypt_str cf_name; #endif --- a/fs/f2fs/hash.c +++ b/fs/f2fs/hash.c @@ -91,7 +91,7 @@ static u32 TEA_hash_name(const u8 *p, si /* * Compute @fname->hash. For all directories, @fname->disk_name must be set. * For casefolded directories, @fname->usr_fname must be set, and also - * @fname->cf_name if the filename is valid Unicode. + * @fname->cf_name if the filename is valid Unicode and is not "." or "..". */ void f2fs_hash_filename(const struct inode *dir, struct f2fs_filename *fname) { @@ -110,10 +110,11 @@ void f2fs_hash_filename(const struct ino /* * If the casefolded name is provided, hash it instead of the * on-disk name. If the casefolded name is *not* provided, that - * should only be because the name wasn't valid Unicode, so fall - * back to treating the name as an opaque byte sequence. Note - * that to handle encrypted directories, the fallback must use - * usr_fname (plaintext) rather than disk_name (ciphertext). + * should only be because the name wasn't valid Unicode or was + * "." or "..", so fall back to treating the name as an opaque + * byte sequence. Note that to handle encrypted directories, + * the fallback must use usr_fname (plaintext) rather than + * disk_name (ciphertext). */ WARN_ON_ONCE(!fname->usr_fname->name); if (fname->cf_name.name) {
From: Chao Yu chao@kernel.org
commit 958ed92922028ec67f504dcdc72bfdfd0f43936a upstream.
This patch tries to fix permission consistency issue as all other mainline filesystems.
Since the initial introduction of (posix) fallocate back at the turn of the century, it has been possible to use this syscall to change the user-visible contents of files. This can happen by extending the file size during a preallocation, or through any of the newer modes (punch, zero, collapse, insert range). Because the call can be used to change file contents, we should treat it like we do any other modification to a file -- update the mtime, and drop set[ug]id privileges/capabilities.
The VFS function file_modified() does all this for us if pass it a locked inode, so let's make fallocate drop permissions correctly.
Cc: stable@kernel.org Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/file.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1774,6 +1774,10 @@ static long f2fs_fallocate(struct file *
inode_lock(inode);
+ ret = file_modified(file); + if (ret) + goto out; + if (mode & FALLOC_FL_PUNCH_HOLE) { if (offset >= inode->i_size) goto out;
From: Chao Yu chao@kernel.org
commit 677a82b44ebf263d4f9a0cfbd576a6ade797a07b upstream.
Yanming reported a kernel bug in Bugzilla kernel [1], which can be reproduced. The bug message is:
The kernel message is shown below:
kernel BUG at fs/inode.c:611! Call Trace: evict+0x282/0x4e0 __dentry_kill+0x2b2/0x4d0 dput+0x2dd/0x720 do_renameat2+0x596/0x970 __x64_sys_rename+0x78/0x90 do_syscall_64+0x3b/0x90
[1] https://bugzilla.kernel.org/show_bug.cgi?id=215895
The bug is due to fuzzed inode has both inline_data and encrypted flags. During f2fs_evict_inode(), as the inode was deleted by rename(), it will cause inline data conversion due to conflicting flags. The page cache will be polluted and the panic will be triggered in clear_inode().
Try fixing the bug by doing more sanity checks for inline data inode in sanity_check_inode().
Cc: stable@vger.kernel.org Reported-by: Ming Yan yanming@tju.edu.cn Signed-off-by: Chao Yu chao.yu@oppo.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/f2fs.h | 1 + fs/f2fs/inline.c | 29 ++++++++++++++++++++++++----- fs/f2fs/inode.c | 3 +-- 3 files changed, 26 insertions(+), 7 deletions(-)
--- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4052,6 +4052,7 @@ extern struct kmem_cache *f2fs_inode_ent * inline.c */ bool f2fs_may_inline_data(struct inode *inode); +bool f2fs_sanity_check_inline_data(struct inode *inode); bool f2fs_may_inline_dentry(struct inode *inode); void f2fs_do_read_inline_data(struct page *page, struct page *ipage); void f2fs_truncate_inline_inode(struct inode *inode, --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -14,21 +14,40 @@ #include "node.h" #include <trace/events/f2fs.h>
-bool f2fs_may_inline_data(struct inode *inode) +static bool support_inline_data(struct inode *inode) { if (f2fs_is_atomic_file(inode)) return false; - if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) return false; - if (i_size_read(inode) > MAX_INLINE_DATA(inode)) return false; + return true; +} + +bool f2fs_may_inline_data(struct inode *inode) +{ + if (!support_inline_data(inode)) + return false; + + return !f2fs_post_read_required(inode); +}
- if (f2fs_post_read_required(inode)) +bool f2fs_sanity_check_inline_data(struct inode *inode) +{ + if (!f2fs_has_inline_data(inode)) return false;
- return true; + if (!support_inline_data(inode)) + return true; + + /* + * used by sanity_check_inode(), when disk layout fields has not + * been synchronized to inmem fields. + */ + return (S_ISREG(inode->i_mode) && + (file_is_encrypt(inode) || file_is_verity(inode) || + (F2FS_I(inode)->i_flags & F2FS_COMPR_FL))); }
bool f2fs_may_inline_dentry(struct inode *inode) --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -276,8 +276,7 @@ static bool sanity_check_inode(struct in } }
- if (f2fs_has_inline_data(inode) && - (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode))) { + if (f2fs_sanity_check_inline_data(inode)) { set_sbi_flag(sbi, SBI_NEED_FSCK); f2fs_warn(sbi, "%s: inode (ino=%lx, mode=%u) should not have inline_data, run fsck to fix", __func__, inode->i_ino, inode->i_mode);
From: Mikulas Patocka mpatocka@redhat.com
commit 22682a07acc308ef78681572e19502ce8893c4d4 upstream.
Commit c087c6e7b551 ("objtool: Fix type of reloc::addend") failed to appreciate cross building from ILP32 hosts, where 'int' == 'long' and the issue persists.
As such, use s64/int64_t/Elf64_Sxword for this field and suffer the pain that is ISO C99 printf formats for it.
Fixes: c087c6e7b551 ("objtool: Fix type of reloc::addend") Signed-off-by: Mikulas Patocka mpatocka@redhat.com [peterz: reword changelog, s/long long/s64/] Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/alpine.LRH.2.02.2205161041260.11556@file01.intrane... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/objtool/check.c | 9 +++++---- tools/objtool/elf.c | 2 +- tools/objtool/include/objtool/elf.h | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-)
--- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -5,6 +5,7 @@
#include <string.h> #include <stdlib.h> +#include <inttypes.h> #include <sys/mman.h>
#include <arch/elf.h> @@ -560,12 +561,12 @@ static int add_dead_ends(struct objtool_ else if (reloc->addend == reloc->sym->sec->sh.sh_size) { insn = find_last_insn(file, reloc->sym->sec); if (!insn) { - WARN("can't find unreachable insn at %s+0x%lx", + WARN("can't find unreachable insn at %s+0x%" PRIx64, reloc->sym->sec->name, reloc->addend); return -1; } } else { - WARN("can't find unreachable insn at %s+0x%lx", + WARN("can't find unreachable insn at %s+0x%" PRIx64, reloc->sym->sec->name, reloc->addend); return -1; } @@ -595,12 +596,12 @@ reachable: else if (reloc->addend == reloc->sym->sec->sh.sh_size) { insn = find_last_insn(file, reloc->sym->sec); if (!insn) { - WARN("can't find reachable insn at %s+0x%lx", + WARN("can't find reachable insn at %s+0x%" PRIx64, reloc->sym->sec->name, reloc->addend); return -1; } } else { - WARN("can't find reachable insn at %s+0x%lx", + WARN("can't find reachable insn at %s+0x%" PRIx64, reloc->sym->sec->name, reloc->addend); return -1; } --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -546,7 +546,7 @@ static struct section *elf_create_reloc_ int reltype);
int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, - unsigned int type, struct symbol *sym, long addend) + unsigned int type, struct symbol *sym, s64 addend) { struct reloc *reloc;
--- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -73,7 +73,7 @@ struct reloc { struct symbol *sym; unsigned long offset; unsigned int type; - long addend; + s64 addend; int idx; bool jump_table_start; }; @@ -135,7 +135,7 @@ struct elf *elf_open_read(const char *na struct section *elf_create_section(struct elf *elf, const char *name, unsigned int sh_flags, size_t entsize, int nr);
int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, - unsigned int type, struct symbol *sym, long addend); + unsigned int type, struct symbol *sym, s64 addend); int elf_add_reloc_to_insn(struct elf *elf, struct section *sec, unsigned long offset, unsigned int type, struct section *insn_sec, unsigned long insn_off);
From: Peter Zijlstra peterz@infradead.org
commit ead165fa1042247b033afad7be4be9b815d04ade upstream.
Nathan reported objtool failing with the following messages:
warning: objtool: no non-local symbols !? warning: objtool: gelf_update_symshndx: invalid section index
The problem is due to commit 4abff6d48dbc ("objtool: Fix code relocs vs weak symbols") failing to consider the case where an object would have no non-local symbols.
The problem that commit tries to address is adding a STB_LOCAL symbol to the symbol table in light of the ELF spec's requirement that:
In each symbol table, all symbols with STB_LOCAL binding preced the weak and global symbols. As ``Sections'' above describes, a symbol table section's sh_info section header member holds the symbol table index for the first non-local symbol.
The approach taken is to find this first non-local symbol, move that to the end and then re-use the freed spot to insert a new local symbol and increment sh_info.
Except it never considered the case of object files without global symbols and got a whole bunch of details wrong -- so many in fact that it is a wonder it ever worked :/
Specifically:
- It failed to re-hash the symbol on the new index, so a subsequent find_symbol_by_index() would not find it at the new location and a query for the old location would now return a non-deterministic choice between the old and new symbol.
- It failed to appreciate that the GElf wrappers are not a valid disk format (it works because GElf is basically Elf64 and we only support x86_64 atm.)
- It failed to fully appreciate how horrible the libelf API really is and got the gelf_update_symshndx() call pretty much completely wrong; with the direct consequence that if inserting a second STB_LOCAL symbol would require moving the same STB_GLOBAL symbol again it would completely come unstuck.
Write a new elf_update_symbol() function that wraps all the magic required to update or create a new symbol at a given index.
Specifically, gelf_update_sym*() require an @ndx argument that is relative to the @data argument; this means you have to manually iterate the section data descriptor list and update @ndx.
Fixes: 4abff6d48dbc ("objtool: Fix code relocs vs weak symbols") Reported-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Josh Poimboeuf jpoimboe@kernel.org Tested-by: Nathan Chancellor nathan@kernel.org Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/YoPCTEYjoPqE4ZxB@hirez.programming.kicks-ass.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/objtool/elf.c | 198 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 69 deletions(-)
--- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -374,6 +374,9 @@ static void elf_add_symbol(struct elf *e struct list_head *entry; struct rb_node *pnode;
+ INIT_LIST_HEAD(&sym->pv_target); + sym->alias = sym; + sym->type = GELF_ST_TYPE(sym->sym.st_info); sym->bind = GELF_ST_BIND(sym->sym.st_info);
@@ -435,8 +438,6 @@ static int read_symbols(struct elf *elf) return -1; } memset(sym, 0, sizeof(*sym)); - INIT_LIST_HEAD(&sym->pv_target); - sym->alias = sym;
sym->idx = i;
@@ -600,24 +601,21 @@ static void elf_dirty_reloc_sym(struct e }
/* - * Move the first global symbol, as per sh_info, into a new, higher symbol - * index. This fees up the shndx for a new local symbol. + * The libelf API is terrible; gelf_update_sym*() takes a data block relative + * index value, *NOT* the symbol index. As such, iterate the data blocks and + * adjust index until it fits. + * + * If no data block is found, allow adding a new data block provided the index + * is only one past the end. */ -static int elf_move_global_symbol(struct elf *elf, struct section *symtab, - struct section *symtab_shndx) +static int elf_update_symbol(struct elf *elf, struct section *symtab, + struct section *symtab_shndx, struct symbol *sym) { - Elf_Data *data, *shndx_data = NULL; - Elf32_Word first_non_local; - struct symbol *sym; - Elf_Scn *s; - - first_non_local = symtab->sh.sh_info; - - sym = find_symbol_by_index(elf, first_non_local); - if (!sym) { - WARN("no non-local symbols !?"); - return first_non_local; - } + Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF; + Elf_Data *symtab_data = NULL, *shndx_data = NULL; + Elf64_Xword entsize = symtab->sh.sh_entsize; + int max_idx, idx = sym->idx; + Elf_Scn *s, *t = NULL;
s = elf_getscn(elf->elf, symtab->idx); if (!s) { @@ -625,79 +623,124 @@ static int elf_move_global_symbol(struct return -1; }
- data = elf_newdata(s); - if (!data) { - WARN_ELF("elf_newdata"); - return -1; + if (symtab_shndx) { + t = elf_getscn(elf->elf, symtab_shndx->idx); + if (!t) { + WARN_ELF("elf_getscn"); + return -1; + } }
- data->d_buf = &sym->sym; - data->d_size = sizeof(sym->sym); - data->d_align = 1; - data->d_type = ELF_T_SYM; + for (;;) { + /* get next data descriptor for the relevant sections */ + symtab_data = elf_getdata(s, symtab_data); + if (t) + shndx_data = elf_getdata(t, shndx_data); + + /* end-of-list */ + if (!symtab_data) { + void *buf; + + if (idx) { + /* we don't do holes in symbol tables */ + WARN("index out of range"); + return -1; + }
- sym->idx = symtab->sh.sh_size / sizeof(sym->sym); - elf_dirty_reloc_sym(elf, sym); + /* if @idx == 0, it's the next contiguous entry, create it */ + symtab_data = elf_newdata(s); + if (t) + shndx_data = elf_newdata(t); + + buf = calloc(1, entsize); + if (!buf) { + WARN("malloc"); + return -1; + }
- symtab->sh.sh_info += 1; - symtab->sh.sh_size += data->d_size; - symtab->changed = true; + symtab_data->d_buf = buf; + symtab_data->d_size = entsize; + symtab_data->d_align = 1; + symtab_data->d_type = ELF_T_SYM; + + symtab->sh.sh_size += entsize; + symtab->changed = true; + + if (t) { + shndx_data->d_buf = &sym->sec->idx; + shndx_data->d_size = sizeof(Elf32_Word); + shndx_data->d_align = sizeof(Elf32_Word); + shndx_data->d_type = ELF_T_WORD;
- if (symtab_shndx) { - s = elf_getscn(elf->elf, symtab_shndx->idx); - if (!s) { - WARN_ELF("elf_getscn"); + symtab_shndx->sh.sh_size += sizeof(Elf32_Word); + symtab_shndx->changed = true; + } + + break; + } + + /* empty blocks should not happen */ + if (!symtab_data->d_size) { + WARN("zero size data"); return -1; }
- shndx_data = elf_newdata(s); + /* is this the right block? */ + max_idx = symtab_data->d_size / entsize; + if (idx < max_idx) + break; + + /* adjust index and try again */ + idx -= max_idx; + } + + /* something went side-ways */ + if (idx < 0) { + WARN("negative index"); + return -1; + } + + /* setup extended section index magic and write the symbol */ + if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) { + sym->sym.st_shndx = shndx; + if (!shndx_data) + shndx = 0; + } else { + sym->sym.st_shndx = SHN_XINDEX; if (!shndx_data) { - WARN_ELF("elf_newshndx_data"); + WARN("no .symtab_shndx"); return -1; } + }
- shndx_data->d_buf = &sym->sec->idx; - shndx_data->d_size = sizeof(Elf32_Word); - shndx_data->d_align = 4; - shndx_data->d_type = ELF_T_WORD; - - symtab_shndx->sh.sh_size += 4; - symtab_shndx->changed = true; + if (!gelf_update_symshndx(symtab_data, shndx_data, idx, &sym->sym, shndx)) { + WARN_ELF("gelf_update_symshndx"); + return -1; }
- return first_non_local; + return 0; }
static struct symbol * elf_create_section_symbol(struct elf *elf, struct section *sec) { struct section *symtab, *symtab_shndx; - Elf_Data *shndx_data = NULL; - struct symbol *sym; - Elf32_Word shndx; + Elf32_Word first_non_local, new_idx; + struct symbol *sym, *old;
symtab = find_section_by_name(elf, ".symtab"); if (symtab) { symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); - if (symtab_shndx) - shndx_data = symtab_shndx->data; } else { WARN("no .symtab"); return NULL; }
- sym = malloc(sizeof(*sym)); + sym = calloc(1, sizeof(*sym)); if (!sym) { perror("malloc"); return NULL; } - memset(sym, 0, sizeof(*sym)); - - sym->idx = elf_move_global_symbol(elf, symtab, symtab_shndx); - if (sym->idx < 0) { - WARN("elf_move_global_symbol"); - return NULL; - }
sym->name = sec->name; sym->sec = sec; @@ -707,24 +750,41 @@ elf_create_section_symbol(struct elf *el // st_other 0 // st_value 0 // st_size 0 - shndx = sec->idx; - if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) { - sym->sym.st_shndx = shndx; - if (!shndx_data) - shndx = 0; - } else { - sym->sym.st_shndx = SHN_XINDEX; - if (!shndx_data) { - WARN("no .symtab_shndx"); + + /* + * Move the first global symbol, as per sh_info, into a new, higher + * symbol index. This fees up a spot for a new local symbol. + */ + first_non_local = symtab->sh.sh_info; + new_idx = symtab->sh.sh_size / symtab->sh.sh_entsize; + old = find_symbol_by_index(elf, first_non_local); + if (old) { + old->idx = new_idx; + + hlist_del(&old->hash); + elf_hash_add(symbol, &old->hash, old->idx); + + elf_dirty_reloc_sym(elf, old); + + if (elf_update_symbol(elf, symtab, symtab_shndx, old)) { + WARN("elf_update_symbol move"); return NULL; } + + new_idx = first_non_local; }
- if (!gelf_update_symshndx(symtab->data, shndx_data, sym->idx, &sym->sym, shndx)) { - WARN_ELF("gelf_update_symshndx"); + sym->idx = new_idx; + if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) { + WARN("elf_update_symbol"); return NULL; }
+ /* + * Either way, we added a LOCAL symbol. + */ + symtab->sh.sh_info += 1; + elf_add_symbol(elf, sym);
return sym;
From: Johannes Berg johannes.berg@intel.com
commit 2965c4cdf7ad9ce0796fac5e57debb9519ea721e upstream.
In ieee80211_vif_use_reserved_context(), when we have an old context and the new context's replace_state is set to IEEE80211_CHANCTX_REPLACE_NONE, we free the old context in ieee80211_vif_use_reserved_reassign(). Therefore, we cannot check the old_ctx anymore, so we should set it to NULL after this point.
However, since the new_ctx replace state is clearly not IEEE80211_CHANCTX_REPLACES_OTHER, we're not going to do anything else in this function and can just return to avoid accessing the freed old_ctx.
Cc: stable@vger.kernel.org Fixes: 5bcae31d9cb1 ("mac80211: implement multi-vif in-place reservations") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220601091926.df419d91b165.I17a9b3894ff0b8323ce2a... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mac80211/chan.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
--- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1749,12 +1749,9 @@ int ieee80211_vif_use_reserved_context(s
if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) { if (old_ctx) - err = ieee80211_vif_use_reserved_reassign(sdata); - else - err = ieee80211_vif_use_reserved_assign(sdata); + return ieee80211_vif_use_reserved_reassign(sdata);
- if (err) - return err; + return ieee80211_vif_use_reserved_assign(sdata); }
/*
From: Johannes Berg johannes.berg@intel.com
commit d1f6530c3e373ddd7c76b05646052a27eead14ad upstream.
When no table data was read from ACPI, then filling the data and returning success here will fill zero values, which means transmit power will be limited to 0 dBm. This is clearly not intended.
Return an error from iwl_sar_geo_init() if there's no data to fill into the command structure.
Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg johannes.berg@intel.com Fixes: 78a19d5285d9 ("iwlwifi: mvm: Read the PPAG and SAR tables at INIT stage") Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20220517120044.bc45923b74e9.Id2b4362234b7f8ced82c5... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c @@ -937,6 +937,9 @@ int iwl_sar_geo_init(struct iwl_fw_runti { int i, j;
+ if (!fwrt->geo_enabled) + return -ENODATA; + if (!iwl_sar_geo_support(fwrt)) return -EOPNOTSUPP;
From: Emmanuel Grumbach emmanuel.grumbach@intel.com
commit 9d096e3d3061dbf4ee10e2b59fc2c06e05bdb997 upstream.
When we reconfig we must not send the MAC_POWER command that relates to a MAC that was not yet added to the firmware.
Ignore those in the iterator.
Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach emmanuel.grumbach@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20220517120044.ed2ffc8ce732.If786e19512d0da4334a63... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/intel/iwlwifi/mvm/power.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -563,6 +563,9 @@ static void iwl_mvm_power_get_vifs_itera struct iwl_power_vifs *power_iterator = _data; bool active = mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < NUM_PHY_CTX;
+ if (!mvmvif->uploaded) + return; + switch (ieee80211_vif_type_p2p(vif)) { case NL80211_IFTYPE_P2P_DEVICE: break;
From: Avraham Stern avraham.stern@intel.com
commit 55cf10488d7a9fa1b1b473a5e44a80666932e094 upstream.
The SAP data header has some fields that are marked as reserved but are actually in use by CSME. Clear those fields before sending the data to avoid having random values in those fields.
Cc: stable@vger.kernel.org Signed-off-by: Avraham Stern avraham.stern@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20220517120045.8dd3423cf683.I02976028eaa6aab395cb2... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/intel/iwlwifi/mei/main.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -493,6 +493,7 @@ void iwl_mei_add_data_to_ring(struct sk_ if (cb_tx) { struct iwl_sap_cb_data *cb_hdr = skb_push(skb, sizeof(*cb_hdr));
+ memset(cb_hdr, 0, sizeof(*cb_hdr)); cb_hdr->hdr.type = cpu_to_le16(SAP_MSG_CB_DATA_PACKET); cb_hdr->hdr.len = cpu_to_le16(skb->len - sizeof(cb_hdr->hdr)); cb_hdr->hdr.seq_num = cpu_to_le32(atomic_inc_return(&mei->sap_seq_no));
From: Johannes Berg johannes.berg@intel.com
commit 78488a64aea94a3336ee97f345c1496e9bc5ebdf upstream.
If SKB allocation fails, continue rather than using the NULL pointer.
Coverity CID: 1497650
Cc: stable@vger.kernel.org Fixes: 2da4366f9e2c ("iwlwifi: mei: add the driver to allow cooperation with CSME") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Gregory Greenman gregory.greenman@intel.com Link: https://lore.kernel.org/r/20220517120045.90c1b1fd534e.Ibb42463e74d0ec7d36ec8... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/intel/iwlwifi/mei/main.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -1020,6 +1020,8 @@ static void iwl_mei_handle_sap_data(stru
/* We need enough room for the WiFi header + SNAP + IV */ skb = netdev_alloc_skb(netdev, len + QOS_HDR_IV_SNAP_LEN); + if (!skb) + continue;
skb_reserve(skb, QOS_HDR_IV_SNAP_LEN); ethhdr = skb_push(skb, sizeof(*ethhdr));
From: Miaoqian Lin linmq006@gmail.com
commit a508e33956b538e034ed5df619a73ec7c15bda72 upstream.
of_parse_phandle() 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: 00d93611f002 ("ipmi:ipmb: Add the ability to have a separate slave and master device") Signed-off-by: Miaoqian Lin linmq006@gmail.com Message-Id: 20220512044445.3102-1-linmq006@gmail.com Cc: stable@vger.kernel.org # v5.17+ Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/ipmi/ipmi_ipmb.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/char/ipmi/ipmi_ipmb.c +++ b/drivers/char/ipmi/ipmi_ipmb.c @@ -476,6 +476,7 @@ static int ipmi_ipmb_probe(struct i2c_cl slave_np = of_parse_phandle(dev->of_node, "slave-dev", 0); if (slave_np) { slave_adap = of_get_i2c_adapter_by_node(slave_np); + of_node_put(slave_np); if (!slave_adap) { dev_notice(&client->dev, "Could not find slave adapter\n");
From: Zhihao Cheng chengzhihao1@huawei.com
commit 68f4c6eba70df70a720188bce95c85570ddfcc87 upstream.
Commit 505a666ee3fc ("writeback: plug writeback in wb_writeback() and writeback_inodes_wb()") has us holding a plug during wb_writeback, which may cause a potential ABBA dead lock:
wb_writeback fat_file_fsync blk_start_plug(&plug) for (;;) { iter i-1: some reqs have been added into plug->mq_list // LOCK A iter i: progress = __writeback_inodes_wb(wb, work) . writeback_sb_inodes // fat's bdev . __writeback_single_inode . . generic_writepages . . __block_write_full_page . . . . __generic_file_fsync . . . . sync_inode_metadata . . . . writeback_single_inode . . . . __writeback_single_inode . . . . fat_write_inode . . . . __fat_write_inode . . . . sync_dirty_buffer // fat's bdev . . . . lock_buffer(bh) // LOCK B . . . . submit_bh . . . . blk_mq_get_tag // LOCK A . . . trylock_buffer(bh) // LOCK B . . . redirty_page_for_writepage . . . wbc->pages_skipped++ . . --wbc->nr_to_write . wrote += write_chunk - wbc.nr_to_write // wrote > 0 . requeue_inode . redirty_tail_locked if (progress) // progress > 0 continue; iter i+1: queue_io // similar process with iter i, infinite for-loop ! } blk_finish_plug(&plug) // flush plug won't be called
Above process triggers a hungtask like: [ 399.044861] INFO: task bb:2607 blocked for more than 30 seconds. [ 399.046824] Not tainted 5.18.0-rc1-00005-gefae4d9eb6a2-dirty [ 399.051539] task:bb state:D stack: 0 pid: 2607 ppid: 2426 flags:0x00004000 [ 399.051556] Call Trace: [ 399.051570] __schedule+0x480/0x1050 [ 399.051592] schedule+0x92/0x1a0 [ 399.051602] io_schedule+0x22/0x50 [ 399.051613] blk_mq_get_tag+0x1d3/0x3c0 [ 399.051640] __blk_mq_alloc_requests+0x21d/0x3f0 [ 399.051657] blk_mq_submit_bio+0x68d/0xca0 [ 399.051674] __submit_bio+0x1b5/0x2d0 [ 399.051708] submit_bio_noacct+0x34e/0x720 [ 399.051718] submit_bio+0x3b/0x150 [ 399.051725] submit_bh_wbc+0x161/0x230 [ 399.051734] __sync_dirty_buffer+0xd1/0x420 [ 399.051744] sync_dirty_buffer+0x17/0x20 [ 399.051750] __fat_write_inode+0x289/0x310 [ 399.051766] fat_write_inode+0x2a/0xa0 [ 399.051783] __writeback_single_inode+0x53c/0x6f0 [ 399.051795] writeback_single_inode+0x145/0x200 [ 399.051803] sync_inode_metadata+0x45/0x70 [ 399.051856] __generic_file_fsync+0xa3/0x150 [ 399.051880] fat_file_fsync+0x1d/0x80 [ 399.051895] vfs_fsync_range+0x40/0xb0 [ 399.051929] __x64_sys_fsync+0x18/0x30
In my test, 'need_resched()' (which is imported by 590dca3a71 "fs-writeback: unplug before cond_resched in writeback_sb_inodes") in function 'writeback_sb_inodes()' seldom comes true, unless cond_resched() is deleted from write_cache_pages().
Fix it by correcting wrote number according number of skipped pages in writeback_sb_inodes().
Goto Link to find a reproducer.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=215837 Cc: stable@vger.kernel.org # v4.3 Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220510133805.1988292-1-chengzhihao1@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fs-writeback.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
--- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -1779,11 +1779,12 @@ static long writeback_sb_inodes(struct s }; unsigned long start_time = jiffies; long write_chunk; - long wrote = 0; /* count both pages and inodes */ + long total_wrote = 0; /* count both pages and inodes */
while (!list_empty(&wb->b_io)) { struct inode *inode = wb_inode(wb->b_io.prev); struct bdi_writeback *tmp_wb; + long wrote;
if (inode->i_sb != sb) { if (work->sb) { @@ -1859,7 +1860,9 @@ static long writeback_sb_inodes(struct s
wbc_detach_inode(&wbc); work->nr_pages -= write_chunk - wbc.nr_to_write; - wrote += write_chunk - wbc.nr_to_write; + wrote = write_chunk - wbc.nr_to_write - wbc.pages_skipped; + wrote = wrote < 0 ? 0 : wrote; + total_wrote += wrote;
if (need_resched()) { /* @@ -1881,7 +1884,7 @@ static long writeback_sb_inodes(struct s tmp_wb = inode_to_wb_and_lock_list(inode); spin_lock(&inode->i_lock); if (!(inode->i_state & I_DIRTY_ALL)) - wrote++; + total_wrote++; requeue_inode(inode, tmp_wb, &wbc); inode_sync_complete(inode); spin_unlock(&inode->i_lock); @@ -1895,14 +1898,14 @@ static long writeback_sb_inodes(struct s * bail out to wb_writeback() often enough to check * background threshold and other termination conditions. */ - if (wrote) { + if (total_wrote) { if (time_is_before_jiffies(start_time + HZ / 10UL)) break; if (work->nr_pages <= 0) break; } } - return wrote; + return total_wrote; }
static long __writeback_inodes_wb(struct bdi_writeback *wb,
From: Aditya Garg gargaditya08@live.com
commit 155ca952c7ca19aa32ecfb7373a32bbc2e1ec6eb upstream.
On Apple T2 Macs, when Linux attempts to read the db and dbx efi variables at early boot to load UEFI Secure Boot certificates, a page fault occurs in Apple firmware code and EFI runtime services are disabled with the following logs:
[Firmware Bug]: Page fault caused by firmware at PA: 0xffffb1edc0068000 WARNING: CPU: 3 PID: 104 at arch/x86/platform/efi/quirks.c:735 efi_crash_gracefully_on_page_fault+0x50/0xf0 (Removed some logs from here) Call Trace: <TASK> page_fault_oops+0x4f/0x2c0 ? search_bpf_extables+0x6b/0x80 ? search_module_extables+0x50/0x80 ? search_exception_tables+0x5b/0x60 kernelmode_fixup_or_oops+0x9e/0x110 __bad_area_nosemaphore+0x155/0x190 bad_area_nosemaphore+0x16/0x20 do_kern_addr_fault+0x8c/0xa0 exc_page_fault+0xd8/0x180 asm_exc_page_fault+0x1e/0x30 (Removed some logs from here) ? __efi_call+0x28/0x30 ? switch_mm+0x20/0x30 ? efi_call_rts+0x19a/0x8e0 ? process_one_work+0x222/0x3f0 ? worker_thread+0x4a/0x3d0 ? kthread+0x17a/0x1a0 ? process_one_work+0x3f0/0x3f0 ? set_kthread_struct+0x40/0x40 ? ret_from_fork+0x22/0x30 </TASK> ---[ end trace 1f82023595a5927f ]--- efi: Froze efi_rts_wq and disabled EFI Runtime Services integrity: Couldn't get size: 0x8000000000000015 integrity: MODSIGN: Couldn't get UEFI db list efi: EFI Runtime Services are disabled! integrity: Couldn't get size: 0x8000000000000015 integrity: Couldn't get UEFI dbx list integrity: Couldn't get size: 0x8000000000000015 integrity: Couldn't get mokx list integrity: Couldn't get size: 0x80000000
So we avoid reading these UEFI variables and thus prevent the crash.
Cc: stable@vger.kernel.org Signed-off-by: Aditya Garg gargaditya08@live.com Reviewed-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/integrity/platform_certs/keyring_handler.h | 8 ++++ security/integrity/platform_certs/load_uefi.c | 33 ++++++++++++++++++++ 2 files changed, 41 insertions(+)
--- a/security/integrity/platform_certs/keyring_handler.h +++ b/security/integrity/platform_certs/keyring_handler.h @@ -35,3 +35,11 @@ efi_element_handler_t get_handler_for_mo efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type);
#endif + +#ifndef UEFI_QUIRK_SKIP_CERT +#define UEFI_QUIRK_SKIP_CERT(vendor, product) \ + .matches = { \ + DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ + DMI_MATCH(DMI_PRODUCT_NAME, product), \ + }, +#endif --- a/security/integrity/platform_certs/load_uefi.c +++ b/security/integrity/platform_certs/load_uefi.c @@ -3,6 +3,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/cred.h> +#include <linux/dmi.h> #include <linux/err.h> #include <linux/efi.h> #include <linux/slab.h> @@ -13,6 +14,31 @@ #include "keyring_handler.h"
/* + * On T2 Macs reading the db and dbx efi variables to load UEFI Secure Boot + * certificates causes occurrence of a page fault in Apple's firmware and + * a crash disabling EFI runtime services. The following quirk skips reading + * these variables. + */ +static const struct dmi_system_id uefi_skip_cert[] = { + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,2") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,3") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro15,4") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,2") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,3") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookPro16,4") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir8,2") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacBookAir9,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacMini8,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") }, + { UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") }, + { } +}; + +/* * Look to see if a UEFI variable called MokIgnoreDB exists and return true if * it does. * @@ -138,6 +164,13 @@ static int __init load_uefi_certs(void) unsigned long dbsize = 0, dbxsize = 0, mokxsize = 0; efi_status_t status; int rc = 0; + const struct dmi_system_id *dmi_id; + + dmi_id = dmi_first_match(uefi_skip_cert); + if (dmi_id) { + pr_err("Reading UEFI Secure Boot Certs is not supported on T2 Macs.\n"); + return false; + }
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) return false;
From: Jan Kara jack@suse.cz
commit 70456e5210f40ffdb8f6d905acfdcec5bd5fad9e upstream.
bfq_setup_cooperator() can mark bic as stably merged even though it decides to not merge its bfqqs (when bfq_setup_merge() returns NULL). Make sure to mark bic as stably merged only if we are really going to merge bfqqs.
CC: stable@vger.kernel.org Tested-by: "yukuai (C)" yukuai3@huawei.com Fixes: 430a67f9d616 ("block, bfq: merge bursts of newly-created queues") Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-1-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-iosched.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2899,9 +2899,12 @@ bfq_setup_cooperator(struct bfq_data *bf struct bfq_queue *new_bfqq = bfq_setup_merge(bfqq, stable_merge_bfqq);
- bic->stably_merged = true; - if (new_bfqq && new_bfqq->bic) - new_bfqq->bic->stably_merged = true; + if (new_bfqq) { + bic->stably_merged = true; + if (new_bfqq->bic) + new_bfqq->bic->stably_merged = + true; + } return new_bfqq; } else return NULL;
From: Jan Kara jack@suse.cz
commit c1cee4ab36acef271be9101590756ed0c0c374d9 upstream.
It can happen that the parent of a bfqq changes between the moment we decide two queues are worth to merge (and set bic->stable_merge_bfqq) and the moment bfq_setup_merge() is called. This can happen e.g. because the process submitted IO for a different cgroup and thus bfqq got reparented. It can even happen that the bfqq we are merging with has parent cgroup that is already offline and going to be destroyed in which case the merge can lead to use-after-free issues such as:
BUG: KASAN: use-after-free in __bfq_deactivate_entity+0x9cb/0xa50 Read of size 8 at addr ffff88800693c0c0 by task runc:[2:INIT]/10544
CPU: 0 PID: 10544 Comm: runc:[2:INIT] Tainted: G E 5.15.2-0.g5fb85fd-default #1 openSUSE Tumbleweed (unreleased) f1f3b891c72369aebecd2e43e4641a6358867c70 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014 Call Trace: <IRQ> dump_stack_lvl+0x46/0x5a print_address_description.constprop.0+0x1f/0x140 ? __bfq_deactivate_entity+0x9cb/0xa50 kasan_report.cold+0x7f/0x11b ? __bfq_deactivate_entity+0x9cb/0xa50 __bfq_deactivate_entity+0x9cb/0xa50 ? update_curr+0x32f/0x5d0 bfq_deactivate_entity+0xa0/0x1d0 bfq_del_bfqq_busy+0x28a/0x420 ? resched_curr+0x116/0x1d0 ? bfq_requeue_bfqq+0x70/0x70 ? check_preempt_wakeup+0x52b/0xbc0 __bfq_bfqq_expire+0x1a2/0x270 bfq_bfqq_expire+0xd16/0x2160 ? try_to_wake_up+0x4ee/0x1260 ? bfq_end_wr_async_queues+0xe0/0xe0 ? _raw_write_unlock_bh+0x60/0x60 ? _raw_spin_lock_irq+0x81/0xe0 bfq_idle_slice_timer+0x109/0x280 ? bfq_dispatch_request+0x4870/0x4870 __hrtimer_run_queues+0x37d/0x700 ? enqueue_hrtimer+0x1b0/0x1b0 ? kvm_clock_get_cycles+0xd/0x10 ? ktime_get_update_offsets_now+0x6f/0x280 hrtimer_interrupt+0x2c8/0x740
Fix the problem by checking that the parent of the two bfqqs we are merging in bfq_setup_merge() is the same.
Link: https://lore.kernel.org/linux-block/20211125172809.GC19572@quack2.suse.cz/ CC: stable@vger.kernel.org Fixes: 430a67f9d616 ("block, bfq: merge bursts of newly-created queues") Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-2-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-iosched.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2762,6 +2762,14 @@ bfq_setup_merge(struct bfq_queue *bfqq, if (process_refs == 0 || new_process_refs == 0) return NULL;
+ /* + * Make sure merged queues belong to the same parent. Parents could + * have changed since the time we decided the two queues are suitable + * for merging. + */ + if (new_bfqq->entity.parent != bfqq->entity.parent) + return NULL; + bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", new_bfqq->pid);
From: Jan Kara jack@suse.cz
commit 3bc5e683c67d94bd839a1da2e796c15847b51b69 upstream.
When bfqq is shared by multiple processes it can happen that one of the processes gets moved to a different cgroup (or just starts submitting IO for different cgroup). In case that happens we need to split the merged bfqq as otherwise we will have IO for multiple cgroups in one bfqq and we will just account IO time to wrong entities etc.
Similarly if the bfqq is scheduled to merge with another bfqq but the merge didn't happen yet, cancel the merge as it need not be valid anymore.
CC: stable@vger.kernel.org Fixes: e21b7a0b9887 ("block, bfq: add full hierarchical scheduling and cgroups support") Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-3-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-cgroup.c | 36 +++++++++++++++++++++++++++++++++--- block/bfq-iosched.c | 2 +- block/bfq-iosched.h | 1 + 3 files changed, 35 insertions(+), 4 deletions(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -743,9 +743,39 @@ static struct bfq_group *__bfq_bic_chang }
if (sync_bfqq) { - entity = &sync_bfqq->entity; - if (entity->sched_data != &bfqg->sched_data) - bfq_bfqq_move(bfqd, sync_bfqq, bfqg); + if (!sync_bfqq->new_bfqq && !bfq_bfqq_coop(sync_bfqq)) { + /* We are the only user of this bfqq, just move it */ + if (sync_bfqq->entity.sched_data != &bfqg->sched_data) + bfq_bfqq_move(bfqd, sync_bfqq, bfqg); + } else { + struct bfq_queue *bfqq; + + /* + * The queue was merged to a different queue. Check + * that the merge chain still belongs to the same + * cgroup. + */ + for (bfqq = sync_bfqq; bfqq; bfqq = bfqq->new_bfqq) + if (bfqq->entity.sched_data != + &bfqg->sched_data) + break; + if (bfqq) { + /* + * Some queue changed cgroup so the merge is + * not valid anymore. We cannot easily just + * cancel the merge (by clearing new_bfqq) as + * there may be other processes using this + * queue and holding refs to all queues below + * sync_bfqq->new_bfqq. Similarly if the merge + * already happened, we need to detach from + * bfqq now so that we cannot merge bio to a + * request from the old cgroup. + */ + bfq_put_cooperator(sync_bfqq); + bfq_release_process_ref(bfqd, sync_bfqq); + bic_set_bfqq(bic, NULL, 1); + } + } }
return bfqg; --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5319,7 +5319,7 @@ static void bfq_put_stable_ref(struct bf bfq_put_queue(bfqq); }
-static void bfq_put_cooperator(struct bfq_queue *bfqq) +void bfq_put_cooperator(struct bfq_queue *bfqq) { struct bfq_queue *__bfqq, *next;
--- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -980,6 +980,7 @@ void bfq_weights_tree_remove(struct bfq_ void bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq, bool compensate, enum bfqq_expiration reason); void bfq_put_queue(struct bfq_queue *bfqq); +void bfq_put_cooperator(struct bfq_queue *bfqq); void bfq_end_wr_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); void bfq_release_process_ref(struct bfq_data *bfqd, struct bfq_queue *bfqq); void bfq_schedule_dispatch(struct bfq_data *bfqd);
From: Jan Kara jack@suse.cz
commit ea591cd4eb270393810e7be01feb8fde6a34fbbe upstream.
When the process is migrated to a different cgroup (or in case of writeback just starts submitting bios associated with a different cgroup) bfq_merge_bio() can operate with stale cgroup information in bic. Thus the bio can be merged to a request from a different cgroup or it can result in merging of bfqqs for different cgroups or bfqqs of already dead cgroups and causing possible use-after-free issues. Fix the problem by updating cgroup information in bfq_merge_bio().
CC: stable@vger.kernel.org Fixes: e21b7a0b9887 ("block, bfq: add full hierarchical scheduling and cgroups support") Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-4-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-iosched.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2461,10 +2461,17 @@ static bool bfq_bio_merge(struct request
spin_lock_irq(&bfqd->lock);
- if (bic) + if (bic) { + /* + * Make sure cgroup info is uptodate for current process before + * considering the merge. + */ + bfq_bic_update_cgroup(bic, bio); + bfqd->bio_bfqq = bic_to_bfqq(bic, op_is_sync(bio->bi_opf)); - else + } else { bfqd->bio_bfqq = NULL; + } bfqd->bio_bic = bic;
ret = blk_mq_sched_try_merge(q, bio, nr_segs, &free);
From: Jan Kara jack@suse.cz
commit fc84e1f941b91221092da5b3102ec82da24c5673 upstream.
In bfq_insert_request() we unlock bfqd->lock only to call trace_block_rq_insert() and then lock bfqd->lock again. This is really pointless since tracing is disabled if we really care about performance and even if the tracepoint is enabled, it is a quick call.
CC: stable@vger.kernel.org Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-5-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-iosched.c | 3 --- 1 file changed, 3 deletions(-)
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -6154,11 +6154,8 @@ static void bfq_insert_request(struct bl return; }
- spin_unlock_irq(&bfqd->lock); - trace_block_rq_insert(rq);
- spin_lock_irq(&bfqd->lock); bfqq = bfq_init_rq(rq); if (!bfqq || at_head) { if (at_head)
From: Jan Kara jack@suse.cz
commit 5f550ede5edf846ecc0067be1ba80514e6fe7f8e upstream.
We call bfq_init_rq() from request merging functions where requests we get should have already gone through bfq_init_rq() during insert and anyway we want to do anything only if the request is already tracked by BFQ. So replace calls to bfq_init_rq() with RQ_BFQQ() instead to simply skip requests untracked by BFQ. We move bfq_init_rq() call in bfq_insert_request() a bit earlier to cover request merging and thus can transfer FIFO position in case of a merge.
CC: stable@vger.kernel.org Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-6-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-iosched.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -2501,8 +2501,6 @@ static int bfq_request_merge(struct requ return ELEVATOR_NO_MERGE; }
-static struct bfq_queue *bfq_init_rq(struct request *rq); - static void bfq_request_merged(struct request_queue *q, struct request *req, enum elv_merge type) { @@ -2511,7 +2509,7 @@ static void bfq_request_merged(struct re blk_rq_pos(req) < blk_rq_pos(container_of(rb_prev(&req->rb_node), struct request, rb_node))) { - struct bfq_queue *bfqq = bfq_init_rq(req); + struct bfq_queue *bfqq = RQ_BFQQ(req); struct bfq_data *bfqd; struct request *prev, *next_rq;
@@ -2563,8 +2561,8 @@ static void bfq_request_merged(struct re static void bfq_requests_merged(struct request_queue *q, struct request *rq, struct request *next) { - struct bfq_queue *bfqq = bfq_init_rq(rq), - *next_bfqq = bfq_init_rq(next); + struct bfq_queue *bfqq = RQ_BFQQ(rq), + *next_bfqq = RQ_BFQQ(next);
if (!bfqq) goto remove; @@ -6133,6 +6131,8 @@ static inline void bfq_update_insert_sta unsigned int cmd_flags) {} #endif /* CONFIG_BFQ_CGROUP_DEBUG */
+static struct bfq_queue *bfq_init_rq(struct request *rq); + static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, bool at_head) { @@ -6148,6 +6148,7 @@ static void bfq_insert_request(struct bl bfqg_stats_update_legacy_io(q, rq); #endif spin_lock_irq(&bfqd->lock); + bfqq = bfq_init_rq(rq); if (blk_mq_sched_try_insert_merge(q, rq, &free)) { spin_unlock_irq(&bfqd->lock); blk_mq_free_requests(&free); @@ -6156,7 +6157,6 @@ static void bfq_insert_request(struct bl
trace_block_rq_insert(rq);
- bfqq = bfq_init_rq(rq); if (!bfqq || at_head) { if (at_head) list_add(&rq->queuelist, &bfqd->dispatch);
From: Jan Kara jack@suse.cz
commit 09f871868080c33992cd6a9b72a5ca49582578fa upstream.
Track whether bfq_group is still online. We cannot rely on blkcg_gq->online because that gets cleared only after all policies are offlined and we need something that gets updated already under bfqd->lock when we are cleaning up our bfq_group to be able to guarantee that when we see online bfq_group, it will stay online while we are holding bfqd->lock lock.
CC: stable@vger.kernel.org Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-7-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-cgroup.c | 3 ++- block/bfq-iosched.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -557,6 +557,7 @@ static void bfq_pd_init(struct blkg_poli */ bfqg->bfqd = bfqd; bfqg->active_entities = 0; + bfqg->online = true; bfqg->rq_pos_tree = RB_ROOT; }
@@ -603,7 +604,6 @@ struct bfq_group *bfq_find_set_group(str struct bfq_entity *entity;
bfqg = bfq_lookup_bfqg(bfqd, blkcg); - if (unlikely(!bfqg)) return NULL;
@@ -979,6 +979,7 @@ static void bfq_pd_offline(struct blkg_p
put_async_queues: bfq_put_async_queues(bfqd, bfqg); + bfqg->online = false;
spin_unlock_irqrestore(&bfqd->lock, flags); /* --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -929,6 +929,8 @@ struct bfq_group {
/* reference counter (see comments in bfq_bic_update_cgroup) */ int ref; + /* Is bfq_group still online? */ + bool online;
struct bfq_entity entity; struct bfq_sched_data sched_data;
From: Jan Kara jack@suse.cz
commit 4e54a2493e582361adc3bfbf06c7d50d19d18837 upstream.
BFQ usage of __bio_blkcg() is a relict from the past. Furthermore if bio would not be associated with any blkcg, the usage of __bio_blkcg() in BFQ is prone to races with the task being migrated between cgroups as __bio_blkcg() calls at different places could return different blkcgs.
Convert BFQ to the new situation where bio->bi_blkg is initialized in bio_set_dev() and thus practically always valid. This allows us to save blkcg_gq lookup and noticeably simplify the code.
CC: stable@vger.kernel.org Fixes: 0fe061b9f03c ("blkcg: fix ref count issue with bio_blkcg() using task_css") Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-8-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-cgroup.c | 63 ++++++++++++++++++---------------------------------- block/bfq-iosched.c | 11 --------- block/bfq-iosched.h | 3 -- 3 files changed, 25 insertions(+), 52 deletions(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -586,27 +586,11 @@ static void bfq_group_set_parent(struct entity->sched_data = &parent->sched_data; }
-static struct bfq_group *bfq_lookup_bfqg(struct bfq_data *bfqd, - struct blkcg *blkcg) +static void bfq_link_bfqg(struct bfq_data *bfqd, struct bfq_group *bfqg) { - struct blkcg_gq *blkg; - - blkg = blkg_lookup(blkcg, bfqd->queue); - if (likely(blkg)) - return blkg_to_bfqg(blkg); - return NULL; -} - -struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, - struct blkcg *blkcg) -{ - struct bfq_group *bfqg, *parent; + struct bfq_group *parent; struct bfq_entity *entity;
- bfqg = bfq_lookup_bfqg(bfqd, blkcg); - if (unlikely(!bfqg)) - return NULL; - /* * Update chain of bfq_groups as we might be handling a leaf group * which, along with some of its relatives, has not been hooked yet @@ -623,8 +607,15 @@ struct bfq_group *bfq_find_set_group(str bfq_group_set_parent(curr_bfqg, parent); } } +}
- return bfqg; +struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio) +{ + struct blkcg_gq *blkg = bio->bi_blkg; + + if (!blkg) + return bfqd->root_group; + return blkg_to_bfqg(blkg); }
/** @@ -714,25 +705,15 @@ void bfq_bfqq_move(struct bfq_data *bfqd * Move bic to blkcg, assuming that bfqd->lock is held; which makes * sure that the reference to cgroup is valid across the call (see * comments in bfq_bic_update_cgroup on this issue) - * - * NOTE: an alternative approach might have been to store the current - * cgroup in bfqq and getting a reference to it, reducing the lookup - * time here, at the price of slightly more complex code. */ -static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, - struct bfq_io_cq *bic, - struct blkcg *blkcg) +static void *__bfq_bic_change_cgroup(struct bfq_data *bfqd, + struct bfq_io_cq *bic, + struct bfq_group *bfqg) { struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); - struct bfq_group *bfqg; struct bfq_entity *entity;
- bfqg = bfq_find_set_group(bfqd, blkcg); - - if (unlikely(!bfqg)) - bfqg = bfqd->root_group; - if (async_bfqq) { entity = &async_bfqq->entity;
@@ -784,20 +765,24 @@ static struct bfq_group *__bfq_bic_chang void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) { struct bfq_data *bfqd = bic_to_bfqd(bic); - struct bfq_group *bfqg = NULL; + struct bfq_group *bfqg = bfq_bio_bfqg(bfqd, bio); uint64_t serial_nr;
- rcu_read_lock(); - serial_nr = __bio_blkcg(bio)->css.serial_nr; + serial_nr = bfqg_to_blkg(bfqg)->blkcg->css.serial_nr;
/* * Check whether blkcg has changed. The condition may trigger * spuriously on a newly created cic but there's no harm. */ if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr)) - goto out; + return;
- bfqg = __bfq_bic_change_cgroup(bfqd, bic, __bio_blkcg(bio)); + /* + * New cgroup for this process. Make sure it is linked to bfq internal + * cgroup hierarchy. + */ + bfq_link_bfqg(bfqd, bfqg); + __bfq_bic_change_cgroup(bfqd, bic, bfqg); /* * Update blkg_path for bfq_log_* functions. We cache this * path, and update it here, for the following @@ -850,8 +835,6 @@ void bfq_bic_update_cgroup(struct bfq_io */ blkg_path(bfqg_to_blkg(bfqg), bfqg->blkg_path, sizeof(bfqg->blkg_path)); bic->blkcg_serial_nr = serial_nr; -out: - rcu_read_unlock(); }
/** @@ -1469,7 +1452,7 @@ void bfq_end_wr_async(struct bfq_data *b bfq_end_wr_async_queues(bfqd, bfqd->root_group); }
-struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, struct blkcg *blkcg) +struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio) { return bfqd->root_group; } --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -5730,14 +5730,7 @@ static struct bfq_queue *bfq_get_queue(s struct bfq_queue *bfqq; struct bfq_group *bfqg;
- rcu_read_lock(); - - bfqg = bfq_find_set_group(bfqd, __bio_blkcg(bio)); - if (!bfqg) { - bfqq = &bfqd->oom_bfqq; - goto out; - } - + bfqg = bfq_bio_bfqg(bfqd, bio); if (!is_sync) { async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, ioprio); @@ -5783,8 +5776,6 @@ out:
if (bfqq != &bfqd->oom_bfqq && is_sync && !respawn) bfqq = bfq_do_or_sched_stable_merge(bfqd, bfqq, bic); - - rcu_read_unlock(); return bfqq; }
--- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -1010,8 +1010,7 @@ void bfq_bfqq_move(struct bfq_data *bfqd void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg); void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio); void bfq_end_wr_async(struct bfq_data *bfqd); -struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, - struct blkcg *blkcg); +struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio); struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg); struct bfq_group *bfqq_group(struct bfq_queue *bfqq); struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node);
From: Jan Kara jack@suse.cz
commit 075a53b78b815301f8d3dd1ee2cd99554e34f0dd upstream.
Bios queued into BFQ IO scheduler can be associated with a cgroup that was already offlined. This may then cause insertion of this bfq_group into a service tree. But this bfq_group will get freed as soon as last bio associated with it is completed leading to use after free issues for service tree users. Fix the problem by making sure we always operate on online bfq_group. If the bfq_group associated with the bio is not online, we pick the first online parent.
CC: stable@vger.kernel.org Fixes: e21b7a0b9887 ("block, bfq: add full hierarchical scheduling and cgroups support") Tested-by: "yukuai (C)" yukuai3@huawei.com Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20220401102752.8599-9-jack@suse.cz Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/bfq-cgroup.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
--- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -612,10 +612,19 @@ static void bfq_link_bfqg(struct bfq_dat struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio) { struct blkcg_gq *blkg = bio->bi_blkg; + struct bfq_group *bfqg;
- if (!blkg) - return bfqd->root_group; - return blkg_to_bfqg(blkg); + while (blkg) { + bfqg = blkg_to_bfqg(blkg); + if (bfqg->online) { + bio_associate_blkg_from_css(bio, &blkg->blkcg->css); + return bfqg; + } + blkg = blkg->parent; + } + bio_associate_blkg_from_css(bio, + &bfqg_to_blkg(bfqd->root_group)->blkcg->css); + return bfqd->root_group; }
/**
From: Dmitry Monakhov dmtrmonakhov@yandex-team.ru
commit d63c00ea435a5352f486c259665a4ced60399421 upstream.
Otherwise nonaligned fstrim calls will works inconveniently for iterative scanners, for example:
// trim [0,16MB] for group-1, but mark full group as trimmed fstrim -o $((1024*1024*128)) -l $((1024*1024*16)) ./m // handle [16MB,16MB] for group-1, do nothing because group already has the flag. fstrim -o $((1024*1024*144)) -l $((1024*1024*16)) ./m
[ Update function documentation for ext4_trim_all_free -- TYT ]
Signed-off-by: Dmitry Monakhov dmtrmonakhov@yandex-team.ru Link: https://lore.kernel.org/r/1650214995-860245-1-git-send-email-dmtrmonakhov@ya... Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/mballoc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -6398,6 +6398,7 @@ __releases(ext4_group_lock_ptr(sb, e4b-> * @start: first group block to examine * @max: last group block to examine * @minblocks: minimum extent block count + * @set_trimmed: set the trimmed flag if at least one block is trimmed * * ext4_trim_all_free walks through group's block bitmap searching for free * extents. When the free extent is found, mark it as used in group buddy @@ -6407,7 +6408,7 @@ __releases(ext4_group_lock_ptr(sb, e4b-> static ext4_grpblk_t ext4_trim_all_free(struct super_block *sb, ext4_group_t group, ext4_grpblk_t start, ext4_grpblk_t max, - ext4_grpblk_t minblocks) + ext4_grpblk_t minblocks, bool set_trimmed) { struct ext4_buddy e4b; int ret; @@ -6426,7 +6427,7 @@ ext4_trim_all_free(struct super_block *s if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || minblocks < EXT4_SB(sb)->s_last_trim_minblks) { ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); - if (ret >= 0) + if (ret >= 0 && set_trimmed) EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); } else { ret = 0; @@ -6463,6 +6464,7 @@ int ext4_trim_fs(struct super_block *sb, ext4_fsblk_t first_data_blk = le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); + bool whole_group, eof = false; int ret = 0;
start = range->start >> sb->s_blocksize_bits; @@ -6481,8 +6483,10 @@ int ext4_trim_fs(struct super_block *sb, if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) goto out; } - if (end >= max_blks) + if (end >= max_blks - 1) { end = max_blks - 1; + eof = true; + } if (end <= first_data_blk) goto out; if (start < first_data_blk) @@ -6496,6 +6500,7 @@ int ext4_trim_fs(struct super_block *sb,
/* end now represents the last cluster to discard in this group */ end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; + whole_group = true;
for (group = first_group; group <= last_group; group++) { grp = ext4_get_group_info(sb, group); @@ -6512,12 +6517,13 @@ int ext4_trim_fs(struct super_block *sb, * change it for the last group, note that last_cluster is * already computed earlier by ext4_get_group_no_and_offset() */ - if (group == last_group) + if (group == last_group) { end = last_cluster; - + whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; + } if (grp->bb_free >= minlen) { cnt = ext4_trim_all_free(sb, group, first_cluster, - end, minlen); + end, minlen, whole_group); if (cnt < 0) { ret = cnt; break;
From: Ye Bin yebin10@huawei.com
commit 0be698ecbe4471fcad80e81ec6a05001421041b3 upstream.
We got issue as follows: EXT4-fs (loop0): mounted filesystem without journal. Opts: ,errors=continue ext4_get_first_dir_block: bh->b_data=0xffff88810bee6000 len=34478 ext4_get_first_dir_block: *parent_de=0xffff88810beee6ae bh->b_data=0xffff88810bee6000 ext4_rename_dir_prepare: [1] parent_de=0xffff88810beee6ae ================================================================== BUG: KASAN: use-after-free in ext4_rename_dir_prepare+0x152/0x220 Read of size 4 at addr ffff88810beee6ae by task rep/1895
CPU: 13 PID: 1895 Comm: rep Not tainted 5.10.0+ #241 Call Trace: dump_stack+0xbe/0xf9 print_address_description.constprop.0+0x1e/0x220 kasan_report.cold+0x37/0x7f ext4_rename_dir_prepare+0x152/0x220 ext4_rename+0xf44/0x1ad0 ext4_rename2+0x11c/0x170 vfs_rename+0xa84/0x1440 do_renameat2+0x683/0x8f0 __x64_sys_renameat+0x53/0x60 do_syscall_64+0x33/0x40 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x7f45a6fc41c9 RSP: 002b:00007ffc5a470218 EFLAGS: 00000246 ORIG_RAX: 0000000000000108 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f45a6fc41c9 RDX: 0000000000000005 RSI: 0000000020000180 RDI: 0000000000000005 RBP: 00007ffc5a470240 R08: 00007ffc5a470160 R09: 0000000020000080 R10: 00000000200001c0 R11: 0000000000000246 R12: 0000000000400bb0 R13: 00007ffc5a470320 R14: 0000000000000000 R15: 0000000000000000
The buggy address belongs to the page: page:00000000440015ce refcount:0 mapcount:0 mapping:0000000000000000 index:0x1 pfn:0x10beee flags: 0x200000000000000() raw: 0200000000000000 ffffea00043ff4c8 ffffea0004325608 0000000000000000 raw: 0000000000000001 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff88810beee580: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff88810beee600: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff88810beee680: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^ ffff88810beee700: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff88810beee780: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ================================================================== Disabling lock debugging due to kernel taint ext4_rename_dir_prepare: [2] parent_de->inode=3537895424 ext4_rename_dir_prepare: [3] dir=0xffff888124170140 ext4_rename_dir_prepare: [4] ino=2 ext4_rename_dir_prepare: ent->dir->i_ino=2 parent=-757071872
Reason is first directory entry which 'rec_len' is 34478, then will get illegal parent entry. Now, we do not check directory entry after read directory block in 'ext4_get_first_dir_block'. To solve this issue, check directory entry in 'ext4_get_first_dir_block'.
[ Trigger an ext4_error() instead of just warning if the directory is missing a '.' or '..' entry. Also make sure we return an error code if the file system is corrupted. -TYT ]
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220414025223.4113128-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/namei.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-)
--- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3455,6 +3455,9 @@ static struct buffer_head *ext4_get_firs struct buffer_head *bh;
if (!ext4_has_inline_data(inode)) { + struct ext4_dir_entry_2 *de; + unsigned int offset; + /* The first directory block must not be a hole, so * treat it as DIRENT_HTREE */ @@ -3463,9 +3466,30 @@ static struct buffer_head *ext4_get_firs *retval = PTR_ERR(bh); return NULL; } - *parent_de = ext4_next_entry( - (struct ext4_dir_entry_2 *)bh->b_data, - inode->i_sb->s_blocksize); + + de = (struct ext4_dir_entry_2 *) bh->b_data; + if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, + bh->b_size, 0) || + le32_to_cpu(de->inode) != inode->i_ino || + strcmp(".", de->name)) { + EXT4_ERROR_INODE(inode, "directory missing '.'"); + brelse(bh); + *retval = -EFSCORRUPTED; + return NULL; + } + offset = ext4_rec_len_from_disk(de->rec_len, + inode->i_sb->s_blocksize); + de = ext4_next_entry(de, inode->i_sb->s_blocksize); + if (ext4_check_dir_entry(inode, NULL, de, bh, bh->b_data, + bh->b_size, offset) || + le32_to_cpu(de->inode) == 0 || strcmp("..", de->name)) { + EXT4_ERROR_INODE(inode, "directory missing '..'"); + brelse(bh); + *retval = -EFSCORRUPTED; + return NULL; + } + *parent_de = de; + return bh; }
From: Ojaswin Mujoo ojaswin@linux.ibm.com
commit e4e58e5df309d695799c494958962100a4c25039 upstream.
In __ext4_super() we always overwrote the user specified journal_ioprio value with a default value, expecting parse_apply_sb_mount_options() to later correctly set ctx->journal_ioprio to the user specified value. However, if parse_apply_sb_mount_options() returned early because of empty sbi->es_s->s_mount_opts, the correct journal_ioprio value was never set.
This patch fixes __ext4_super() to only use the default value if the user has not specified any value for journal_ioprio.
Similarly, the remount behavior was to either use journal_ioprio value specified during initial mount, or use the default value irrespective of the journal_ioprio value specified during remount. This patch modifies this to first check if a new value for ioprio has been passed during remount and apply it. If no new value is passed, use the value specified during initial mount.
Signed-off-by: Ojaswin Mujoo ojaswin@linux.ibm.com Reviewed-by: Ritesh Harjani riteshh@linux.ibm.com Tested-by: Ritesh Harjani riteshh@linux.ibm.com Link: https://lore.kernel.org/r/20220418083545.45778-1-ojaswin@linux.ibm.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4410,7 +4410,8 @@ static int __ext4_fill_super(struct fs_c int silent = fc->sb_flags & SB_SILENT;
/* Set defaults for the variables that will be set during parsing */ - ctx->journal_ioprio = DEFAULT_JOURNAL_IOPRIO; + if (!(ctx->spec & EXT4_SPEC_JOURNAL_IOPRIO)) + ctx->journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS; sbi->s_sectors_written_start = @@ -6277,7 +6278,6 @@ static int __ext4_remount(struct fs_cont char *to_free[EXT4_MAXQUOTAS]; #endif
- ctx->journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
/* Store the original options */ old_sb_flags = sb->s_flags; @@ -6303,9 +6303,14 @@ static int __ext4_remount(struct fs_cont } else old_opts.s_qf_names[i] = NULL; #endif - if (sbi->s_journal && sbi->s_journal->j_task->io_context) - ctx->journal_ioprio = - sbi->s_journal->j_task->io_context->ioprio; + if (!(ctx->spec & EXT4_SPEC_JOURNAL_IOPRIO)) { + if (sbi->s_journal && sbi->s_journal->j_task->io_context) + ctx->journal_ioprio = + sbi->s_journal->j_task->io_context->ioprio; + else + ctx->journal_ioprio = DEFAULT_JOURNAL_IOPRIO; + + }
ext4_apply_options(fc, sb);
From: Baokun Li libaokun1@huawei.com
commit f87c7a4b084afc13190cbb263538e444cb2b392a upstream.
Hulk Robot reported a BUG_ON: ================================================================== EXT4-fs error (device loop3): ext4_mb_generate_buddy:805: group 0, block bitmap and bg descriptor inconsistent: 25 vs 31513 free clusters kernel BUG at fs/ext4/ext4_jbd2.c:53! invalid opcode: 0000 [#1] SMP KASAN PTI CPU: 0 PID: 25371 Comm: syz-executor.3 Not tainted 5.10.0+ #1 RIP: 0010:ext4_put_nojournal fs/ext4/ext4_jbd2.c:53 [inline] RIP: 0010:__ext4_journal_stop+0x10e/0x110 fs/ext4/ext4_jbd2.c:116 [...] Call Trace: ext4_write_inline_data_end+0x59a/0x730 fs/ext4/inline.c:795 generic_perform_write+0x279/0x3c0 mm/filemap.c:3344 ext4_buffered_write_iter+0x2e3/0x3d0 fs/ext4/file.c:270 ext4_file_write_iter+0x30a/0x11c0 fs/ext4/file.c:520 do_iter_readv_writev+0x339/0x3c0 fs/read_write.c:732 do_iter_write+0x107/0x430 fs/read_write.c:861 vfs_writev fs/read_write.c:934 [inline] do_pwritev+0x1e5/0x380 fs/read_write.c:1031 [...] ==================================================================
Above issue may happen as follows: cpu1 cpu2 __________________________|__________________________ do_pwritev vfs_writev do_iter_write ext4_file_write_iter ext4_buffered_write_iter generic_perform_write ext4_da_write_begin vfs_fallocate ext4_fallocate ext4_convert_inline_data ext4_convert_inline_data_nolock ext4_destroy_inline_data_nolock clear EXT4_STATE_MAY_INLINE_DATA ext4_map_blocks ext4_ext_map_blocks ext4_mb_new_blocks ext4_mb_regular_allocator ext4_mb_good_group_nolock ext4_mb_init_group ext4_mb_init_cache ext4_mb_generate_buddy --> error ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) ext4_restore_inline_data set EXT4_STATE_MAY_INLINE_DATA ext4_block_write_begin ext4_da_write_end ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA) ext4_write_inline_data_end handle=NULL ext4_journal_stop(handle) __ext4_journal_stop ext4_put_nojournal(handle) ref_cnt = (unsigned long)handle BUG_ON(ref_cnt == 0) ---> BUG_ON
The lock held by ext4_convert_inline_data is xattr_sem, but the lock held by generic_perform_write is i_rwsem. Therefore, the two locks can be concurrent.
To solve above issue, we add inode_lock() for ext4_convert_inline_data(). At the same time, move ext4_convert_inline_data() in front of ext4_punch_hole(), remove similar handling from ext4_punch_hole().
Fixes: 0c8d414f163f ("ext4: let fallocate handle inline data correctly") Cc: stable@vger.kernel.org Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220428134031.4153381-1-libaokun1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/extents.c | 10 ++++++---- fs/ext4/inode.c | 9 --------- 2 files changed, 6 insertions(+), 13 deletions(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4693,15 +4693,17 @@ long ext4_fallocate(struct file *file, i FALLOC_FL_INSERT_RANGE)) return -EOPNOTSUPP;
+ inode_lock(inode); + ret = ext4_convert_inline_data(inode); + inode_unlock(inode); + if (ret) + goto exit; + if (mode & FALLOC_FL_PUNCH_HOLE) { ret = ext4_punch_hole(file, offset, len); goto exit; }
- ret = ext4_convert_inline_data(inode); - if (ret) - goto exit; - if (mode & FALLOC_FL_COLLAPSE_RANGE) { ret = ext4_collapse_range(file, offset, len); goto exit; --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3967,15 +3967,6 @@ int ext4_punch_hole(struct file *file, l
trace_ext4_punch_hole(inode, offset, length, 0);
- ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); - if (ext4_has_inline_data(inode)) { - filemap_invalidate_lock(mapping); - ret = ext4_convert_inline_data(inode); - filemap_invalidate_unlock(mapping); - if (ret) - return ret; - } - /* * Write out all dirty pages to avoid race conditions * Then release them.
From: Ye Bin yebin10@huawei.com
commit f4534c9fc94d22383f187b9409abb3f9df2e3db3 upstream.
We got issue as follows: EXT4-fs error (device loop0) in ext4_reserve_inode_write:5741: Out of memory EXT4-fs error (device loop0): ext4_setattr:5462: inode #13: comm syz-executor.0: mark_inode_dirty error EXT4-fs error (device loop0) in ext4_setattr:5519: Out of memory EXT4-fs error (device loop0): ext4_ind_map_blocks:595: inode #13: comm syz-executor.0: Can't allocate blocks for non-extent mapped inodes with bigalloc ------------[ cut here ]------------ WARNING: CPU: 1 PID: 4361 at fs/ext4/file.c:301 ext4_file_write_iter+0x11c9/0x1220 Modules linked in: CPU: 1 PID: 4361 Comm: syz-executor.0 Not tainted 5.10.0+ #1 RIP: 0010:ext4_file_write_iter+0x11c9/0x1220 RSP: 0018:ffff924d80b27c00 EFLAGS: 00010282 RAX: ffffffff815a3379 RBX: 0000000000000000 RCX: 000000003b000000 RDX: ffff924d81601000 RSI: 00000000000009cc RDI: 00000000000009cd RBP: 000000000000000d R08: ffffffffbc5a2c6b R09: 0000902e0e52a96f R10: ffff902e2b7c1b40 R11: ffff902e2b7c1b40 R12: 000000000000000a R13: 0000000000000001 R14: ffff902e0e52aa10 R15: ffffffffffffff8b FS: 00007f81a7f65700(0000) GS:ffff902e3bc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffff600400 CR3: 000000012db88001 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: do_iter_readv_writev+0x2e5/0x360 do_iter_write+0x112/0x4c0 do_pwritev+0x1e5/0x390 __x64_sys_pwritev2+0x7e/0xa0 do_syscall_64+0x37/0x50 entry_SYSCALL_64_after_hwframe+0x44/0xa9
Above issue may happen as follows: Assume inode.i_size=4096 EXT4_I(inode)->i_disksize=4096
step 1: set inode->i_isize = 8192 ext4_setattr if (attr->ia_size != inode->i_size) EXT4_I(inode)->i_disksize = attr->ia_size; rc = ext4_mark_inode_dirty ext4_reserve_inode_write ext4_get_inode_loc __ext4_get_inode_loc sb_getblk --> return -ENOMEM ... if (!error) ->will not update i_size i_size_write(inode, attr->ia_size); Now: inode.i_size=4096 EXT4_I(inode)->i_disksize=8192
step 2: Direct write 4096 bytes ext4_file_write_iter ext4_dio_write_iter iomap_dio_rw ->return error if (extend) ext4_handle_inode_extension WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize); ->Then trigger warning.
To solve above issue, if mark inode dirty failed in ext4_setattr just set 'EXT4_I(inode)->i_disksize' with old value.
Signed-off-by: Ye Bin yebin10@huawei.com Link: https://lore.kernel.org/r/20220326065351.761952-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inode.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5389,6 +5389,7 @@ int ext4_setattr(struct user_namespace * if (attr->ia_valid & ATTR_SIZE) { handle_t *handle; loff_t oldsize = inode->i_size; + loff_t old_disksize; int shrink = (attr->ia_size < inode->i_size);
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { @@ -5460,6 +5461,7 @@ int ext4_setattr(struct user_namespace * inode->i_sb->s_blocksize_bits);
down_write(&EXT4_I(inode)->i_data_sem); + old_disksize = EXT4_I(inode)->i_disksize; EXT4_I(inode)->i_disksize = attr->ia_size; rc = ext4_mark_inode_dirty(handle, inode); if (!error) @@ -5471,6 +5473,8 @@ int ext4_setattr(struct user_namespace * */ if (!error) i_size_write(inode, attr->ia_size); + else + EXT4_I(inode)->i_disksize = old_disksize; up_write(&EXT4_I(inode)->i_data_sem); ext4_journal_stop(handle); if (error)
From: Eric Biggers ebiggers@google.com
commit c069db76ed7b681c69159f44be96d2137e9ca989 upstream.
If processing the on-disk mount options fails after any memory was allocated in the ext4_fs_context, e.g. s_qf_names, then this memory is leaked. Fix this by calling ext4_fc_free() instead of kfree() directly.
Reproducer:
mkfs.ext4 -F /dev/vdc tune2fs /dev/vdc -E mount_opts=usrjquota=file echo clear > /sys/kernel/debug/kmemleak mount /dev/vdc /vdc echo scan > /sys/kernel/debug/kmemleak sleep 5 echo scan > /sys/kernel/debug/kmemleak cat /sys/kernel/debug/kmemleak
Fixes: 7edfd85b1ffd ("ext4: Completely separate options parsing and sb setup") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Tested-by: Ritesh Harjani ritesh.list@gmail.com Link: https://lore.kernel.org/r/20220513231605.175121-2-ebiggers@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2626,8 +2626,10 @@ parse_failed: ret = ext4_apply_options(fc, sb);
out_free: - kfree(s_ctx); - kfree(fc); + if (fc) { + ext4_fc_free(fc); + kfree(fc); + } kfree(s_mount_opts); return ret; }
From: Ye Bin yebin10@huawei.com
commit ef09ed5d37b84d18562b30cf7253e57062d0db05 upstream.
we got issue as follows: EXT4-fs error (device loop0): ext4_mb_generate_buddy:1141: group 0, block bitmap and bg descriptor inconsistent: 25 vs 31513 free cls ------------[ cut here ]------------ kernel BUG at fs/ext4/inode.c:2708! invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI CPU: 2 PID: 2147 Comm: rep Not tainted 5.18.0-rc2-next-20220413+ #155 RIP: 0010:ext4_writepages+0x1977/0x1c10 RSP: 0018:ffff88811d3e7880 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000001 RCX: ffff88811c098000 RDX: 0000000000000000 RSI: ffff88811c098000 RDI: 0000000000000002 RBP: ffff888128140f50 R08: ffffffffb1ff6387 R09: 0000000000000000 R10: 0000000000000007 R11: ffffed10250281ea R12: 0000000000000001 R13: 00000000000000a4 R14: ffff88811d3e7bb8 R15: ffff888128141028 FS: 00007f443aed9740(0000) GS:ffff8883aef00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020007200 CR3: 000000011c2a4000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> do_writepages+0x130/0x3a0 filemap_fdatawrite_wbc+0x83/0xa0 filemap_flush+0xab/0xe0 ext4_alloc_da_blocks+0x51/0x120 __ext4_ioctl+0x1534/0x3210 __x64_sys_ioctl+0x12c/0x170 do_syscall_64+0x3b/0x90
It may happen as follows: 1. write inline_data inode vfs_write new_sync_write ext4_file_write_iter ext4_buffered_write_iter generic_perform_write ext4_da_write_begin ext4_da_write_inline_data_begin -> If inline data size too small will allocate block to write, then mapping will has dirty page ext4_da_convert_inline_data_to_extent ->clear EXT4_STATE_MAY_INLINE_DATA 2. fallocate do_vfs_ioctl ioctl_preallocate vfs_fallocate ext4_fallocate ext4_convert_inline_data ext4_convert_inline_data_nolock ext4_map_blocks -> fail will goto restore data ext4_restore_inline_data ext4_create_inline_data ext4_write_inline_data ext4_set_inode_state -> set inode EXT4_STATE_MAY_INLINE_DATA 3. writepages __ext4_ioctl ext4_alloc_da_blocks filemap_flush filemap_fdatawrite_wbc do_writepages ext4_writepages if (ext4_has_inline_data(inode)) BUG_ON(ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA))
The root cause of this issue is we destory inline data until call ext4_writepages under delay allocation mode. But there maybe already convert from inline to extent. To solve this issue, we call filemap_flush first..
Cc: stable@kernel.org Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220516122634.1690462-1-yebin10@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inline.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -2005,6 +2005,18 @@ int ext4_convert_inline_data(struct inod if (!ext4_has_inline_data(inode)) { ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA); return 0; + } else if (!ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { + /* + * Inode has inline data but EXT4_STATE_MAY_INLINE_DATA is + * cleared. This means we are in the middle of moving of + * inline data to delay allocated block. Just force writeout + * here to finish conversion. + */ + error = filemap_flush(inode->i_mapping); + if (error) + return error; + if (!ext4_has_inline_data(inode)) + return 0; }
needed_blocks = ext4_writepage_trans_blocks(inode);
From: Theodore Ts'o tytso@mit.edu
commit c878bea3c9d724ddfa05a813f30de3d25a0ba83f upstream.
The EXT4_FC_REPLAY bit in sbi->s_mount_state is used to indicate that we are in the middle of replay the fast commit journal. This was actually a mistake, since the sbi->s_mount_info is initialized from es->s_state. Arguably s_mount_state is misleadingly named, but the name is historical --- s_mount_state and s_state dates back to ext2.
What should have been used is the ext4_{set,clear,test}_mount_flag() inline functions, which sets EXT4_MF_* bits in sbi->s_mount_flags.
The problem with using EXT4_FC_REPLAY is that a maliciously corrupted superblock could result in EXT4_FC_REPLAY getting set in s_mount_state. This bypasses some sanity checks, and this can trigger a BUG() in ext4_es_cache_extent(). As a easy-to-backport-fix, filter out the EXT4_FC_REPLAY bit for now. We should eventually transition away from EXT4_FC_REPLAY to something like EXT4_MF_REPLAY.
Cc: stable@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Link: https://lore.kernel.org/r/20220420192312.1655305-1-phind.uet@gmail.com Link: https://lore.kernel.org/r/20220517174028.942119-1-tytso@mit.edu Reported-by: syzbot+c7358a3cd05ee786eb31@syzkaller.appspotmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4890,7 +4890,7 @@ static int __ext4_fill_super(struct fs_c sbi->s_inodes_per_block; sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb); sbi->s_sbh = bh; - sbi->s_mount_state = le16_to_cpu(es->s_state); + sbi->s_mount_state = le16_to_cpu(es->s_state) & ~EXT4_FC_REPLAY; sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb)); sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb));
@@ -6453,7 +6453,8 @@ static int __ext4_remount(struct fs_cont if (err) goto restore_opts; } - sbi->s_mount_state = le16_to_cpu(es->s_state); + sbi->s_mount_state = (le16_to_cpu(es->s_state) & + ~EXT4_FC_REPLAY);
err = ext4_setup_super(sb, es, 0); if (err)
From: Baokun Li libaokun1@huawei.com
commit d36f6ed761b53933b0b4126486c10d3da7751e7f upstream.
Hulk Robot reported a BUG_ON: ================================================================== kernel BUG at fs/ext4/extents_status.c:199! [...] RIP: 0010:ext4_es_end fs/ext4/extents_status.c:199 [inline] RIP: 0010:__es_tree_search+0x1e0/0x260 fs/ext4/extents_status.c:217 [...] Call Trace: ext4_es_cache_extent+0x109/0x340 fs/ext4/extents_status.c:766 ext4_cache_extents+0x239/0x2e0 fs/ext4/extents.c:561 ext4_find_extent+0x6b7/0xa20 fs/ext4/extents.c:964 ext4_ext_map_blocks+0x16b/0x4b70 fs/ext4/extents.c:4384 ext4_map_blocks+0xe26/0x19f0 fs/ext4/inode.c:567 ext4_getblk+0x320/0x4c0 fs/ext4/inode.c:980 ext4_bread+0x2d/0x170 fs/ext4/inode.c:1031 ext4_quota_read+0x248/0x320 fs/ext4/super.c:6257 v2_read_header+0x78/0x110 fs/quota/quota_v2.c:63 v2_check_quota_file+0x76/0x230 fs/quota/quota_v2.c:82 vfs_load_quota_inode+0x5d1/0x1530 fs/quota/dquot.c:2368 dquot_enable+0x28a/0x330 fs/quota/dquot.c:2490 ext4_quota_enable fs/ext4/super.c:6137 [inline] ext4_enable_quotas+0x5d7/0x960 fs/ext4/super.c:6163 ext4_fill_super+0xa7c9/0xdc00 fs/ext4/super.c:4754 mount_bdev+0x2e9/0x3b0 fs/super.c:1158 mount_fs+0x4b/0x1e4 fs/super.c:1261 [...] ==================================================================
Above issue may happen as follows: ------------------------------------- ext4_fill_super ext4_enable_quotas ext4_quota_enable ext4_iget __ext4_iget ext4_ext_check_inode ext4_ext_check __ext4_ext_check ext4_valid_extent_entries Check for overlapping extents does't take effect dquot_enable vfs_load_quota_inode v2_check_quota_file v2_read_header ext4_quota_read ext4_bread ext4_getblk ext4_map_blocks ext4_ext_map_blocks ext4_find_extent ext4_cache_extents ext4_es_cache_extent ext4_es_cache_extent __es_tree_search ext4_es_end BUG_ON(es->es_lblk + es->es_len < es->es_lblk)
The error ext4 extents is as follows: 0af3 0300 0400 0000 00000000 extent_header 00000000 0100 0000 12000000 extent1 00000000 0100 0000 18000000 extent2 02000000 0400 0000 14000000 extent3
In the ext4_valid_extent_entries function, if prev is 0, no error is returned even if lblock<=prev. This was intended to skip the check on the first extent, but in the error image above, prev=0+1-1=0 when checking the second extent, so even though lblock<=prev, the function does not return an error. As a result, bug_ON occurs in __es_tree_search and the system panics.
To solve this problem, we only need to check that: 1. The lblock of the first extent is not less than 0. 2. The lblock of the next extent is not less than the next block of the previous extent. The same applies to extent_idx.
Cc: stable@kernel.org Fixes: 5946d089379a ("ext4: check for overlapping extents in ext4_valid_extent_entries()") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220518120816.1541863-1-libaokun1@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/extents.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -372,7 +372,7 @@ static int ext4_valid_extent_entries(str { unsigned short entries; ext4_lblk_t lblock = 0; - ext4_lblk_t prev = 0; + ext4_lblk_t cur = 0;
if (eh->eh_entries == 0) return 1; @@ -396,11 +396,11 @@ static int ext4_valid_extent_entries(str
/* Check for overlapping extents */ lblock = le32_to_cpu(ext->ee_block); - if ((lblock <= prev) && prev) { + if (lblock < cur) { *pblk = ext4_ext_pblock(ext); return 0; } - prev = lblock + ext4_ext_get_actual_len(ext) - 1; + cur = lblock + ext4_ext_get_actual_len(ext); ext++; entries--; } @@ -420,13 +420,13 @@ static int ext4_valid_extent_entries(str
/* Check for overlapping index extents */ lblock = le32_to_cpu(ext_idx->ei_block); - if ((lblock <= prev) && prev) { + if (lblock < cur) { *pblk = ext4_idx_pblock(ext_idx); return 0; } ext_idx++; entries--; - prev = lblock; + cur = lblock + 1; } } return 1;
From: Jan Kara jack@suse.cz
commit 46c116b920ebec58031f0a78c5ea9599b0d2a371 upstream.
Before splitting a directory block verify its directory entries are sane so that the splitting code does not access memory it should not.
Cc: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220518093332.13986-1-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/namei.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-)
--- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -277,9 +277,9 @@ static struct dx_frame *dx_probe(struct struct dx_hash_info *hinfo, struct dx_frame *frame); static void dx_release(struct dx_frame *frames); -static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, - unsigned blocksize, struct dx_hash_info *hinfo, - struct dx_map_entry map[]); +static int dx_make_map(struct inode *dir, struct buffer_head *bh, + struct dx_hash_info *hinfo, + struct dx_map_entry *map_tail); static void dx_sort_map(struct dx_map_entry *map, unsigned count); static struct ext4_dir_entry_2 *dx_move_dirents(struct inode *dir, char *from, char *to, struct dx_map_entry *offsets, @@ -1249,15 +1249,23 @@ static inline int search_dirblock(struct * Create map of hash values, offsets, and sizes, stored at end of block. * Returns number of entries mapped. */ -static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, - unsigned blocksize, struct dx_hash_info *hinfo, +static int dx_make_map(struct inode *dir, struct buffer_head *bh, + struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) { int count = 0; - char *base = (char *) de; + struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *)bh->b_data; + unsigned int buflen = bh->b_size; + char *base = bh->b_data; struct dx_hash_info h = *hinfo;
- while ((char *) de < base + blocksize) { + if (ext4_has_metadata_csum(dir->i_sb)) + buflen -= sizeof(struct ext4_dir_entry_tail); + + while ((char *) de < base + buflen) { + if (ext4_check_dir_entry(dir, NULL, de, bh, base, buflen, + ((char *)de) - base)) + return -EFSCORRUPTED; if (de->name_len && de->inode) { if (ext4_hash_in_dirent(dir)) h.hash = EXT4_DIRENT_HASH(de); @@ -1270,8 +1278,7 @@ static int dx_make_map(struct inode *dir count++; cond_resched(); } - /* XXX: do we need to check rec_len == 0 case? -Chris */ - de = ext4_next_entry(de, blocksize); + de = ext4_next_entry(de, dir->i_sb->s_blocksize); } return count; } @@ -1943,8 +1950,11 @@ static struct ext4_dir_entry_2 *do_split
/* create map in the end of data2 block */ map = (struct dx_map_entry *) (data2 + blocksize); - count = dx_make_map(dir, (struct ext4_dir_entry_2 *) data1, - blocksize, hinfo, map); + count = dx_make_map(dir, *bh, hinfo, map); + if (count < 0) { + err = count; + goto journal_error; + } map -= count; dx_sort_map(map, count); /* Ensure that neither split block is over half full */
From: Jan Kara jack@suse.cz
commit 3ba733f879c2a88910744647e41edeefbc0d92b2 upstream.
A maliciously corrupted filesystem can contain cycles in the h-tree stored inside a directory. That can easily lead to the kernel corrupting tree nodes that were already verified under its hands while doing a node split and consequently accessing unallocated memory. Fix the problem by verifying traversed block numbers are unique.
Cc: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20220518093332.13986-2-jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/namei.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
--- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -777,12 +777,14 @@ static struct dx_frame * dx_probe(struct ext4_filename *fname, struct inode *dir, struct dx_hash_info *hinfo, struct dx_frame *frame_in) { - unsigned count, indirect; + unsigned count, indirect, level, i; struct dx_entry *at, *entries, *p, *q, *m; struct dx_root *root; struct dx_frame *frame = frame_in; struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR); u32 hash; + ext4_lblk_t block; + ext4_lblk_t blocks[EXT4_HTREE_LEVEL];
memset(frame_in, 0, EXT4_HTREE_LEVEL * sizeof(frame_in[0])); frame->bh = ext4_read_dirblock(dir, 0, INDEX); @@ -854,6 +856,8 @@ dx_probe(struct ext4_filename *fname, st }
dxtrace(printk("Look up %x", hash)); + level = 0; + blocks[0] = 0; while (1) { count = dx_get_count(entries); if (!count || count > dx_get_limit(entries)) { @@ -882,15 +886,27 @@ dx_probe(struct ext4_filename *fname, st dx_get_block(at))); frame->entries = entries; frame->at = at; - if (!indirect--) + + block = dx_get_block(at); + for (i = 0; i <= level; i++) { + if (blocks[i] == block) { + ext4_warning_inode(dir, + "dx entry: tree cycle block %u points back to block %u", + blocks[level], block); + goto fail; + } + } + if (++level > indirect) return frame; + blocks[level] = block; frame++; - frame->bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX); + frame->bh = ext4_read_dirblock(dir, block, INDEX); if (IS_ERR(frame->bh)) { ret_err = (struct dx_frame *) frame->bh; frame->bh = NULL; goto fail; } + entries = ((struct dx_node *) frame->bh->b_data)->entries;
if (dx_get_limit(entries) != dx_node_limit(dir)) {
From: Sakari Ailus sakari.ailus@linux.intel.com
commit 3bd561e1572ee02a50cd1a5be339abf1a5b78d56 upstream.
struct acpi_device_properties describes one source of properties present on either struct acpi_device or struct acpi_data_node. When properties are parsed, both are populated but when released, only those properties that are associated with the device node are freed.
Fix this by also releasing memory of the data node properties.
Fixes: 5f5e4890d57a ("ACPI / property: Allow multiple property compatible _DSD entries") Cc: 4.20+ stable@vger.kernel.org # 4.20+ Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/acpi/property.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -433,6 +433,16 @@ void acpi_init_properties(struct acpi_de acpi_extract_apple_properties(adev); }
+static void acpi_free_device_properties(struct list_head *list) +{ + struct acpi_device_properties *props, *tmp; + + list_for_each_entry_safe(props, tmp, list, list) { + list_del(&props->list); + kfree(props); + } +} + static void acpi_destroy_nondev_subnodes(struct list_head *list) { struct acpi_data_node *dn, *next; @@ -445,22 +455,18 @@ static void acpi_destroy_nondev_subnodes wait_for_completion(&dn->kobj_done); list_del(&dn->sibling); ACPI_FREE((void *)dn->data.pointer); + acpi_free_device_properties(&dn->data.properties); kfree(dn); } }
void acpi_free_properties(struct acpi_device *adev) { - struct acpi_device_properties *props, *tmp; - acpi_destroy_nondev_subnodes(&adev->data.subnodes); ACPI_FREE((void *)adev->data.pointer); adev->data.of_compatible = NULL; adev->data.pointer = NULL; - list_for_each_entry_safe(props, tmp, &adev->data.properties, list) { - list_del(&props->list); - kfree(props); - } + acpi_free_device_properties(&adev->data.properties); }
/**
From: Laurent Vivier laurent@vivier.eu
commit 2e2ac4a3327479f7e2744cdd88a5c823f2057bad upstream.
The goldfish TTY device was clearly defined as having little-endian registers, but the switch to __raw_{read,write}l(() broke its driver when running on big-endian kernels (if anyone ever tried this).
The m68k qemu implementation got this wrong, and assumed native-endian registers. While this is a bug in qemu, it is probably impossible to fix that since there is no way of knowing which other operating systems have started relying on that bug over the years.
Hence revert commit da31de35cd2f ("tty: goldfish: use __raw_writel()/__raw_readl()", and define gf_ioread32()/gf_iowrite32() to be able to use accessors defined by the architecture.
Cc: stable@vger.kernel.org # v5.11+ Fixes: da31de35cd2fb78f ("tty: goldfish: use __raw_writel()/__raw_readl()") Signed-off-by: Laurent Vivier laurent@vivier.eu Link: https://lore.kernel.org/r/20220406201523.243733-2-laurent@vivier.eu [geert: Add rationale based on Arnd's comments] Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/goldfish.c | 20 ++++++++++---------- include/linux/goldfish.h | 15 +++++++++++---- 2 files changed, 21 insertions(+), 14 deletions(-)
--- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -61,13 +61,13 @@ static void do_rw_io(struct goldfish_tty spin_lock_irqsave(&qtty->lock, irq_flags); gf_write_ptr((void *)address, base + GOLDFISH_TTY_REG_DATA_PTR, base + GOLDFISH_TTY_REG_DATA_PTR_HIGH); - __raw_writel(count, base + GOLDFISH_TTY_REG_DATA_LEN); + gf_iowrite32(count, base + GOLDFISH_TTY_REG_DATA_LEN);
if (is_write) - __raw_writel(GOLDFISH_TTY_CMD_WRITE_BUFFER, + gf_iowrite32(GOLDFISH_TTY_CMD_WRITE_BUFFER, base + GOLDFISH_TTY_REG_CMD); else - __raw_writel(GOLDFISH_TTY_CMD_READ_BUFFER, + gf_iowrite32(GOLDFISH_TTY_CMD_READ_BUFFER, base + GOLDFISH_TTY_REG_CMD);
spin_unlock_irqrestore(&qtty->lock, irq_flags); @@ -142,7 +142,7 @@ static irqreturn_t goldfish_tty_interrup unsigned char *buf; u32 count;
- count = __raw_readl(base + GOLDFISH_TTY_REG_BYTES_READY); + count = gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY); if (count == 0) return IRQ_NONE;
@@ -159,7 +159,7 @@ static int goldfish_tty_activate(struct { struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); - __raw_writel(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD); + gf_iowrite32(GOLDFISH_TTY_CMD_INT_ENABLE, qtty->base + GOLDFISH_TTY_REG_CMD); return 0; }
@@ -167,7 +167,7 @@ static void goldfish_tty_shutdown(struct { struct goldfish_tty *qtty = container_of(port, struct goldfish_tty, port); - __raw_writel(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD); + gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, qtty->base + GOLDFISH_TTY_REG_CMD); }
static int goldfish_tty_open(struct tty_struct *tty, struct file *filp) @@ -202,7 +202,7 @@ static unsigned int goldfish_tty_chars_i { struct goldfish_tty *qtty = &goldfish_ttys[tty->index]; void __iomem *base = qtty->base; - return __raw_readl(base + GOLDFISH_TTY_REG_BYTES_READY); + return gf_ioread32(base + GOLDFISH_TTY_REG_BYTES_READY); }
static void goldfish_tty_console_write(struct console *co, const char *b, @@ -355,7 +355,7 @@ static int goldfish_tty_probe(struct pla * on Ranchu emulator (qemu2) returns 1 here and * driver will use physical addresses. */ - qtty->version = __raw_readl(base + GOLDFISH_TTY_REG_VERSION); + qtty->version = gf_ioread32(base + GOLDFISH_TTY_REG_VERSION);
/* * Goldfish TTY device on Ranchu emulator (qemu2) @@ -374,7 +374,7 @@ static int goldfish_tty_probe(struct pla } }
- __raw_writel(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD); + gf_iowrite32(GOLDFISH_TTY_CMD_INT_DISABLE, base + GOLDFISH_TTY_REG_CMD);
ret = request_irq(irq, goldfish_tty_interrupt, IRQF_SHARED, "goldfish_tty", qtty); @@ -436,7 +436,7 @@ static int goldfish_tty_remove(struct pl #ifdef CONFIG_GOLDFISH_TTY_EARLY_CONSOLE static void gf_early_console_putchar(struct uart_port *port, unsigned char ch) { - __raw_writel(ch, port->membase); + gf_iowrite32(ch, port->membase); }
static void gf_early_write(struct console *con, const char *s, unsigned int n) --- a/include/linux/goldfish.h +++ b/include/linux/goldfish.h @@ -8,14 +8,21 @@
/* Helpers for Goldfish virtual platform */
+#ifndef gf_ioread32 +#define gf_ioread32 ioread32 +#endif +#ifndef gf_iowrite32 +#define gf_iowrite32 iowrite32 +#endif + static inline void gf_write_ptr(const void *ptr, void __iomem *portl, void __iomem *porth) { const unsigned long addr = (unsigned long)ptr;
- __raw_writel(lower_32_bits(addr), portl); + gf_iowrite32(lower_32_bits(addr), portl); #ifdef CONFIG_64BIT - __raw_writel(upper_32_bits(addr), porth); + gf_iowrite32(upper_32_bits(addr), porth); #endif }
@@ -23,9 +30,9 @@ static inline void gf_write_dma_addr(con void __iomem *portl, void __iomem *porth) { - __raw_writel(lower_32_bits(addr), portl); + gf_iowrite32(lower_32_bits(addr), portl); #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - __raw_writel(upper_32_bits(addr), porth); + gf_iowrite32(upper_32_bits(addr), porth); #endif }
From: Steven Rostedt (Google) rostedt@goodmis.org
commit 499f12168aebd6da8fa32c9b7d6203ca9b5eb88d upstream.
The print fmt check against trace events to make sure that the format does not use pointers that may be freed from the time of the trace to the time the event is read, gives a false positive on %pISpc when reading data that was saved in __get_dynamic_array() when it is perfectly fine to do so, as the data being read is on the ring buffer.
Link: https://lore.kernel.org/all/20220407144524.2a592ed6@canb.auug.org.au/
Cc: stable@vger.kernel.org Fixes: 5013f454a352c ("tracing: Add check of trace event print fmts for dereferencing pointers") Reported-by: Stephen Rothwell sfr@canb.auug.org.au Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_events.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -392,12 +392,6 @@ static void test_event_printk(struct tra if (!(dereference_flags & (1ULL << arg))) goto next_arg;
- /* Check for __get_sockaddr */; - if (str_has_prefix(fmt + i, "__get_sockaddr(")) { - dereference_flags &= ~(1ULL << arg); - goto next_arg; - } - /* Find the REC-> in the argument */ c = strchr(fmt + i, ','); r = strstr(fmt + i, "REC->"); @@ -413,7 +407,14 @@ static void test_event_printk(struct tra a = strchr(fmt + i, '&'); if ((a && (a < r)) || test_field(r, call)) dereference_flags &= ~(1ULL << arg); + } else if ((r = strstr(fmt + i, "__get_dynamic_array(")) && + (!c || r < c)) { + dereference_flags &= ~(1ULL << arg); + } else if ((r = strstr(fmt + i, "__get_sockaddr(")) && + (!c || r < c)) { + dereference_flags &= ~(1ULL << arg); } + next_arg: i--; arg++;
From: Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp
commit 99696a2592bca641eb88cc9a80c90e591afebd0f upstream.
In create_var_ref(), init_var_ref() is called to initialize the fields of variable ref_field, which is allocated in the previous function call to create_hist_field(). Function init_var_ref() allocates the corresponding fields such as ref_field->system, but frees these fields when the function encounters an error. The caller later calls destroy_hist_field() to conduct error handling, which frees the fields and the variable itself. This results in double free of the fields which are already freed in the previous function.
Fix this by storing NULL to the corresponding fields when they are freed in init_var_ref().
Link: https://lkml.kernel.org/r/20220425063739.3859998-1-keitasuzuki.park@sslab.ic...
Fixes: 067fe038e70f ("tracing: Add variable reference handling to hist triggers") CC: stable@vger.kernel.org Reviewed-by: Masami Hiramatsu mhiramat@kernel.org Reviewed-by: Tom Zanussi zanussi@kernel.org Signed-off-by: Keita Suzuki keitasuzuki.park@sslab.ics.keio.ac.jp Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_events_hist.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -2093,8 +2093,11 @@ static int init_var_ref(struct hist_fiel return err; free: kfree(ref_field->system); + ref_field->system = NULL; kfree(ref_field->event_name); + ref_field->event_name = NULL; kfree(ref_field->name); + ref_field->name = NULL;
goto out; }
From: Wonhyuk Yang vvghjk1234@gmail.com
commit b27f266f74fbda4ee36c2b2b04d15992860cf23b upstream.
Setting set_event_pid with trailing whitespace lead to endless write system calls like below.
$ strace echo "123 " > /sys/kernel/debug/tracing/set_event_pid execve("/usr/bin/echo", ["echo", "123 "], ...) = 0 ... write(1, "123 \n", 5) = 4 write(1, "\n", 1) = 0 write(1, "\n", 1) = 0 write(1, "\n", 1) = 0 write(1, "\n", 1) = 0 write(1, "\n", 1) = 0 ....
This is because, the result of trace_get_user's are not returned when it read at least one pid. To fix it, update read variable even if parser->idx == 0.
The result of applied patch is below.
$ strace echo "123 " > /sys/kernel/debug/tracing/set_event_pid execve("/usr/bin/echo", ["echo", "123 "], ...) = 0 ... write(1, "123 \n", 5) = 5 close(1) = 0
Link: https://lkml.kernel.org/r/20220503050546.288911-1-vvghjk1234@gmail.com
Cc: Ingo Molnar mingo@redhat.com Cc: Baik Song An bsahn@etri.re.kr Cc: Hong Yeon Kim kimhy@etri.re.kr Cc: Taeung Song taeung@reallinux.co.kr Cc: linuxgeek@linuxgeek.io Cc: stable@vger.kernel.org Fixes: 4909010788640 ("tracing: Add set_event_pid directory for future use") Signed-off-by: Wonhyuk Yang vvghjk1234@gmail.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -721,13 +721,16 @@ int trace_pid_write(struct trace_pid_lis pos = 0;
ret = trace_get_user(&parser, ubuf, cnt, &pos); - if (ret < 0 || !trace_parser_loaded(&parser)) + if (ret < 0) break;
read += ret; ubuf += ret; cnt -= ret;
+ if (!trace_parser_loaded(&parser)) + break; + ret = -EINVAL; if (kstrtoul(parser.buffer, 0, &val)) break; @@ -753,7 +756,6 @@ int trace_pid_write(struct trace_pid_lis if (!nr_pids) { /* Cleared the list of pids */ trace_pid_list_free(pid_list); - read = ret; pid_list = NULL; }
From: Gautam Menghani gautammenghani201@gmail.com
commit 154827f8e53d8c492b3fb0cb757fbcadb5d516b5 upstream.
Initialize the integer variable to 0 to fix the clang scan warning: Undefined or garbage value returned to caller [core.uninitialized.UndefReturn] return ret;
Link: https://lkml.kernel.org/r/20220522061826.1751-1-gautammenghani201@gmail.com
Cc: stable@vger.kernel.org Fixes: 8993665abcce ("tracing/boot: Support multiple handlers for per-event histogram") Acked-by: Masami Hiramatsu (Google) mhiramat@kernel.org Signed-off-by: Gautam Menghani gautammenghani201@gmail.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/trace_boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace_boot.c +++ b/kernel/trace/trace_boot.c @@ -300,7 +300,7 @@ trace_boot_hist_add_handlers(struct xbc_ { struct xbc_node *node; const char *p, *handler; - int ret; + int ret = 0;
handler = xbc_node_get_data(hnode);
From: Alex Deucher alexander.deucher@amd.com
commit 62e9bd20035b53ff6c679499c08546d96c6c60a7 upstream.
Add a beige goby PCI ID.
Reviewed-by: Guchun Chen guchun.chen@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_drv.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1931,6 +1931,7 @@ static const struct pci_device_id pciidl {0x1002, 0x7421, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY}, {0x1002, 0x7422, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY}, {0x1002, 0x7423, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY}, + {0x1002, 0x7424, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY}, {0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
{ PCI_DEVICE(0x1002, PCI_ANY_ID),
From: Bjorn Helgaas bhelgaas@google.com
commit 12068bb346db5776d0ec9bb4cd073f8427a1ac92 upstream.
92597f97a40b ("PCI/PM: Avoid putting Elo i2 PCIe Ports in D3cold") omitted braces around the new Elo i2 entry, so it overwrote the existing Gigabyte X299 entry. Add the appropriate braces.
Found by:
$ make W=1 drivers/pci/pci.o CC drivers/pci/pci.o drivers/pci/pci.c:2974:12: error: initialized field overwritten [-Werror=override-init] 2974 | .ident = "Elo i2", | ^~~~~~~~
Link: https://lore.kernel.org/r/20220526221258.GA409855@bhelgaas Fixes: 92597f97a40b ("PCI/PM: Avoid putting Elo i2 PCIe Ports in D3cold") Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org # v5.15+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/pci.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2920,6 +2920,8 @@ static const struct dmi_system_id bridge DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), DMI_MATCH(DMI_BOARD_NAME, "X299 DESIGNARE EX-CF"), }, + }, + { /* * Downstream device is not accessible after putting a root port * into D3cold and back into D0 on Elo i2.
From: Johan Hovold johan+linaro@kernel.org
commit fdf6a2f533115ec5d4d9629178f8196331f1ac50 upstream.
Fix a clock imbalance introduced by ed8cc3b1fc84 ("PCI: qcom: Add support for SDM845 PCIe controller"), which enables the pipe clock both in init() and in post_init() but only disables in post_deinit().
Note that the pipe clock was also never disabled in the init() error paths and that enabling the clock before powering up the PHY looks questionable.
Link: https://lore.kernel.org/r/20220401133351.10113-1-johan+linaro@kernel.org Fixes: ed8cc3b1fc84 ("PCI: qcom: Add support for SDM845 PCIe controller") Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Cc: stable@vger.kernel.org # 5.6 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/dwc/pcie-qcom.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1238,12 +1238,6 @@ static int qcom_pcie_init_2_7_0(struct q goto err_disable_clocks; }
- ret = clk_prepare_enable(res->pipe_clk); - if (ret) { - dev_err(dev, "cannot prepare/enable pipe clock\n"); - goto err_disable_clocks; - } - /* Wait for reset to complete, required on SM8450 */ usleep_range(1000, 1500);
From: Johan Hovold johan+linaro@kernel.org
commit 87d83b96c8d6c6c2d2096bd0bdba73bcf42b8ef0 upstream.
Drop the leftover pm_runtime_disable() calls from the late probe error paths that would, for example, prevent runtime PM from being reenabled after a probe deferral.
Link: https://lore.kernel.org/r/20220401133854.10421-2-johan+linaro@kernel.org Fixes: 6e5da6f7d824 ("PCI: qcom: Fix error handling in runtime PM support") Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Acked-by: Stanimir Varbanov svarbanov@mm-sol.com Cc: stable@vger.kernel.org # 4.20 Cc: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/dwc/pcie-qcom.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1621,17 +1621,14 @@ static int qcom_pcie_probe(struct platfo pp->ops = &qcom_pcie_dw_ops;
ret = phy_init(pcie->phy); - if (ret) { - pm_runtime_disable(&pdev->dev); + if (ret) goto err_pm_runtime_put; - }
platform_set_drvdata(pdev, pcie);
ret = dw_pcie_host_init(pp); if (ret) { dev_err(dev, "cannot initialize host\n"); - pm_runtime_disable(&pdev->dev); goto err_pm_runtime_put; }
From: Johan Hovold johan+linaro@kernel.org
commit 83013631f0f9961416abd812e228c8efbc2f6069 upstream.
Undo the PHY initialisation (e.g. balance runtime PM) if host initialisation fails during probe.
Link: https://lore.kernel.org/r/20220401133854.10421-3-johan+linaro@kernel.org Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") Signed-off-by: Johan Hovold johan+linaro@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Acked-by: Stanimir Varbanov svarbanov@mm-sol.com Cc: stable@vger.kernel.org # 4.5 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/dwc/pcie-qcom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -1629,11 +1629,13 @@ static int qcom_pcie_probe(struct platfo ret = dw_pcie_host_init(pp); if (ret) { dev_err(dev, "cannot initialize host\n"); - goto err_pm_runtime_put; + goto err_phy_exit; }
return 0;
+err_phy_exit: + phy_exit(pcie->phy); err_pm_runtime_put: pm_runtime_put(dev); pm_runtime_disable(dev);
From: Denis Efremov denis.e.efremov@oracle.com
commit bc10916e890948d8927a5c8c40fb5dc44be5e1b8 upstream.
This code has a check to prevent read overflow but it needs another check to prevent writing beyond the end of the ->Ssid[] array.
Fixes: 2b42bd58b321 ("staging: r8188eu: introduce new os_dep dir for RTL8188eu driver") Cc: stable stable@vger.kernel.org Signed-off-by: Denis Efremov denis.e.efremov@oracle.com Link: https://lore.kernel.org/r/20220518070052.108287-1-denis.e.efremov@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -1131,9 +1131,11 @@ static int rtw_wx_set_scan(struct net_de break; } sec_len = *(pos++); len -= 1; - if (sec_len > 0 && sec_len <= len) { + if (sec_len > 0 && + sec_len <= len && + sec_len <= 32) { ssid[ssid_index].SsidLength = sec_len; - memcpy(ssid[ssid_index].Ssid, pos, ssid[ssid_index].SsidLength); + memcpy(ssid[ssid_index].Ssid, pos, sec_len); ssid_index++; } pos += sec_len;
From: Damien Le Moal damien.lemoal@opensource.wdc.com
commit 41e46b3c2aa24f755b2ae9ec4ce931ba5f0d8532 upstream.
When being read, a sysfs attribute is already protected against removal with the kobject node active reference counter. As a result, in blk_ia_range_sysfs_show(), there is no need to take the queue sysfs lock when reading the value of a range attribute. Using the queue sysfs lock in this function creates a potential deadlock situation with the disk removal, something that a lockdep signals with a splat when the device is removed:
[ 760.703551] Possible unsafe locking scenario: [ 760.703551] [ 760.703554] CPU0 CPU1 [ 760.703556] ---- ---- [ 760.703558] lock(&q->sysfs_lock); [ 760.703565] lock(kn->active#385); [ 760.703573] lock(&q->sysfs_lock); [ 760.703579] lock(kn->active#385); [ 760.703587] [ 760.703587] *** DEADLOCK ***
Solve this by removing the mutex_lock()/mutex_unlock() calls from blk_ia_range_sysfs_show().
Fixes: a2247f19ee1c ("block: Add independent access ranges support") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal damien.lemoal@opensource.wdc.com Link: https://lore.kernel.org/r/20220603021905.1441419-1-damien.lemoal@opensource.... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-ia-ranges.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
--- a/block/blk-ia-ranges.c +++ b/block/blk-ia-ranges.c @@ -54,13 +54,8 @@ static ssize_t blk_ia_range_sysfs_show(s container_of(attr, struct blk_ia_range_sysfs_entry, attr); struct blk_independent_access_range *iar = container_of(kobj, struct blk_independent_access_range, kobj); - ssize_t ret;
- mutex_lock(&iar->queue->sysfs_lock); - ret = entry->show(iar, buf); - mutex_unlock(&iar->queue->sysfs_lock); - - return ret; + return entry->show(iar, buf); }
static const struct sysfs_ops blk_ia_range_sysfs_ops = {
From: Rei Yamamoto yamamoto.rei@jp.fujitsu.com
commit bbe832b9db2e1ad21522f8f0bf02775fff8a0e0e upstream.
At present, pages not in the target zone are added to cc->migratepages list in isolate_migratepages_block(). As a result, pages may migrate between nodes unintentionally.
This would be a serious problem for older kernels without commit a984226f457f849e ("mm: memcontrol: remove the pgdata parameter of mem_cgroup_page_lruvec"), because it can corrupt the lru list by handling pages in list without holding proper lru_lock.
Avoid returning a pfn outside the target zone in the case that it is not aligned with a pageblock boundary. Otherwise isolate_migratepages_block() will handle pages not in the target zone.
Link: https://lkml.kernel.org/r/20220511044300.4069-1-yamamoto.rei@jp.fujitsu.com Fixes: 70b44595eafe ("mm, compaction: use free lists to quickly locate a migration source") Signed-off-by: Rei Yamamoto yamamoto.rei@jp.fujitsu.com Reviewed-by: Miaohe Lin linmiaohe@huawei.com Acked-by: Mel Gorman mgorman@techsingularity.net Reviewed-by: Oscar Salvador osalvador@suse.de Cc: Don Dutile ddutile@redhat.com Cc: Wonhyuk Yang vvghjk1234@gmail.com Cc: Rei Yamamoto yamamoto.rei@jp.fujitsu.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/compaction.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/mm/compaction.c +++ b/mm/compaction.c @@ -1858,6 +1858,8 @@ static unsigned long fast_find_migratebl
update_fast_start_pfn(cc, free_pfn); pfn = pageblock_start_pfn(free_pfn); + if (pfn < cc->zone->zone_start_pfn) + pfn = cc->zone->zone_start_pfn; cc->fast_search_fail = 0; found_block = true; set_pageblock_skip(freepage);
From: Nico Boehr nrb@linux.ibm.com
commit c9bfb460c3e4da2462e16b0f0b200990b36b1dd2 upstream.
Since commit 1179f170b6f0 ("s390: fix fpu restore in entry.S"), the sie_block pointer is located at empty1[1], but in sie_block() it was taken from empty1[0].
This leads to a random pointer being dereferenced, possibly causing system crash.
This problem can be observed when running a simple guest with an endless loop and recording the cpu-clock event:
sudo perf kvm --guestvmlinux=<guestkernel> --guest top -e cpu-clock
With this fix, the correct guest address is shown.
Fixes: 1179f170b6f0 ("s390: fix fpu restore in entry.S") Cc: stable@vger.kernel.org Acked-by: Christian Borntraeger borntraeger@de.ibm.com Acked-by: Claudio Imbrenda imbrenda@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Nico Boehr nrb@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kernel/perf_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -30,7 +30,7 @@ static struct kvm_s390_sie_block *sie_bl if (!stack) return NULL;
- return (struct kvm_s390_sie_block *) stack->empty1[0]; + return (struct kvm_s390_sie_block *)stack->empty1[1]; }
static bool is_in_guest(struct pt_regs *regs)
From: Sven Schnelle svens@linux.ibm.com
commit 5ace65ebb5ce9fe1cc8fdbdd97079fb566ef0ea4 upstream.
clock_delta is declared as unsigned long in various places. However, the clock sync delta can be negative. This would add a huge positive offset in clock_sync_global where clock_delta is added to clk.eitod which is a 72 bit integer. Declare it as signed long to fix this.
Cc: stable@vger.kernel.org Signed-off-by: Sven Schnelle svens@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/include/asm/cio.h | 2 +- arch/s390/kernel/time.c | 8 ++++---- drivers/s390/cio/chsc.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-)
--- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h @@ -369,7 +369,7 @@ void cio_gp_dma_destroy(struct gen_pool struct gen_pool *cio_gp_dma_create(struct device *dma_dev, int nr_pages);
/* Function from drivers/s390/cio/chsc.c */ -int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta); +int chsc_sstpc(void *page, unsigned int op, u16 ctrl, long *clock_delta); int chsc_sstpi(void *page, void *result, size_t size); int chsc_stzi(void *page, void *result, size_t size); int chsc_sgib(u32 origin); --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -364,7 +364,7 @@ static inline int check_sync_clock(void) * Apply clock delta to the global data structures. * This is called once on the CPU that performed the clock sync. */ -static void clock_sync_global(unsigned long delta) +static void clock_sync_global(long delta) { unsigned long now, adj; struct ptff_qto qto; @@ -400,7 +400,7 @@ static void clock_sync_global(unsigned l * Apply clock delta to the per-CPU data structures of this CPU. * This is called for each online CPU after the call to clock_sync_global. */ -static void clock_sync_local(unsigned long delta) +static void clock_sync_local(long delta) { /* Add the delta to the clock comparator. */ if (S390_lowcore.clock_comparator != clock_comparator_max) { @@ -424,7 +424,7 @@ static void __init time_init_wq(void) struct clock_sync_data { atomic_t cpus; int in_sync; - unsigned long clock_delta; + long clock_delta; };
/* @@ -544,7 +544,7 @@ static int stpinfo_valid(void) static int stp_sync_clock(void *data) { struct clock_sync_data *sync = data; - u64 clock_delta, flags; + long clock_delta, flags; static int first; int rc;
--- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -1255,7 +1255,7 @@ exit: EXPORT_SYMBOL_GPL(css_general_characteristics); EXPORT_SYMBOL_GPL(css_chsc_characteristics);
-int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta) +int chsc_sstpc(void *page, unsigned int op, u16 ctrl, long *clock_delta) { struct { struct chsc_header request; @@ -1266,7 +1266,7 @@ int chsc_sstpc(void *page, unsigned int unsigned int rsvd2[5]; struct chsc_header response; unsigned int rsvd3[3]; - u64 clock_delta; + s64 clock_delta; unsigned int rsvd4[2]; } *rr; int rc;
From: Alexander Aring aahringo@redhat.com
commit 42252d0d2aa9b94d168241710a761588b3959019 upstream.
This patch fixes an invalid read showed by KASAN. A unlock will allocate a "struct plock_op" and a followed send_op() will append it to a global send_list data structure. In some cases a followed dev_read() moves it to recv_list and dev_write() will cast it to "struct plock_xop" and access fields which are only available in those structures. At this point an invalid read happens by accessing those fields.
To fix this issue the "callback" field is moved to "struct plock_op" to indicate that a cast to "plock_xop" is allowed and does the additional "plock_xop" handling if set.
Example of the KASAN output which showed the invalid read:
[ 2064.296453] ================================================================== [ 2064.304852] BUG: KASAN: slab-out-of-bounds in dev_write+0x52b/0x5a0 [dlm] [ 2064.306491] Read of size 8 at addr ffff88800ef227d8 by task dlm_controld/7484 [ 2064.308168] [ 2064.308575] CPU: 0 PID: 7484 Comm: dlm_controld Kdump: loaded Not tainted 5.14.0+ #9 [ 2064.310292] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 [ 2064.311618] Call Trace: [ 2064.312218] dump_stack_lvl+0x56/0x7b [ 2064.313150] print_address_description.constprop.8+0x21/0x150 [ 2064.314578] ? dev_write+0x52b/0x5a0 [dlm] [ 2064.315610] ? dev_write+0x52b/0x5a0 [dlm] [ 2064.316595] kasan_report.cold.14+0x7f/0x11b [ 2064.317674] ? dev_write+0x52b/0x5a0 [dlm] [ 2064.318687] dev_write+0x52b/0x5a0 [dlm] [ 2064.319629] ? dev_read+0x4a0/0x4a0 [dlm] [ 2064.320713] ? bpf_lsm_kernfs_init_security+0x10/0x10 [ 2064.321926] vfs_write+0x17e/0x930 [ 2064.322769] ? __fget_light+0x1aa/0x220 [ 2064.323753] ksys_write+0xf1/0x1c0 [ 2064.324548] ? __ia32_sys_read+0xb0/0xb0 [ 2064.325464] do_syscall_64+0x3a/0x80 [ 2064.326387] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 2064.327606] RIP: 0033:0x7f807e4ba96f [ 2064.328470] Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 39 87 f8 ff 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 7c 87 f8 ff 48 [ 2064.332902] RSP: 002b:00007ffd50cfe6e0 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 [ 2064.334658] RAX: ffffffffffffffda RBX: 000055cc3886eb30 RCX: 00007f807e4ba96f [ 2064.336275] RDX: 0000000000000040 RSI: 00007ffd50cfe7e0 RDI: 0000000000000010 [ 2064.337980] RBP: 00007ffd50cfe7e0 R08: 0000000000000000 R09: 0000000000000001 [ 2064.339560] R10: 000055cc3886eb30 R11: 0000000000000293 R12: 000055cc3886eb80 [ 2064.341237] R13: 000055cc3886eb00 R14: 000055cc3886f590 R15: 0000000000000001 [ 2064.342857] [ 2064.343226] Allocated by task 12438: [ 2064.344057] kasan_save_stack+0x1c/0x40 [ 2064.345079] __kasan_kmalloc+0x84/0xa0 [ 2064.345933] kmem_cache_alloc_trace+0x13b/0x220 [ 2064.346953] dlm_posix_unlock+0xec/0x720 [dlm] [ 2064.348811] do_lock_file_wait.part.32+0xca/0x1d0 [ 2064.351070] fcntl_setlk+0x281/0xbc0 [ 2064.352879] do_fcntl+0x5e4/0xfe0 [ 2064.354657] __x64_sys_fcntl+0x11f/0x170 [ 2064.356550] do_syscall_64+0x3a/0x80 [ 2064.358259] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 2064.360745] [ 2064.361511] Last potentially related work creation: [ 2064.363957] kasan_save_stack+0x1c/0x40 [ 2064.365811] __kasan_record_aux_stack+0xaf/0xc0 [ 2064.368100] call_rcu+0x11b/0xf70 [ 2064.369785] dlm_process_incoming_buffer+0x47d/0xfd0 [dlm] [ 2064.372404] receive_from_sock+0x290/0x770 [dlm] [ 2064.374607] process_recv_sockets+0x32/0x40 [dlm] [ 2064.377290] process_one_work+0x9a8/0x16e0 [ 2064.379357] worker_thread+0x87/0xbf0 [ 2064.381188] kthread+0x3ac/0x490 [ 2064.383460] ret_from_fork+0x22/0x30 [ 2064.385588] [ 2064.386518] Second to last potentially related work creation: [ 2064.389219] kasan_save_stack+0x1c/0x40 [ 2064.391043] __kasan_record_aux_stack+0xaf/0xc0 [ 2064.393303] call_rcu+0x11b/0xf70 [ 2064.394885] dlm_process_incoming_buffer+0x47d/0xfd0 [dlm] [ 2064.397694] receive_from_sock+0x290/0x770 [dlm] [ 2064.399932] process_recv_sockets+0x32/0x40 [dlm] [ 2064.402180] process_one_work+0x9a8/0x16e0 [ 2064.404388] worker_thread+0x87/0xbf0 [ 2064.406124] kthread+0x3ac/0x490 [ 2064.408021] ret_from_fork+0x22/0x30 [ 2064.409834] [ 2064.410599] The buggy address belongs to the object at ffff88800ef22780 [ 2064.410599] which belongs to the cache kmalloc-96 of size 96 [ 2064.416495] The buggy address is located 88 bytes inside of [ 2064.416495] 96-byte region [ffff88800ef22780, ffff88800ef227e0) [ 2064.422045] The buggy address belongs to the page: [ 2064.424635] page:00000000b6bef8bc refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xef22 [ 2064.428970] flags: 0xfffffc0000200(slab|node=0|zone=1|lastcpupid=0x1fffff) [ 2064.432515] raw: 000fffffc0000200 ffffea0000d68b80 0000001400000014 ffff888001041780 [ 2064.436110] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000 [ 2064.439813] page dumped because: kasan: bad access detected [ 2064.442548] [ 2064.443310] Memory state around the buggy address: [ 2064.445988] ffff88800ef22680: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc [ 2064.449444] ffff88800ef22700: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc [ 2064.452941] >ffff88800ef22780: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc [ 2064.456383] ^ [ 2064.459386] ffff88800ef22800: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc [ 2064.462788] ffff88800ef22880: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc [ 2064.466239] ==================================================================
reproducer in python:
import argparse import struct import fcntl import os
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file', help='file to use fcntl, must be on dlm lock filesystem e.g. gfs2')
args = parser.parse_args()
f = open(args.file, 'wb+')
lockdata = struct.pack('hhllhh', fcntl.F_WRLCK,0,0,0,0,0) fcntl.fcntl(f, fcntl.F_SETLK, lockdata) lockdata = struct.pack('hhllhh', fcntl.F_UNLCK,0,0,0,0,0) fcntl.fcntl(f, fcntl.F_SETLK, lockdata)
Fixes: 586759f03e2e ("gfs2: nfs lock support for gfs2") Cc: stable@vger.kernel.org Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Alexander Aring aahringo@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/dlm/plock.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
--- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -23,11 +23,11 @@ struct plock_op { struct list_head list; int done; struct dlm_plock_info info; + int (*callback)(struct file_lock *fl, int result); };
struct plock_xop { struct plock_op xop; - int (*callback)(struct file_lock *fl, int result); void *fl; void *file; struct file_lock flc; @@ -129,19 +129,18 @@ int dlm_posix_lock(dlm_lockspace_t *lock /* fl_owner is lockd which doesn't distinguish processes on the nfs client */ op->info.owner = (__u64) fl->fl_pid; - xop->callback = fl->fl_lmops->lm_grant; + op->callback = fl->fl_lmops->lm_grant; locks_init_lock(&xop->flc); locks_copy_lock(&xop->flc, fl); xop->fl = fl; xop->file = file; } else { op->info.owner = (__u64)(long) fl->fl_owner; - xop->callback = NULL; }
send_op(op);
- if (xop->callback == NULL) { + if (!op->callback) { rv = wait_event_interruptible(recv_wq, (op->done != 0)); if (rv == -ERESTARTSYS) { log_debug(ls, "dlm_posix_lock: wait killed %llx", @@ -203,7 +202,7 @@ static int dlm_plock_callback(struct plo file = xop->file; flc = &xop->flc; fl = xop->fl; - notify = xop->callback; + notify = op->callback;
if (op->info.rv) { notify(fl, op->info.rv); @@ -436,10 +435,9 @@ static ssize_t dev_write(struct file *fi if (op->info.fsid == info.fsid && op->info.number == info.number && op->info.owner == info.owner) { - struct plock_xop *xop = (struct plock_xop *)op; list_del_init(&op->list); memcpy(&op->info, &info, sizeof(info)); - if (xop->callback) + if (op->callback) do_callback = 1; else op->done = 1;
From: Dan Carpenter dan.carpenter@oracle.com
commit 1f4f10845e14690b02410de50d9ea9684625a4ae upstream.
The "sock" variable is not initialized on this error path.
Cc: stable@vger.kernel.org Fixes: 2dc6b1158c28 ("fs: dlm: introduce generic listen") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Alexander Aring aahringo@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/dlm/lowcomms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1789,7 +1789,7 @@ static int dlm_listen_for_all(void) SOCK_STREAM, dlm_proto_ops->proto, &sock); if (result < 0) { log_print("Can't create comms socket: %d", result); - goto out; + return result; }
sock_set_mark(sock->sk, dlm_config.ci_mark);
From: Alexander Aring aahringo@redhat.com
commit f6f7418357457ed58cbb020fc97e74d4e0e7b47f upstream.
This patch move the wake_up() call at the point when a remove message completed. Before it was only when a remove message was going to be sent. The possible waiter in wait_pending_remove() waits until a remove is done if the resource name matches with the per ls variable ls->ls_remove_name. If this is the case we must wait until a pending remove is done which is indicated if DLM_WAIT_PENDING_COND() returns false which will always be the case when ls_remove_len and ls_remove_name are unset to indicate that a remove is not going on anymore.
Fixes: 21d9ac1a5376 ("fs: dlm: use event based wait for pending remove") Cc: stable@vger.kernel.org Signed-off-by: Alexander Aring aahringo@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/dlm/lock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1795,7 +1795,6 @@ static void shrink_bucket(struct dlm_ls memcpy(ls->ls_remove_name, name, DLM_RESNAME_MAXLEN); spin_unlock(&ls->ls_remove_spin); spin_unlock(&ls->ls_rsbtbl[b].lock); - wake_up(&ls->ls_remove_wait);
send_remove(r);
@@ -1804,6 +1803,7 @@ static void shrink_bucket(struct dlm_ls ls->ls_remove_len = 0; memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN); spin_unlock(&ls->ls_remove_spin); + wake_up(&ls->ls_remove_wait);
dlm_free_rsb(r); } @@ -4079,7 +4079,6 @@ static void send_repeat_remove(struct dl memcpy(ls->ls_remove_name, name, DLM_RESNAME_MAXLEN); spin_unlock(&ls->ls_remove_spin); spin_unlock(&ls->ls_rsbtbl[b].lock); - wake_up(&ls->ls_remove_wait);
rv = _create_message(ls, sizeof(struct dlm_message) + len, dir_nodeid, DLM_MSG_REMOVE, &ms, &mh); @@ -4095,6 +4094,7 @@ static void send_repeat_remove(struct dl ls->ls_remove_len = 0; memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN); spin_unlock(&ls->ls_remove_spin); + wake_up(&ls->ls_remove_wait); }
static int receive_request(struct dlm_ls *ls, struct dlm_message *ms)
From: Alexander Aring aahringo@redhat.com
commit 1689c169134f4b5a39156122d799b7dca76d8ddb upstream.
We always call hold_lkb(lkb) if we increment lkb->lkb_wait_count. So, we always need to call unhold_lkb(lkb) if we decrement lkb->lkb_wait_count. This patch will add missing unhold_lkb(lkb) if we decrement lkb->lkb_wait_count. In case of setting lkb->lkb_wait_count to zero we need to countdown until reaching zero and call unhold_lkb(lkb). The waiters list unhold_lkb(lkb) can be removed because it's done for the last lkb_wait_count decrement iteration as it's done in _remove_from_waiters().
This issue was discovered by a dlm gfs2 test case which use excessively dlm_unlock(LKF_CANCEL) feature. Probably the lkb->lkb_wait_count value never reached above 1 if this feature isn't used and so it was not discovered before.
The testcase ended in a rsb on the rsb keep data structure with a refcount of 1 but no lkb was associated with it, which is itself an invalid behaviour. A side effect of that was a condition in which the dlm was sending remove messages in a looping behaviour. With this patch that has not been reproduced.
Cc: stable@vger.kernel.org Signed-off-by: Alexander Aring aahringo@redhat.com Signed-off-by: David Teigland teigland@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/dlm/lock.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
--- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -1559,6 +1559,7 @@ static int _remove_from_waiters(struct d lkb->lkb_wait_type = 0; lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; lkb->lkb_wait_count--; + unhold_lkb(lkb); goto out_del; }
@@ -1585,6 +1586,7 @@ static int _remove_from_waiters(struct d log_error(ls, "remwait error %x reply %d wait_type %d overlap", lkb->lkb_id, mstype, lkb->lkb_wait_type); lkb->lkb_wait_count--; + unhold_lkb(lkb); lkb->lkb_wait_type = 0; }
@@ -5331,11 +5333,16 @@ int dlm_recover_waiters_post(struct dlm_ lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK; lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; lkb->lkb_wait_type = 0; - lkb->lkb_wait_count = 0; + /* drop all wait_count references we still + * hold a reference for this iteration. + */ + while (lkb->lkb_wait_count) { + lkb->lkb_wait_count--; + unhold_lkb(lkb); + } mutex_lock(&ls->ls_waiters_mutex); list_del_init(&lkb->lkb_wait_reply); mutex_unlock(&ls->ls_waiters_mutex); - unhold_lkb(lkb); /* for waiters list */
if (oc || ou) { /* do an unlock or cancel instead of resending */
From: Junxiao Bi via Ocfs2-devel ocfs2-devel@oss.oracle.com
commit 863e0d81b6683c4cbc588ad831f560c90e494bef upstream.
When user_dlm_destroy_lock failed, it didn't clean up the flags it set before exit. For USER_LOCK_IN_TEARDOWN, if this function fails because of lock is still in used, next time when unlink invokes this function, it will return succeed, and then unlink will remove inode and dentry if lock is not in used(file closed), but the dlm lock is still linked in dlm lock resource, then when bast come in, it will trigger a panic due to user-after-free. See the following panic call trace. To fix this, USER_LOCK_IN_TEARDOWN should be reverted if fail. And also error should be returned if USER_LOCK_IN_TEARDOWN is set to let user know that unlink fail.
For the case of ocfs2_dlm_unlock failure, besides USER_LOCK_IN_TEARDOWN, USER_LOCK_BUSY is also required to be cleared. Even though spin lock is released in between, but USER_LOCK_IN_TEARDOWN is still set, for USER_LOCK_BUSY, if before every place that waits on this flag, USER_LOCK_IN_TEARDOWN is checked to bail out, that will make sure no flow waits on the busy flag set by user_dlm_destroy_lock(), then we can simplely revert USER_LOCK_BUSY when ocfs2_dlm_unlock fails. Fix user_dlm_cluster_lock() which is the only function not following this.
[ 941.336392] (python,26174,16):dlmfs_unlink:562 ERROR: unlink 004fb0000060000b5a90b8c847b72e1, error -16 from destroy [ 989.757536] ------------[ cut here ]------------ [ 989.757709] kernel BUG at fs/ocfs2/dlmfs/userdlm.c:173! [ 989.757876] invalid opcode: 0000 [#1] SMP [ 989.758027] Modules linked in: ksplice_2zhuk2jr_ib_ipoib_new(O) ksplice_2zhuk2jr(O) mptctl mptbase xen_netback xen_blkback xen_gntalloc xen_gntdev xen_evtchn cdc_ether usbnet mii ocfs2 jbd2 rpcsec_gss_krb5 auth_rpcgss nfsv4 nfsv3 nfs_acl nfs fscache lockd grace ocfs2_dlmfs ocfs2_stack_o2cb ocfs2_dlm ocfs2_nodemanager ocfs2_stackglue configfs bnx2fc fcoe libfcoe libfc scsi_transport_fc sunrpc ipmi_devintf bridge stp llc rds_rdma rds bonding ib_sdp ib_ipoib rdma_ucm ib_ucm ib_uverbs ib_umad rdma_cm ib_cm iw_cm falcon_lsm_serviceable(PE) falcon_nf_netcontain(PE) mlx4_vnic falcon_kal(E) falcon_lsm_pinned_13402(E) mlx4_ib ib_sa ib_mad ib_core ib_addr xenfs xen_privcmd dm_multipath iTCO_wdt iTCO_vendor_support pcspkr sb_edac edac_core i2c_i801 lpc_ich mfd_core ipmi_ssif i2c_core ipmi_si ipmi_msghandler [ 989.760686] ioatdma sg ext3 jbd mbcache sd_mod ahci libahci ixgbe dca ptp pps_core vxlan udp_tunnel ip6_udp_tunnel megaraid_sas mlx4_core crc32c_intel be2iscsi bnx2i cnic uio cxgb4i cxgb4 cxgb3i libcxgbi ipv6 cxgb3 mdio libiscsi_tcp qla4xxx iscsi_boot_sysfs libiscsi scsi_transport_iscsi wmi dm_mirror dm_region_hash dm_log dm_mod [last unloaded: ksplice_2zhuk2jr_ib_ipoib_old] [ 989.761987] CPU: 10 PID: 19102 Comm: dlm_thread Tainted: P OE 4.1.12-124.57.1.el6uek.x86_64 #2 [ 989.762290] Hardware name: Oracle Corporation ORACLE SERVER X5-2/ASM,MOTHERBOARD,1U, BIOS 30350100 06/17/2021 [ 989.762599] task: ffff880178af6200 ti: ffff88017f7c8000 task.ti: ffff88017f7c8000 [ 989.762848] RIP: e030:[<ffffffffc07d4316>] [<ffffffffc07d4316>] __user_dlm_queue_lockres.part.4+0x76/0x80 [ocfs2_dlmfs] [ 989.763185] RSP: e02b:ffff88017f7cbcb8 EFLAGS: 00010246 [ 989.763353] RAX: 0000000000000000 RBX: ffff880174d48008 RCX: 0000000000000003 [ 989.763565] RDX: 0000000000120012 RSI: 0000000000000003 RDI: ffff880174d48170 [ 989.763778] RBP: ffff88017f7cbcc8 R08: ffff88021f4293b0 R09: 0000000000000000 [ 989.763991] R10: ffff880179c8c000 R11: 0000000000000003 R12: ffff880174d48008 [ 989.764204] R13: 0000000000000003 R14: ffff880179c8c000 R15: ffff88021db7a000 [ 989.764422] FS: 0000000000000000(0000) GS:ffff880247480000(0000) knlGS:ffff880247480000 [ 989.764685] CS: e033 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 989.764865] CR2: ffff8000007f6800 CR3: 0000000001ae0000 CR4: 0000000000042660 [ 989.765081] Stack: [ 989.765167] 0000000000000003 ffff880174d48040 ffff88017f7cbd18 ffffffffc07d455f [ 989.765442] ffff88017f7cbd88 ffffffff816fb639 ffff88017f7cbd38 ffff8800361b5600 [ 989.765717] ffff88021db7a000 ffff88021f429380 0000000000000003 ffffffffc0453020 [ 989.765991] Call Trace: [ 989.766093] [<ffffffffc07d455f>] user_bast+0x5f/0xf0 [ocfs2_dlmfs] [ 989.766287] [<ffffffff816fb639>] ? schedule_timeout+0x169/0x2d0 [ 989.766475] [<ffffffffc0453020>] ? o2dlm_lock_ast_wrapper+0x20/0x20 [ocfs2_stack_o2cb] [ 989.766738] [<ffffffffc045303a>] o2dlm_blocking_ast_wrapper+0x1a/0x20 [ocfs2_stack_o2cb] [ 989.767010] [<ffffffffc0864ec6>] dlm_do_local_bast+0x46/0xe0 [ocfs2_dlm] [ 989.767217] [<ffffffffc084f5cc>] ? dlm_lockres_calc_usage+0x4c/0x60 [ocfs2_dlm] [ 989.767466] [<ffffffffc08501f1>] dlm_thread+0xa31/0x1140 [ocfs2_dlm] [ 989.767662] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.767834] [<ffffffff816f78ce>] ? __schedule+0x23e/0x810 [ 989.768006] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.768178] [<ffffffff816f78ce>] ? __schedule+0x23e/0x810 [ 989.768349] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.768521] [<ffffffff816f78ce>] ? __schedule+0x23e/0x810 [ 989.768693] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.768893] [<ffffffff816f78ce>] ? __schedule+0x23e/0x810 [ 989.769067] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.769241] [<ffffffff810ce4d0>] ? wait_woken+0x90/0x90 [ 989.769411] [<ffffffffc084f7c0>] ? dlm_kick_thread+0x80/0x80 [ocfs2_dlm] [ 989.769617] [<ffffffff810a8bbb>] kthread+0xcb/0xf0 [ 989.769774] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.769945] [<ffffffff816f78da>] ? __schedule+0x24a/0x810 [ 989.770117] [<ffffffff810a8af0>] ? kthread_create_on_node+0x180/0x180 [ 989.770321] [<ffffffff816fdaa1>] ret_from_fork+0x61/0x90 [ 989.770492] [<ffffffff810a8af0>] ? kthread_create_on_node+0x180/0x180 [ 989.770689] Code: d0 00 00 00 f0 45 7d c0 bf 00 20 00 00 48 89 83 c0 00 00 00 48 89 83 c8 00 00 00 e8 55 c1 8c c0 83 4b 04 10 48 83 c4 08 5b 5d c3 <0f> 0b 0f 1f 84 00 00 00 00 00 55 48 89 e5 41 55 41 54 53 48 83 [ 989.771892] RIP [<ffffffffc07d4316>] __user_dlm_queue_lockres.part.4+0x76/0x80 [ocfs2_dlmfs] [ 989.772174] RSP <ffff88017f7cbcb8> [ 989.772704] ---[ end trace ebd1e38cebcc93a8 ]--- [ 989.772907] Kernel panic - not syncing: Fatal exception [ 989.773173] Kernel Offset: disabled
Link: https://lkml.kernel.org/r/20220518235224.87100-2-junxiao.bi@oracle.com Signed-off-by: Junxiao Bi junxiao.bi@oracle.com Reviewed-by: Joseph Qi joseph.qi@linux.alibaba.com Cc: Mark Fasheh mark@fasheh.com Cc: Joel Becker jlbec@evilplan.org Cc: Joseph Qi jiangqi903@gmail.com Cc: Changwei Ge gechangwei@live.cn Cc: Gang He ghe@suse.com Cc: Jun Piao piaojun@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ocfs2/dlmfs/userdlm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
--- a/fs/ocfs2/dlmfs/userdlm.c +++ b/fs/ocfs2/dlmfs/userdlm.c @@ -433,6 +433,11 @@ again: }
spin_lock(&lockres->l_lock); + if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { + spin_unlock(&lockres->l_lock); + status = -EAGAIN; + goto bail; + }
/* We only compare against the currently granted level * here. If the lock is blocked waiting on a downconvert, @@ -595,7 +600,7 @@ int user_dlm_destroy_lock(struct user_lo spin_lock(&lockres->l_lock); if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) { spin_unlock(&lockres->l_lock); - return 0; + goto bail; }
lockres->l_flags |= USER_LOCK_IN_TEARDOWN; @@ -609,12 +614,17 @@ int user_dlm_destroy_lock(struct user_lo }
if (lockres->l_ro_holders || lockres->l_ex_holders) { + lockres->l_flags &= ~USER_LOCK_IN_TEARDOWN; spin_unlock(&lockres->l_lock); goto bail; }
status = 0; if (!(lockres->l_flags & USER_LOCK_ATTACHED)) { + /* + * lock is never requested, leave USER_LOCK_IN_TEARDOWN set + * to avoid new lock request coming in. + */ spin_unlock(&lockres->l_lock); goto bail; } @@ -625,6 +635,10 @@ int user_dlm_destroy_lock(struct user_lo
status = ocfs2_dlm_unlock(conn, &lockres->l_lksb, DLM_LKF_VALBLK); if (status) { + spin_lock(&lockres->l_lock); + lockres->l_flags &= ~USER_LOCK_IN_TEARDOWN; + lockres->l_flags &= ~USER_LOCK_BUSY; + spin_unlock(&lockres->l_lock); user_log_dlm_error("ocfs2_dlm_unlock", status, lockres); goto bail; }
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 036a45aa587a10fa2abbd50fbd0f6c4cfc44f69f upstream.
The bug is here:
p->target_id, p->target_lun);
The list iterator 'p' 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 an invalid memory access.
To fix this bug, add a check. Use a new variable 'iter' as the list iterator, and use the original variable 'p' as a dedicated pointer to point to the found element.
Link: https://lore.kernel.org/r/20220414040231.2662-1-xiam0nd.tong@gmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/dc395x.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
--- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -3585,10 +3585,19 @@ static struct DeviceCtlBlk *device_alloc #endif if (dcb->target_lun != 0) { /* Copy settings */ - struct DeviceCtlBlk *p; - list_for_each_entry(p, &acb->dcb_list, list) - if (p->target_id == dcb->target_id) + struct DeviceCtlBlk *p = NULL, *iter; + + list_for_each_entry(iter, &acb->dcb_list, list) + if (iter->target_id == dcb->target_id) { + p = iter; break; + } + + if (!p) { + kfree(dcb); + return NULL; + } + dprintkdbg(DBG_1, "device_alloc: <%02i-%i> copy from <%02i-%i>\n", dcb->target_id, dcb->target_lun,
From: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org
commit 8eecddfca30e1651dc1c74531ed5eef21dcce7e3 upstream.
In ufs_qcom_dev_ref_clk_ctrl(), it was noted that the ref_clk needs to be stable for at least 1us. Even though there is wmb() to make sure the write gets "completed", there is no guarantee that the write actually reached the UFS device. There is a good chance that the write could be stored in a Write Buffer (WB). In that case, even though the CPU waits for 1us, the ref_clk might not be stable for that period.
So lets do a readl() to make sure that the previous write has reached the UFS device before udelay().
Also, the wmb() after writel_relaxed() is not really needed. Both writel() and readl() are ordered on all architectures and the CPU won't speculate instructions after readl() due to the in-built control dependency with read value on weakly ordered architectures. So it can be safely removed.
Link: https://lore.kernel.org/r/20220504084212.11605-4-manivannan.sadhasivam@linar... Fixes: f06fcc7155dc ("scsi: ufs-qcom: add QUniPro hardware support and power optimizations") Cc: stable@vger.kernel.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/ufs/ufs-qcom.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -682,8 +682,11 @@ static void ufs_qcom_dev_ref_clk_ctrl(st
writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio);
- /* ensure that ref_clk is enabled/disabled before we return */ - wmb(); + /* + * Make sure the write to ref_clk reaches the destination and + * not stored in a Write Buffer (WB). + */ + readl(host->dev_ref_clk_ctrl_mmio);
/* * If we call hibern8 exit after this, we need to make sure that
From: Mickaël Salaün mic@digikod.net
commit 6cc2df8e3a3967e7c13a424f87f6efb1d4a62d80 upstream.
In preparation to a following commit, add clang-format on and clang-format off stanzas around constant definitions. This enables to keep aligned values, which is much more readable than packed definitions.
Link: https://lore.kernel.org/r/20220506160513.523257-2-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/landlock.h | 4 ++++ security/landlock/fs.c | 2 ++ security/landlock/limits.h | 4 ++++ 3 files changed, 10 insertions(+)
--- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -33,7 +33,9 @@ struct landlock_ruleset_attr { * - %LANDLOCK_CREATE_RULESET_VERSION: Get the highest supported Landlock ABI * version. */ +/* clang-format off */ #define LANDLOCK_CREATE_RULESET_VERSION (1U << 0) +/* clang-format on */
/** * enum landlock_rule_type - Landlock rule type @@ -120,6 +122,7 @@ struct landlock_path_beneath_attr { * :manpage:`access(2)`. * Future Landlock evolutions will enable to restrict them. */ +/* clang-format off */ #define LANDLOCK_ACCESS_FS_EXECUTE (1ULL << 0) #define LANDLOCK_ACCESS_FS_WRITE_FILE (1ULL << 1) #define LANDLOCK_ACCESS_FS_READ_FILE (1ULL << 2) @@ -133,5 +136,6 @@ struct landlock_path_beneath_attr { #define LANDLOCK_ACCESS_FS_MAKE_FIFO (1ULL << 10) #define LANDLOCK_ACCESS_FS_MAKE_BLOCK (1ULL << 11) #define LANDLOCK_ACCESS_FS_MAKE_SYM (1ULL << 12) +/* clang-format on */
#endif /* _UAPI_LINUX_LANDLOCK_H */ --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -141,10 +141,12 @@ retry: }
/* All access rights that can be tied to files. */ +/* clang-format off */ #define ACCESS_FILE ( \ LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE) +/* clang-format on */
/* * @path: Should have been checked by get_path_from_fd(). --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -12,10 +12,14 @@ #include <linux/limits.h> #include <uapi/linux/landlock.h>
+/* clang-format off */ + #define LANDLOCK_MAX_NUM_LAYERS 64 #define LANDLOCK_MAX_NUM_RULES U32_MAX
#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_SYM #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1)
+/* clang-format on */ + #endif /* _SECURITY_LANDLOCK_LIMITS_H */
From: Mickaël Salaün mic@digikod.net
commit 06a1c40a09a8dded4bf0e7e3ccbda6bddcccd7c8 upstream.
Let's follow a consistent and documented coding style. Everything may not be to our liking but it is better than tacit knowledge. Moreover, this will help maintain style consistency between different developers.
This contains only whitespace changes.
Automatically formatted with: clang-format-14 -i security/landlock/*.[ch] include/uapi/linux/landlock.h
Link: https://lore.kernel.org/r/20220506160513.523257-3-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/landlock/cred.c | 4 +- security/landlock/cred.h | 8 ++-- security/landlock/fs.c | 78 +++++++++++++++++++++-------------------- security/landlock/fs.h | 11 +++-- security/landlock/object.c | 6 +-- security/landlock/object.h | 6 +-- security/landlock/ptrace.c | 10 ++--- security/landlock/ruleset.c | 80 +++++++++++++++++++++---------------------- security/landlock/ruleset.h | 15 ++++---- security/landlock/syscalls.c | 60 ++++++++++++++++---------------- 10 files changed, 142 insertions(+), 136 deletions(-)
--- a/security/landlock/cred.c +++ b/security/landlock/cred.c @@ -15,7 +15,7 @@ #include "setup.h"
static int hook_cred_prepare(struct cred *const new, - const struct cred *const old, const gfp_t gfp) + const struct cred *const old, const gfp_t gfp) { struct landlock_ruleset *const old_dom = landlock_cred(old)->domain;
@@ -42,5 +42,5 @@ static struct security_hook_list landloc __init void landlock_add_cred_hooks(void) { security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), - LANDLOCK_NAME); + LANDLOCK_NAME); } --- a/security/landlock/cred.h +++ b/security/landlock/cred.h @@ -20,8 +20,8 @@ struct landlock_cred_security { struct landlock_ruleset *domain; };
-static inline struct landlock_cred_security *landlock_cred( - const struct cred *cred) +static inline struct landlock_cred_security * +landlock_cred(const struct cred *cred) { return cred->security + landlock_blob_sizes.lbs_cred; } @@ -34,8 +34,8 @@ static inline const struct landlock_rule /* * The call needs to come from an RCU read-side critical section. */ -static inline const struct landlock_ruleset *landlock_get_task_domain( - const struct task_struct *const task) +static inline const struct landlock_ruleset * +landlock_get_task_domain(const struct task_struct *const task) { return landlock_cred(__task_cred(task))->domain; } --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -152,14 +152,14 @@ retry: * @path: Should have been checked by get_path_from_fd(). */ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, - const struct path *const path, u32 access_rights) + const struct path *const path, u32 access_rights) { int err; struct landlock_object *object;
/* Files only get access rights that make sense. */ - if (!d_is_dir(path->dentry) && (access_rights | ACCESS_FILE) != - ACCESS_FILE) + if (!d_is_dir(path->dentry) && + (access_rights | ACCESS_FILE) != ACCESS_FILE) return -EINVAL; if (WARN_ON_ONCE(ruleset->num_layers != 1)) return -EINVAL; @@ -182,10 +182,9 @@ int landlock_append_fs_rule(struct landl
/* Access-control management */
-static inline u64 unmask_layers( - const struct landlock_ruleset *const domain, - const struct path *const path, const u32 access_request, - u64 layer_mask) +static inline u64 unmask_layers(const struct landlock_ruleset *const domain, + const struct path *const path, + const u32 access_request, u64 layer_mask) { const struct landlock_rule *rule; const struct inode *inode; @@ -196,8 +195,8 @@ static inline u64 unmask_layers( return layer_mask; inode = d_backing_inode(path->dentry); rcu_read_lock(); - rule = landlock_find_rule(domain, - rcu_dereference(landlock_inode(inode)->object)); + rule = landlock_find_rule( + domain, rcu_dereference(landlock_inode(inode)->object)); rcu_read_unlock(); if (!rule) return layer_mask; @@ -225,7 +224,7 @@ static inline u64 unmask_layers( }
static int check_access_path(const struct landlock_ruleset *const domain, - const struct path *const path, u32 access_request) + const struct path *const path, u32 access_request) { bool allowed = false; struct path walker_path; @@ -245,8 +244,8 @@ static int check_access_path(const struc * /proc/<pid>/fd/<file-descriptor> . */ if ((path->dentry->d_sb->s_flags & SB_NOUSER) || - (d_is_positive(path->dentry) && - unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))) + (d_is_positive(path->dentry) && + unlikely(IS_PRIVATE(d_backing_inode(path->dentry))))) return 0; if (WARN_ON_ONCE(domain->num_layers < 1)) return -EACCES; @@ -270,8 +269,8 @@ static int check_access_path(const struc while (true) { struct dentry *parent_dentry;
- layer_mask = unmask_layers(domain, &walker_path, - access_request, layer_mask); + layer_mask = unmask_layers(domain, &walker_path, access_request, + layer_mask); if (layer_mask == 0) { /* Stops when a rule from each layer grants access. */ allowed = true; @@ -310,7 +309,7 @@ jump_up: }
static inline int current_check_access_path(const struct path *const path, - const u32 access_request) + const u32 access_request) { const struct landlock_ruleset *const dom = landlock_get_current_domain(); @@ -438,8 +437,8 @@ static void hook_sb_delete(struct super_ if (prev_inode) iput(prev_inode); /* Waits for pending iput() in release_inode(). */ - wait_var_event(&landlock_superblock(sb)->inode_refs, !atomic_long_read( - &landlock_superblock(sb)->inode_refs)); + wait_var_event(&landlock_superblock(sb)->inode_refs, + !atomic_long_read(&landlock_superblock(sb)->inode_refs)); }
/* @@ -461,8 +460,8 @@ static void hook_sb_delete(struct super_ * a dedicated user space option would be required (e.g. as a ruleset flag). */ static int hook_sb_mount(const char *const dev_name, - const struct path *const path, const char *const type, - const unsigned long flags, void *const data) + const struct path *const path, const char *const type, + const unsigned long flags, void *const data) { if (!landlock_get_current_domain()) return 0; @@ -470,7 +469,7 @@ static int hook_sb_mount(const char *con }
static int hook_move_mount(const struct path *const from_path, - const struct path *const to_path) + const struct path *const to_path) { if (!landlock_get_current_domain()) return 0; @@ -504,7 +503,7 @@ static int hook_sb_remount(struct super_ * view of the filesystem. */ static int hook_sb_pivotroot(const struct path *const old_path, - const struct path *const new_path) + const struct path *const new_path) { if (!landlock_get_current_domain()) return 0; @@ -547,8 +546,8 @@ static inline u32 get_mode_access(const * deal with that. */ static int hook_path_link(struct dentry *const old_dentry, - const struct path *const new_dir, - struct dentry *const new_dentry) + const struct path *const new_dir, + struct dentry *const new_dentry) { const struct landlock_ruleset *const dom = landlock_get_current_domain(); @@ -561,8 +560,9 @@ static int hook_path_link(struct dentry return -EXDEV; if (unlikely(d_is_negative(old_dentry))) return -ENOENT; - return check_access_path(dom, new_dir, - get_mode_access(d_backing_inode(old_dentry)->i_mode)); + return check_access_path( + dom, new_dir, + get_mode_access(d_backing_inode(old_dentry)->i_mode)); }
static inline u32 maybe_remove(const struct dentry *const dentry) @@ -570,13 +570,13 @@ static inline u32 maybe_remove(const str if (d_is_negative(dentry)) return 0; return d_is_dir(dentry) ? LANDLOCK_ACCESS_FS_REMOVE_DIR : - LANDLOCK_ACCESS_FS_REMOVE_FILE; + LANDLOCK_ACCESS_FS_REMOVE_FILE; }
static int hook_path_rename(const struct path *const old_dir, - struct dentry *const old_dentry, - const struct path *const new_dir, - struct dentry *const new_dentry) + struct dentry *const old_dentry, + const struct path *const new_dir, + struct dentry *const new_dentry) { const struct landlock_ruleset *const dom = landlock_get_current_domain(); @@ -590,20 +590,21 @@ static int hook_path_rename(const struct if (unlikely(d_is_negative(old_dentry))) return -ENOENT; /* RENAME_EXCHANGE is handled because directories are the same. */ - return check_access_path(dom, old_dir, maybe_remove(old_dentry) | - maybe_remove(new_dentry) | + return check_access_path( + dom, old_dir, + maybe_remove(old_dentry) | maybe_remove(new_dentry) | get_mode_access(d_backing_inode(old_dentry)->i_mode)); }
static int hook_path_mkdir(const struct path *const dir, - struct dentry *const dentry, const umode_t mode) + struct dentry *const dentry, const umode_t mode) { return current_check_access_path(dir, LANDLOCK_ACCESS_FS_MAKE_DIR); }
static int hook_path_mknod(const struct path *const dir, - struct dentry *const dentry, const umode_t mode, - const unsigned int dev) + struct dentry *const dentry, const umode_t mode, + const unsigned int dev) { const struct landlock_ruleset *const dom = landlock_get_current_domain(); @@ -614,19 +615,20 @@ static int hook_path_mknod(const struct }
static int hook_path_symlink(const struct path *const dir, - struct dentry *const dentry, const char *const old_name) + struct dentry *const dentry, + const char *const old_name) { return current_check_access_path(dir, LANDLOCK_ACCESS_FS_MAKE_SYM); }
static int hook_path_unlink(const struct path *const dir, - struct dentry *const dentry) + struct dentry *const dentry) { return current_check_access_path(dir, LANDLOCK_ACCESS_FS_REMOVE_FILE); }
static int hook_path_rmdir(const struct path *const dir, - struct dentry *const dentry) + struct dentry *const dentry) { return current_check_access_path(dir, LANDLOCK_ACCESS_FS_REMOVE_DIR); } @@ -690,5 +692,5 @@ static struct security_hook_list landloc __init void landlock_add_fs_hooks(void) { security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), - LANDLOCK_NAME); + LANDLOCK_NAME); } --- a/security/landlock/fs.h +++ b/security/landlock/fs.h @@ -50,14 +50,14 @@ struct landlock_superblock_security { atomic_long_t inode_refs; };
-static inline struct landlock_inode_security *landlock_inode( - const struct inode *const inode) +static inline struct landlock_inode_security * +landlock_inode(const struct inode *const inode) { return inode->i_security + landlock_blob_sizes.lbs_inode; }
-static inline struct landlock_superblock_security *landlock_superblock( - const struct super_block *const superblock) +static inline struct landlock_superblock_security * +landlock_superblock(const struct super_block *const superblock) { return superblock->s_security + landlock_blob_sizes.lbs_superblock; } @@ -65,6 +65,7 @@ static inline struct landlock_superblock __init void landlock_add_fs_hooks(void);
int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, - const struct path *const path, u32 access_hierarchy); + const struct path *const path, + u32 access_hierarchy);
#endif /* _SECURITY_LANDLOCK_FS_H */ --- a/security/landlock/object.c +++ b/security/landlock/object.c @@ -17,9 +17,9 @@
#include "object.h"
-struct landlock_object *landlock_create_object( - const struct landlock_object_underops *const underops, - void *const underobj) +struct landlock_object * +landlock_create_object(const struct landlock_object_underops *const underops, + void *const underobj) { struct landlock_object *new_object;
--- a/security/landlock/object.h +++ b/security/landlock/object.h @@ -76,9 +76,9 @@ struct landlock_object { }; };
-struct landlock_object *landlock_create_object( - const struct landlock_object_underops *const underops, - void *const underobj); +struct landlock_object * +landlock_create_object(const struct landlock_object_underops *const underops, + void *const underobj);
void landlock_put_object(struct landlock_object *const object);
--- a/security/landlock/ptrace.c +++ b/security/landlock/ptrace.c @@ -30,7 +30,7 @@ * means a subset of) the @child domain. */ static bool domain_scope_le(const struct landlock_ruleset *const parent, - const struct landlock_ruleset *const child) + const struct landlock_ruleset *const child) { const struct landlock_hierarchy *walker;
@@ -48,7 +48,7 @@ static bool domain_scope_le(const struct }
static bool task_is_scoped(const struct task_struct *const parent, - const struct task_struct *const child) + const struct task_struct *const child) { bool is_scoped; const struct landlock_ruleset *dom_parent, *dom_child; @@ -62,7 +62,7 @@ static bool task_is_scoped(const struct }
static int task_ptrace(const struct task_struct *const parent, - const struct task_struct *const child) + const struct task_struct *const child) { /* Quick return for non-landlocked tasks. */ if (!landlocked(parent)) @@ -86,7 +86,7 @@ static int task_ptrace(const struct task * granted, -errno if denied. */ static int hook_ptrace_access_check(struct task_struct *const child, - const unsigned int mode) + const unsigned int mode) { return task_ptrace(current, child); } @@ -116,5 +116,5 @@ static struct security_hook_list landloc __init void landlock_add_ptrace_hooks(void) { security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), - LANDLOCK_NAME); + LANDLOCK_NAME); } --- a/security/landlock/ruleset.c +++ b/security/landlock/ruleset.c @@ -28,8 +28,9 @@ static struct landlock_ruleset *create_r { struct landlock_ruleset *new_ruleset;
- new_ruleset = kzalloc(struct_size(new_ruleset, fs_access_masks, - num_layers), GFP_KERNEL_ACCOUNT); + new_ruleset = + kzalloc(struct_size(new_ruleset, fs_access_masks, num_layers), + GFP_KERNEL_ACCOUNT); if (!new_ruleset) return ERR_PTR(-ENOMEM); refcount_set(&new_ruleset->usage, 1); @@ -66,11 +67,10 @@ static void build_check_rule(void) BUILD_BUG_ON(rule.num_layers < LANDLOCK_MAX_NUM_LAYERS); }
-static struct landlock_rule *create_rule( - struct landlock_object *const object, - const struct landlock_layer (*const layers)[], - const u32 num_layers, - const struct landlock_layer *const new_layer) +static struct landlock_rule * +create_rule(struct landlock_object *const object, + const struct landlock_layer (*const layers)[], const u32 num_layers, + const struct landlock_layer *const new_layer) { struct landlock_rule *new_rule; u32 new_num_layers; @@ -85,7 +85,7 @@ static struct landlock_rule *create_rule new_num_layers = num_layers; } new_rule = kzalloc(struct_size(new_rule, layers, new_num_layers), - GFP_KERNEL_ACCOUNT); + GFP_KERNEL_ACCOUNT); if (!new_rule) return ERR_PTR(-ENOMEM); RB_CLEAR_NODE(&new_rule->node); @@ -94,7 +94,7 @@ static struct landlock_rule *create_rule new_rule->num_layers = new_num_layers; /* Copies the original layer stack. */ memcpy(new_rule->layers, layers, - flex_array_size(new_rule, layers, num_layers)); + flex_array_size(new_rule, layers, num_layers)); if (new_layer) /* Adds a copy of @new_layer on the layer stack. */ new_rule->layers[new_rule->num_layers - 1] = *new_layer; @@ -142,9 +142,9 @@ static void build_check_ruleset(void) * access rights. */ static int insert_rule(struct landlock_ruleset *const ruleset, - struct landlock_object *const object, - const struct landlock_layer (*const layers)[], - size_t num_layers) + struct landlock_object *const object, + const struct landlock_layer (*const layers)[], + size_t num_layers) { struct rb_node **walker_node; struct rb_node *parent_node = NULL; @@ -156,8 +156,8 @@ static int insert_rule(struct landlock_r return -ENOENT; walker_node = &(ruleset->root.rb_node); while (*walker_node) { - struct landlock_rule *const this = rb_entry(*walker_node, - struct landlock_rule, node); + struct landlock_rule *const this = + rb_entry(*walker_node, struct landlock_rule, node);
if (this->object != object) { parent_node = *walker_node; @@ -194,7 +194,7 @@ static int insert_rule(struct landlock_r * ruleset and a domain. */ new_rule = create_rule(object, &this->layers, this->num_layers, - &(*layers)[0]); + &(*layers)[0]); if (IS_ERR(new_rule)) return PTR_ERR(new_rule); rb_replace_node(&this->node, &new_rule->node, &ruleset->root); @@ -228,13 +228,13 @@ static void build_check_layer(void)
/* @ruleset must be locked by the caller. */ int landlock_insert_rule(struct landlock_ruleset *const ruleset, - struct landlock_object *const object, const u32 access) + struct landlock_object *const object, const u32 access) { - struct landlock_layer layers[] = {{ + struct landlock_layer layers[] = { { .access = access, /* When @level is zero, insert_rule() extends @ruleset. */ .level = 0, - }}; + } };
build_check_layer(); return insert_rule(ruleset, object, &layers, ARRAY_SIZE(layers)); @@ -257,7 +257,7 @@ static void put_hierarchy(struct landloc }
static int merge_ruleset(struct landlock_ruleset *const dst, - struct landlock_ruleset *const src) + struct landlock_ruleset *const src) { struct landlock_rule *walker_rule, *next_rule; int err = 0; @@ -282,11 +282,11 @@ static int merge_ruleset(struct landlock dst->fs_access_masks[dst->num_layers - 1] = src->fs_access_masks[0];
/* Merges the @src tree. */ - rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, - &src->root, node) { - struct landlock_layer layers[] = {{ + rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, &src->root, + node) { + struct landlock_layer layers[] = { { .level = dst->num_layers, - }}; + } };
if (WARN_ON_ONCE(walker_rule->num_layers != 1)) { err = -EINVAL; @@ -298,7 +298,7 @@ static int merge_ruleset(struct landlock } layers[0].access = walker_rule->layers[0].access; err = insert_rule(dst, walker_rule->object, &layers, - ARRAY_SIZE(layers)); + ARRAY_SIZE(layers)); if (err) goto out_unlock; } @@ -310,7 +310,7 @@ out_unlock: }
static int inherit_ruleset(struct landlock_ruleset *const parent, - struct landlock_ruleset *const child) + struct landlock_ruleset *const child) { struct landlock_rule *walker_rule, *next_rule; int err = 0; @@ -325,9 +325,10 @@ static int inherit_ruleset(struct landlo
/* Copies the @parent tree. */ rbtree_postorder_for_each_entry_safe(walker_rule, next_rule, - &parent->root, node) { + &parent->root, node) { err = insert_rule(child, walker_rule->object, - &walker_rule->layers, walker_rule->num_layers); + &walker_rule->layers, + walker_rule->num_layers); if (err) goto out_unlock; } @@ -338,7 +339,7 @@ static int inherit_ruleset(struct landlo } /* Copies the parent layer stack and leaves a space for the new layer. */ memcpy(child->fs_access_masks, parent->fs_access_masks, - flex_array_size(parent, fs_access_masks, parent->num_layers)); + flex_array_size(parent, fs_access_masks, parent->num_layers));
if (WARN_ON_ONCE(!parent->hierarchy)) { err = -EINVAL; @@ -358,8 +359,7 @@ static void free_ruleset(struct landlock struct landlock_rule *freeme, *next;
might_sleep(); - rbtree_postorder_for_each_entry_safe(freeme, next, &ruleset->root, - node) + rbtree_postorder_for_each_entry_safe(freeme, next, &ruleset->root, node) free_rule(freeme); put_hierarchy(ruleset->hierarchy); kfree(ruleset); @@ -397,9 +397,9 @@ void landlock_put_ruleset_deferred(struc * Returns the intersection of @parent and @ruleset, or returns @parent if * @ruleset is empty, or returns a duplicate of @ruleset if @parent is empty. */ -struct landlock_ruleset *landlock_merge_ruleset( - struct landlock_ruleset *const parent, - struct landlock_ruleset *const ruleset) +struct landlock_ruleset * +landlock_merge_ruleset(struct landlock_ruleset *const parent, + struct landlock_ruleset *const ruleset) { struct landlock_ruleset *new_dom; u32 num_layers; @@ -421,8 +421,8 @@ struct landlock_ruleset *landlock_merge_ new_dom = create_ruleset(num_layers); if (IS_ERR(new_dom)) return new_dom; - new_dom->hierarchy = kzalloc(sizeof(*new_dom->hierarchy), - GFP_KERNEL_ACCOUNT); + new_dom->hierarchy = + kzalloc(sizeof(*new_dom->hierarchy), GFP_KERNEL_ACCOUNT); if (!new_dom->hierarchy) { err = -ENOMEM; goto out_put_dom; @@ -449,9 +449,9 @@ out_put_dom: /* * The returned access has the same lifetime as @ruleset. */ -const struct landlock_rule *landlock_find_rule( - const struct landlock_ruleset *const ruleset, - const struct landlock_object *const object) +const struct landlock_rule * +landlock_find_rule(const struct landlock_ruleset *const ruleset, + const struct landlock_object *const object) { const struct rb_node *node;
@@ -459,8 +459,8 @@ const struct landlock_rule *landlock_fin return NULL; node = ruleset->root.rb_node; while (node) { - struct landlock_rule *this = rb_entry(node, - struct landlock_rule, node); + struct landlock_rule *this = + rb_entry(node, struct landlock_rule, node);
if (this->object == object) return this; --- a/security/landlock/ruleset.h +++ b/security/landlock/ruleset.h @@ -146,15 +146,16 @@ void landlock_put_ruleset(struct landloc void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset);
int landlock_insert_rule(struct landlock_ruleset *const ruleset, - struct landlock_object *const object, const u32 access); + struct landlock_object *const object, + const u32 access);
-struct landlock_ruleset *landlock_merge_ruleset( - struct landlock_ruleset *const parent, - struct landlock_ruleset *const ruleset); +struct landlock_ruleset * +landlock_merge_ruleset(struct landlock_ruleset *const parent, + struct landlock_ruleset *const ruleset);
-const struct landlock_rule *landlock_find_rule( - const struct landlock_ruleset *const ruleset, - const struct landlock_object *const object); +const struct landlock_rule * +landlock_find_rule(const struct landlock_ruleset *const ruleset, + const struct landlock_object *const object);
static inline void landlock_get_ruleset(struct landlock_ruleset *const ruleset) { --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -43,9 +43,10 @@ * @src: User space pointer or NULL. * @usize: (Alleged) size of the data pointed to by @src. */ -static __always_inline int copy_min_struct_from_user(void *const dst, - const size_t ksize, const size_t ksize_min, - const void __user *const src, const size_t usize) +static __always_inline int +copy_min_struct_from_user(void *const dst, const size_t ksize, + const size_t ksize_min, const void __user *const src, + const size_t usize) { /* Checks buffer inconsistencies. */ BUILD_BUG_ON(!dst); @@ -93,7 +94,7 @@ static void build_check_abi(void) /* Ruleset handling */
static int fop_ruleset_release(struct inode *const inode, - struct file *const filp) + struct file *const filp) { struct landlock_ruleset *ruleset = filp->private_data;
@@ -102,15 +103,15 @@ static int fop_ruleset_release(struct in }
static ssize_t fop_dummy_read(struct file *const filp, char __user *const buf, - const size_t size, loff_t *const ppos) + const size_t size, loff_t *const ppos) { /* Dummy handler to enable FMODE_CAN_READ. */ return -EINVAL; }
static ssize_t fop_dummy_write(struct file *const filp, - const char __user *const buf, const size_t size, - loff_t *const ppos) + const char __user *const buf, const size_t size, + loff_t *const ppos) { /* Dummy handler to enable FMODE_CAN_WRITE. */ return -EINVAL; @@ -128,7 +129,7 @@ static const struct file_operations rule .write = fop_dummy_write, };
-#define LANDLOCK_ABI_VERSION 1 +#define LANDLOCK_ABI_VERSION 1
/** * sys_landlock_create_ruleset - Create a new ruleset @@ -168,22 +169,23 @@ SYSCALL_DEFINE3(landlock_create_ruleset, return -EOPNOTSUPP;
if (flags) { - if ((flags == LANDLOCK_CREATE_RULESET_VERSION) - && !attr && !size) + if ((flags == LANDLOCK_CREATE_RULESET_VERSION) && !attr && + !size) return LANDLOCK_ABI_VERSION; return -EINVAL; }
/* Copies raw user space buffer. */ err = copy_min_struct_from_user(&ruleset_attr, sizeof(ruleset_attr), - offsetofend(typeof(ruleset_attr), handled_access_fs), - attr, size); + offsetofend(typeof(ruleset_attr), + handled_access_fs), + attr, size); if (err) return err;
/* Checks content (and 32-bits cast). */ if ((ruleset_attr.handled_access_fs | LANDLOCK_MASK_ACCESS_FS) != - LANDLOCK_MASK_ACCESS_FS) + LANDLOCK_MASK_ACCESS_FS) return -EINVAL;
/* Checks arguments and transforms to kernel struct. */ @@ -193,7 +195,7 @@ SYSCALL_DEFINE3(landlock_create_ruleset,
/* Creates anonymous FD referring to the ruleset. */ ruleset_fd = anon_inode_getfd("[landlock-ruleset]", &ruleset_fops, - ruleset, O_RDWR | O_CLOEXEC); + ruleset, O_RDWR | O_CLOEXEC); if (ruleset_fd < 0) landlock_put_ruleset(ruleset); return ruleset_fd; @@ -204,7 +206,7 @@ SYSCALL_DEFINE3(landlock_create_ruleset, * landlock_put_ruleset() on the return value. */ static struct landlock_ruleset *get_ruleset_from_fd(const int fd, - const fmode_t mode) + const fmode_t mode) { struct fd ruleset_f; struct landlock_ruleset *ruleset; @@ -244,8 +246,8 @@ static int get_path_from_fd(const s32 fd struct fd f; int err = 0;
- BUILD_BUG_ON(!__same_type(fd, - ((struct landlock_path_beneath_attr *)NULL)->parent_fd)); + BUILD_BUG_ON(!__same_type( + fd, ((struct landlock_path_beneath_attr *)NULL)->parent_fd));
/* Handles O_PATH. */ f = fdget_raw(fd); @@ -257,10 +259,10 @@ static int get_path_from_fd(const s32 fd * pipefs). */ if ((f.file->f_op == &ruleset_fops) || - (f.file->f_path.mnt->mnt_flags & MNT_INTERNAL) || - (f.file->f_path.dentry->d_sb->s_flags & SB_NOUSER) || - d_is_negative(f.file->f_path.dentry) || - IS_PRIVATE(d_backing_inode(f.file->f_path.dentry))) { + (f.file->f_path.mnt->mnt_flags & MNT_INTERNAL) || + (f.file->f_path.dentry->d_sb->s_flags & SB_NOUSER) || + d_is_negative(f.file->f_path.dentry) || + IS_PRIVATE(d_backing_inode(f.file->f_path.dentry))) { err = -EBADFD; goto out_fdput; } @@ -301,8 +303,8 @@ out_fdput: * - EPERM: @ruleset_fd has no write access to the underlying ruleset; * - EFAULT: @rule_attr inconsistency. */ -SYSCALL_DEFINE4(landlock_add_rule, - const int, ruleset_fd, const enum landlock_rule_type, rule_type, +SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd, + const enum landlock_rule_type, rule_type, const void __user *const, rule_attr, const __u32, flags) { struct landlock_path_beneath_attr path_beneath_attr; @@ -322,7 +324,7 @@ SYSCALL_DEFINE4(landlock_add_rule,
/* Copies raw user space buffer, only one type for now. */ res = copy_from_user(&path_beneath_attr, rule_attr, - sizeof(path_beneath_attr)); + sizeof(path_beneath_attr)); if (res) return -EFAULT;
@@ -344,7 +346,7 @@ SYSCALL_DEFINE4(landlock_add_rule, * (ruleset->fs_access_masks[0] is automatically upgraded to 64-bits). */ if ((path_beneath_attr.allowed_access | ruleset->fs_access_masks[0]) != - ruleset->fs_access_masks[0]) { + ruleset->fs_access_masks[0]) { err = -EINVAL; goto out_put_ruleset; } @@ -356,7 +358,7 @@ SYSCALL_DEFINE4(landlock_add_rule,
/* Imports the new rule. */ err = landlock_append_fs_rule(ruleset, &path, - path_beneath_attr.allowed_access); + path_beneath_attr.allowed_access); path_put(&path);
out_put_ruleset: @@ -389,8 +391,8 @@ out_put_ruleset: * - E2BIG: The maximum number of stacked rulesets is reached for the current * thread. */ -SYSCALL_DEFINE2(landlock_restrict_self, - const int, ruleset_fd, const __u32, flags) +SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, + flags) { struct landlock_ruleset *new_dom, *ruleset; struct cred *new_cred; @@ -409,7 +411,7 @@ SYSCALL_DEFINE2(landlock_restrict_self, * returned. */ if (!task_no_new_privs(current) && - !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) + !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM;
/* Gets and checks the ruleset. */
From: Mickaël Salaün mic@digikod.net
commit 4598d9abf4215e1e371a35683350d50122793c80 upstream.
In preparation to a following commit, add clang-format on and clang-format off stanzas around constant definitions and the TEST_F_FORK macro. This enables to keep aligned values, which is much more readable than packed definitions.
Add other clang-format exceptions for FIXTURE() and FIXTURE_VARIANT_ADD() declarations to force space before open brace, which is reported by checkpatch.pl .
Link: https://lore.kernel.org/r/20220506160513.523257-4-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/common.h | 2 ++ tools/testing/selftests/landlock/fs_test.c | 23 +++++++++++++++++------ tools/testing/selftests/landlock/ptrace_test.c | 20 +++++++++++++++++++- 3 files changed, 38 insertions(+), 7 deletions(-)
--- a/tools/testing/selftests/landlock/common.h +++ b/tools/testing/selftests/landlock/common.h @@ -25,6 +25,7 @@ * this to be possible, we must not call abort() but instead exit smoothly * (hence the step print). */ +/* clang-format off */ #define TEST_F_FORK(fixture_name, test_name) \ static void fixture_name##_##test_name##_child( \ struct __test_metadata *_metadata, \ @@ -71,6 +72,7 @@ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \ const FIXTURE_VARIANT(fixture_name) \ __attribute__((unused)) *variant) +/* clang-format on */
#ifndef landlock_create_ruleset static inline int landlock_create_ruleset( --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -221,8 +221,9 @@ static void remove_layout1(struct __test EXPECT_EQ(0, remove_path(dir_s3d2)); }
-FIXTURE(layout1) { -}; +/* clang-format off */ +FIXTURE(layout1) {}; +/* clang-format on */
FIXTURE_SETUP(layout1) { @@ -376,6 +377,8 @@ TEST_F_FORK(layout1, inval) ASSERT_EQ(0, close(ruleset_fd)); }
+/* clang-format off */ + #define ACCESS_FILE ( \ LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ @@ -396,6 +399,8 @@ TEST_F_FORK(layout1, inval) LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ ACCESS_LAST)
+/* clang-format on */ + TEST_F_FORK(layout1, file_access_rights) { __u64 access; @@ -452,6 +457,8 @@ struct rule { __u64 access; };
+/* clang-format off */ + #define ACCESS_RO ( \ LANDLOCK_ACCESS_FS_READ_FILE | \ LANDLOCK_ACCESS_FS_READ_DIR) @@ -460,6 +467,8 @@ struct rule { ACCESS_RO | \ LANDLOCK_ACCESS_FS_WRITE_FILE)
+/* clang-format on */ + static int create_ruleset(struct __test_metadata *const _metadata, const __u64 handled_access_fs, const struct rule rules[]) { @@ -2070,8 +2079,9 @@ TEST_F_FORK(layout1, proc_pipe) ASSERT_EQ(0, close(pipe_fds[1])); }
-FIXTURE(layout1_bind) { -}; +/* clang-format off */ +FIXTURE(layout1_bind) {}; +/* clang-format on */
FIXTURE_SETUP(layout1_bind) { @@ -2411,8 +2421,9 @@ static const char (*merge_sub_files[])[] * └── work */
-FIXTURE(layout2_overlay) { -}; +/* clang-format off */ +FIXTURE(layout2_overlay) {}; +/* clang-format on */
FIXTURE_SETUP(layout2_overlay) { --- a/tools/testing/selftests/landlock/ptrace_test.c +++ b/tools/testing/selftests/landlock/ptrace_test.c @@ -59,7 +59,9 @@ static int test_ptrace_read(const pid_t return 0; }
-FIXTURE(hierarchy) { }; +/* clang-format off */ +FIXTURE(hierarchy) {}; +/* clang-format on */
FIXTURE_VARIANT(hierarchy) { const bool domain_both; @@ -83,7 +85,9 @@ FIXTURE_VARIANT(hierarchy) { * \ P2 -> P1 : allow * 'P2 */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, allow_without_domain) { + /* clang-format on */ .domain_both = false, .domain_parent = false, .domain_child = false, @@ -98,7 +102,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_wit * | P2 | * '------' */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, allow_with_one_domain) { + /* clang-format on */ .domain_both = false, .domain_parent = false, .domain_child = true, @@ -112,7 +118,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_wit * ' * P2 */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, deny_with_parent_domain) { + /* clang-format on */ .domain_both = false, .domain_parent = true, .domain_child = false, @@ -127,7 +135,9 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with * | P2 | * '------' */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, deny_with_sibling_domain) { + /* clang-format on */ .domain_both = false, .domain_parent = true, .domain_child = true, @@ -142,7 +152,9 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with * | P2 | * '-------------' */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, allow_sibling_domain) { + /* clang-format on */ .domain_both = true, .domain_parent = false, .domain_child = false, @@ -158,7 +170,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_sib * | '------' | * '-----------------' */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, allow_with_nested_domain) { + /* clang-format on */ .domain_both = true, .domain_parent = false, .domain_child = true, @@ -174,7 +188,9 @@ FIXTURE_VARIANT_ADD(hierarchy, allow_wit * | P2 | * '-----------------' */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, deny_with_nested_and_parent_domain) { + /* clang-format on */ .domain_both = true, .domain_parent = true, .domain_child = false, @@ -192,7 +208,9 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with * | '------' | * '-----------------' */ +/* clang-format off */ FIXTURE_VARIANT_ADD(hierarchy, deny_with_forked_domain) { + /* clang-format on */ .domain_both = true, .domain_parent = true, .domain_child = true,
From: Mickaël Salaün mic@digikod.net
commit 135464f9d29c5b306d7201220f1d00dab30fea89 upstream.
Add a comma after each array value to make clang-format keep the current array formatting. See the following commit.
Automatically modified with: sed -i 's/\t({}|NULL)$/\0,/' tools/testing/selftests/landlock/fs_test.c
Link: https://lore.kernel.org/r/20220506160513.523257-5-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/fs_test.c | 112 ++++++++++++++--------------- 1 file changed, 56 insertions(+), 56 deletions(-)
--- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -514,7 +514,7 @@ TEST_F_FORK(layout1, proc_nsfs) .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; struct landlock_path_beneath_attr path_beneath; const int ruleset_fd = create_ruleset(_metadata, rules[0].access | @@ -560,7 +560,7 @@ TEST_F_FORK(layout1, unpriv) { .path = dir_s1d2, .access = ACCESS_RO, }, - {} + {}, }; int ruleset_fd;
@@ -588,7 +588,7 @@ TEST_F_FORK(layout1, effective_access) .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules); char buf; @@ -635,7 +635,7 @@ TEST_F_FORK(layout1, unhandled_access) .path = dir_s1d2, .access = ACCESS_RO, }, - {} + {}, }; /* Here, we only handle read accesses, not write accesses. */ const int ruleset_fd = create_ruleset(_metadata, ACCESS_RO, rules); @@ -669,7 +669,7 @@ TEST_F_FORK(layout1, ruleset_overlap) .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -703,14 +703,14 @@ TEST_F_FORK(layout1, non_overlapping_acc .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_MAKE_REG, }, - {} + {}, }; const struct rule layer2[] = { { .path = dir_s1d3, .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, }, - {} + {}, }; int ruleset_fd;
@@ -767,7 +767,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = file1_s1d3, .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; /* First rule with write restrictions. */ const struct rule layer2_read_write[] = { @@ -782,7 +782,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; const struct rule layer3_read[] = { /* Allows read access via its great-grandparent directory. */ @@ -790,7 +790,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = dir_s1d1, .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; const struct rule layer4_read_write[] = { /* @@ -801,7 +801,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; const struct rule layer5_read[] = { /* @@ -812,7 +812,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; const struct rule layer6_execute[] = { /* @@ -823,7 +823,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = dir_s2d1, .access = LANDLOCK_ACCESS_FS_EXECUTE, }, - {} + {}, }; const struct rule layer7_read_write[] = { /* @@ -834,7 +834,7 @@ TEST_F_FORK(layout1, interleaved_masked_ .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; int ruleset_fd;
@@ -932,7 +932,7 @@ TEST_F_FORK(layout1, inherit_subset) .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1048,7 +1048,7 @@ TEST_F_FORK(layout1, inherit_superset) .path = dir_s1d3, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1084,7 +1084,7 @@ TEST_F_FORK(layout1, max_layers) .path = dir_s1d2, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1146,7 +1146,7 @@ TEST_F_FORK(layout1, rule_on_mountpoint) .path = dir_s3d2, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1175,7 +1175,7 @@ TEST_F_FORK(layout1, rule_over_mountpoin .path = dir_s3d1, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1203,7 +1203,7 @@ TEST_F_FORK(layout1, rule_over_root_allo .path = "/", .access = ACCESS_RO, }, - {} + {}, }; int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1233,7 +1233,7 @@ TEST_F_FORK(layout1, rule_over_root_deny .path = "/", .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1253,7 +1253,7 @@ TEST_F_FORK(layout1, rule_inside_mount_n .path = "s3d3", .access = ACCESS_RO, }, - {} + {}, }; int ruleset_fd;
@@ -1280,7 +1280,7 @@ TEST_F_FORK(layout1, mount_and_pivot) .path = dir_s3d2, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1303,7 +1303,7 @@ TEST_F_FORK(layout1, move_mount) .path = dir_s3d2, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1344,7 +1344,7 @@ TEST_F_FORK(layout1, release_inodes) .path = dir_s3d3, .access = ACCESS_RO, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
@@ -1382,7 +1382,7 @@ static void test_relative_path(struct __ .path = TMP_DIR, .access = ACCESS_RO, }, - {} + {}, }; const struct rule layer2_subs[] = { { @@ -1393,7 +1393,7 @@ static void test_relative_path(struct __ .path = dir_s2d2, .access = ACCESS_RO, }, - {} + {}, }; int dirfd, ruleset_fd;
@@ -1558,7 +1558,7 @@ TEST_F_FORK(layout1, execute) .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_EXECUTE, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1591,7 +1591,7 @@ TEST_F_FORK(layout1, link) .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_MAKE_REG, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1628,7 +1628,7 @@ TEST_F_FORK(layout1, rename_file) .path = dir_s2d2, .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1705,7 +1705,7 @@ TEST_F_FORK(layout1, rename_dir) .path = dir_s2d1, .access = LANDLOCK_ACCESS_FS_REMOVE_DIR, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1759,7 +1759,7 @@ TEST_F_FORK(layout1, remove_dir) .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_REMOVE_DIR, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1796,7 +1796,7 @@ TEST_F_FORK(layout1, remove_file) .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1821,7 +1821,7 @@ static void test_make_file(struct __test .path = dir_s1d2, .access = access, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, access, rules);
@@ -1907,7 +1907,7 @@ TEST_F_FORK(layout1, make_sym) .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_MAKE_SYM, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1952,7 +1952,7 @@ TEST_F_FORK(layout1, make_dir) .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_MAKE_DIR, }, - {} + {}, }; const int ruleset_fd = create_ruleset(_metadata, rules[0].access, rules); @@ -1992,7 +1992,7 @@ TEST_F_FORK(layout1, proc_unlinked_file) .path = file1_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; int reg_fd, proc_fd; const int ruleset_fd = create_ruleset(_metadata, @@ -2034,7 +2034,7 @@ TEST_F_FORK(layout1, proc_pipe) .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; /* Limits read and write access to files tied to the filesystem. */ const int ruleset_fd = create_ruleset(_metadata, rules[0].access, @@ -2171,7 +2171,7 @@ TEST_F_FORK(layout1_bind, same_content_s .path = dir_s2d1, .access = ACCESS_RW, }, - {} + {}, }; /* * Sets access rights on the same bind-mounted directories. The result @@ -2187,7 +2187,7 @@ TEST_F_FORK(layout1_bind, same_content_s .path = dir_s2d2, .access = ACCESS_RW, }, - {} + {}, }; /* Only allow read-access to the s1d3 hierarchies. */ const struct rule layer3_source[] = { @@ -2195,7 +2195,7 @@ TEST_F_FORK(layout1_bind, same_content_s .path = dir_s1d3, .access = LANDLOCK_ACCESS_FS_READ_FILE, }, - {} + {}, }; /* Removes all access rights. */ const struct rule layer4_destination[] = { @@ -2203,7 +2203,7 @@ TEST_F_FORK(layout1_bind, same_content_s .path = bind_file1_s1d3, .access = LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; int ruleset_fd;
@@ -2305,18 +2305,18 @@ static const char lower_do1_fl3[] = LOWE static const char (*lower_base_files[])[] = { &lower_fl1, &lower_fo1, - NULL + NULL, }; static const char (*lower_base_directories[])[] = { &lower_dl1, &lower_do1, - NULL + NULL, }; static const char (*lower_sub_files[])[] = { &lower_dl1_fl2, &lower_do1_fo2, &lower_do1_fl3, - NULL + NULL, };
#define UPPER_BASE TMP_DIR "/upper" @@ -2333,18 +2333,18 @@ static const char upper_do1_fu3[] = UPPE static const char (*upper_base_files[])[] = { &upper_fu1, &upper_fo1, - NULL + NULL, }; static const char (*upper_base_directories[])[] = { &upper_du1, &upper_do1, - NULL + NULL, }; static const char (*upper_sub_files[])[] = { &upper_du1_fu2, &upper_do1_fo2, &upper_do1_fu3, - NULL + NULL, };
#define MERGE_BASE TMP_DIR "/merge" @@ -2365,13 +2365,13 @@ static const char (*merge_base_files[])[ &merge_fl1, &merge_fu1, &merge_fo1, - NULL + NULL, }; static const char (*merge_base_directories[])[] = { &merge_dl1, &merge_du1, &merge_do1, - NULL + NULL, }; static const char (*merge_sub_files[])[] = { &merge_dl1_fl2, @@ -2379,7 +2379,7 @@ static const char (*merge_sub_files[])[] &merge_do1_fo2, &merge_do1_fl3, &merge_do1_fu3, - NULL + NULL, };
/* @@ -2544,7 +2544,7 @@ TEST_F_FORK(layout2_overlay, same_conten .path = MERGE_BASE, .access = ACCESS_RW, }, - {} + {}, }; const struct rule layer2_data[] = { { @@ -2559,7 +2559,7 @@ TEST_F_FORK(layout2_overlay, same_conten .path = MERGE_DATA, .access = ACCESS_RW, }, - {} + {}, }; /* Sets access right on directories inside both layers. */ const struct rule layer3_subdirs[] = { @@ -2591,7 +2591,7 @@ TEST_F_FORK(layout2_overlay, same_conten .path = merge_do1, .access = ACCESS_RW, }, - {} + {}, }; /* Tighten access rights to the files. */ const struct rule layer4_files[] = { @@ -2644,7 +2644,7 @@ TEST_F_FORK(layout2_overlay, same_conten .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; const struct rule layer5_merge_only[] = { { @@ -2652,7 +2652,7 @@ TEST_F_FORK(layout2_overlay, same_conten .access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, }, - {} + {}, }; int ruleset_fd; size_t i;
From: Mickaël Salaün mic@digikod.net
commit 371183fa578a4cf56b3ae12e54b7f01a4249add1 upstream.
Let's follow a consistent and documented coding style. Everything may not be to our liking but it is better than tacit knowledge. Moreover, this will help maintain style consistency between different developers.
This contains only whitespace changes.
Automatically formatted with: clang-format-14 -i tools/testing/selftests/landlock/*.[ch]
Link: https://lore.kernel.org/r/20220506160513.523257-6-mic@digikod.net Cc: stable@vger.kernel.org [mic: Update style according to https://lore.kernel.org/r/02494cb8-2aa5-1769-f28d-d7206f284e5a@digikod.net] Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/base_test.c | 80 ++--- tools/testing/selftests/landlock/common.h | 64 ++-- tools/testing/selftests/landlock/fs_test.c | 399 +++++++++++++------------ tools/testing/selftests/landlock/ptrace_test.c | 20 - 4 files changed, 312 insertions(+), 251 deletions(-)
--- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -18,10 +18,11 @@ #include "common.h"
#ifndef O_PATH -#define O_PATH 010000000 +#define O_PATH 010000000 #endif
-TEST(inconsistent_attr) { +TEST(inconsistent_attr) +{ const long page_size = sysconf(_SC_PAGESIZE); char *const buf = malloc(page_size + 1); struct landlock_ruleset_attr *const ruleset_attr = (void *)buf; @@ -39,15 +40,16 @@ TEST(inconsistent_attr) { /* The size if less than sizeof(struct landlock_attr_enforce). */ ASSERT_EQ(EFAULT, errno);
- ASSERT_EQ(-1, landlock_create_ruleset(NULL, - sizeof(struct landlock_ruleset_attr), 0)); + ASSERT_EQ(-1, landlock_create_ruleset( + NULL, sizeof(struct landlock_ruleset_attr), 0)); ASSERT_EQ(EFAULT, errno);
ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0)); ASSERT_EQ(E2BIG, errno);
- ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, - sizeof(struct landlock_ruleset_attr), 0)); + ASSERT_EQ(-1, landlock_create_ruleset( + ruleset_attr, + sizeof(struct landlock_ruleset_attr), 0)); ASSERT_EQ(ENOMSG, errno); ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size, 0)); ASSERT_EQ(ENOMSG, errno); @@ -63,32 +65,35 @@ TEST(inconsistent_attr) { free(buf); }
-TEST(abi_version) { +TEST(abi_version) +{ const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, }; ASSERT_EQ(1, landlock_create_ruleset(NULL, 0, - LANDLOCK_CREATE_RULESET_VERSION)); + LANDLOCK_CREATE_RULESET_VERSION));
ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, - LANDLOCK_CREATE_RULESET_VERSION)); + LANDLOCK_CREATE_RULESET_VERSION)); ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), - LANDLOCK_CREATE_RULESET_VERSION)); + LANDLOCK_CREATE_RULESET_VERSION)); ASSERT_EQ(EINVAL, errno);
- ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), - LANDLOCK_CREATE_RULESET_VERSION)); + ASSERT_EQ(-1, + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), + LANDLOCK_CREATE_RULESET_VERSION)); ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, - LANDLOCK_CREATE_RULESET_VERSION | 1 << 31)); + LANDLOCK_CREATE_RULESET_VERSION | + 1 << 31)); ASSERT_EQ(EINVAL, errno); }
-TEST(inval_create_ruleset_flags) { +TEST(inval_create_ruleset_flags) +{ const int last_flag = LANDLOCK_CREATE_RULESET_VERSION; const int invalid_flag = last_flag << 1; const struct landlock_ruleset_attr ruleset_attr = { @@ -102,38 +107,42 @@ TEST(inval_create_ruleset_flags) { ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), - invalid_flag)); + invalid_flag)); ASSERT_EQ(EINVAL, errno);
- ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), invalid_flag)); + ASSERT_EQ(-1, + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), + invalid_flag)); ASSERT_EQ(EINVAL, errno); }
-TEST(empty_path_beneath_attr) { +TEST(empty_path_beneath_attr) +{ const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, }; - const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + const int ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
ASSERT_LE(0, ruleset_fd);
/* Similar to struct landlock_path_beneath_attr.parent_fd = 0 */ ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - NULL, 0)); + NULL, 0)); ASSERT_EQ(EFAULT, errno); ASSERT_EQ(0, close(ruleset_fd)); }
-TEST(inval_fd_enforce) { +TEST(inval_fd_enforce) +{ ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); ASSERT_EQ(EBADF, errno); }
-TEST(unpriv_enforce_without_no_new_privs) { +TEST(unpriv_enforce_without_no_new_privs) +{ int err;
drop_caps(_metadata); @@ -151,8 +160,8 @@ TEST(ruleset_fd_io) char buf;
drop_caps(_metadata); - ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd);
ASSERT_EQ(-1, write(ruleset_fd, ".", 1)); @@ -197,14 +206,15 @@ TEST(ruleset_fd_transfer) drop_caps(_metadata);
/* Creates a test ruleset with a simple rule. */ - ruleset_fd_tx = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + ruleset_fd_tx = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd_tx); - path_beneath_attr.parent_fd = open("/tmp", O_PATH | O_NOFOLLOW | - O_DIRECTORY | O_CLOEXEC); + path_beneath_attr.parent_fd = + open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); ASSERT_LE(0, path_beneath_attr.parent_fd); - ASSERT_EQ(0, landlock_add_rule(ruleset_fd_tx, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath_attr, 0)); + ASSERT_EQ(0, + landlock_add_rule(ruleset_fd_tx, LANDLOCK_RULE_PATH_BENEATH, + &path_beneath_attr, 0)); ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
cmsg = CMSG_FIRSTHDR(&msg); @@ -215,7 +225,8 @@ TEST(ruleset_fd_transfer) memcpy(CMSG_DATA(cmsg), &ruleset_fd_tx, sizeof(ruleset_fd_tx));
/* Sends the ruleset FD over a socketpair and then close it. */ - ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, socket_fds)); + ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, + socket_fds)); ASSERT_EQ(sizeof(data_tx), sendmsg(socket_fds[0], &msg, 0)); ASSERT_EQ(0, close(socket_fds[0])); ASSERT_EQ(0, close(ruleset_fd_tx)); @@ -226,7 +237,8 @@ TEST(ruleset_fd_transfer) int ruleset_fd_rx;
*(char *)msg.msg_iov->iov_base = '\0'; - ASSERT_EQ(sizeof(data_tx), recvmsg(socket_fds[1], &msg, MSG_CMSG_CLOEXEC)); + ASSERT_EQ(sizeof(data_tx), + recvmsg(socket_fds[1], &msg, MSG_CMSG_CLOEXEC)); ASSERT_EQ('.', *(char *)msg.msg_iov->iov_base); ASSERT_EQ(0, close(socket_fds[1])); cmsg = CMSG_FIRSTHDR(&msg); --- a/tools/testing/selftests/landlock/common.h +++ b/tools/testing/selftests/landlock/common.h @@ -75,9 +75,9 @@ /* clang-format on */
#ifndef landlock_create_ruleset -static inline int landlock_create_ruleset( - const struct landlock_ruleset_attr *const attr, - const size_t size, const __u32 flags) +static inline int +landlock_create_ruleset(const struct landlock_ruleset_attr *const attr, + const size_t size, const __u32 flags) { return syscall(__NR_landlock_create_ruleset, attr, size, flags); } @@ -85,17 +85,18 @@ static inline int landlock_create_rulese
#ifndef landlock_add_rule static inline int landlock_add_rule(const int ruleset_fd, - const enum landlock_rule_type rule_type, - const void *const rule_attr, const __u32 flags) + const enum landlock_rule_type rule_type, + const void *const rule_attr, + const __u32 flags) { - return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, - rule_attr, flags); + return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr, + flags); } #endif
#ifndef landlock_restrict_self static inline int landlock_restrict_self(const int ruleset_fd, - const __u32 flags) + const __u32 flags) { return syscall(__NR_landlock_restrict_self, ruleset_fd, flags); } @@ -113,69 +114,76 @@ static void _init_caps(struct __test_met };
cap_p = cap_get_proc(); - EXPECT_NE(NULL, cap_p) { + EXPECT_NE(NULL, cap_p) + { TH_LOG("Failed to cap_get_proc: %s", strerror(errno)); } - EXPECT_NE(-1, cap_clear(cap_p)) { + EXPECT_NE(-1, cap_clear(cap_p)) + { TH_LOG("Failed to cap_clear: %s", strerror(errno)); } if (!drop_all) { EXPECT_NE(-1, cap_set_flag(cap_p, CAP_PERMITTED, - ARRAY_SIZE(caps), caps, CAP_SET)) { + ARRAY_SIZE(caps), caps, CAP_SET)) + { TH_LOG("Failed to cap_set_flag: %s", strerror(errno)); } } - EXPECT_NE(-1, cap_set_proc(cap_p)) { + EXPECT_NE(-1, cap_set_proc(cap_p)) + { TH_LOG("Failed to cap_set_proc: %s", strerror(errno)); } - EXPECT_NE(-1, cap_free(cap_p)) { + EXPECT_NE(-1, cap_free(cap_p)) + { TH_LOG("Failed to cap_free: %s", strerror(errno)); } }
/* We cannot put such helpers in a library because of kselftest_harness.h . */ -__attribute__((__unused__)) -static void disable_caps(struct __test_metadata *const _metadata) +__attribute__((__unused__)) static void +disable_caps(struct __test_metadata *const _metadata) { _init_caps(_metadata, false); }
-__attribute__((__unused__)) -static void drop_caps(struct __test_metadata *const _metadata) +__attribute__((__unused__)) static void +drop_caps(struct __test_metadata *const _metadata) { _init_caps(_metadata, true); }
static void _effective_cap(struct __test_metadata *const _metadata, - const cap_value_t caps, const cap_flag_value_t value) + const cap_value_t caps, const cap_flag_value_t value) { cap_t cap_p;
cap_p = cap_get_proc(); - EXPECT_NE(NULL, cap_p) { + EXPECT_NE(NULL, cap_p) + { TH_LOG("Failed to cap_get_proc: %s", strerror(errno)); } - EXPECT_NE(-1, cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &caps, value)) { + EXPECT_NE(-1, cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &caps, value)) + { TH_LOG("Failed to cap_set_flag: %s", strerror(errno)); } - EXPECT_NE(-1, cap_set_proc(cap_p)) { + EXPECT_NE(-1, cap_set_proc(cap_p)) + { TH_LOG("Failed to cap_set_proc: %s", strerror(errno)); } - EXPECT_NE(-1, cap_free(cap_p)) { + EXPECT_NE(-1, cap_free(cap_p)) + { TH_LOG("Failed to cap_free: %s", strerror(errno)); } }
-__attribute__((__unused__)) -static void set_cap(struct __test_metadata *const _metadata, - const cap_value_t caps) +__attribute__((__unused__)) static void +set_cap(struct __test_metadata *const _metadata, const cap_value_t caps) { _effective_cap(_metadata, caps, CAP_SET); }
-__attribute__((__unused__)) -static void clear_cap(struct __test_metadata *const _metadata, - const cap_value_t caps) +__attribute__((__unused__)) static void +clear_cap(struct __test_metadata *const _metadata, const cap_value_t caps) { _effective_cap(_metadata, caps, CAP_CLEAR); } --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -22,8 +22,8 @@
#include "common.h"
-#define TMP_DIR "tmp" -#define BINARY_PATH "./true" +#define TMP_DIR "tmp" +#define BINARY_PATH "./true"
/* Paths (sibling number and depth) */ static const char dir_s1d1[] = TMP_DIR "/s1d1"; @@ -75,7 +75,7 @@ static const char dir_s3d3[] = TMP_DIR " */
static void mkdir_parents(struct __test_metadata *const _metadata, - const char *const path) + const char *const path) { char *walker; const char *parent; @@ -90,9 +90,10 @@ static void mkdir_parents(struct __test_ continue; walker[i] = '\0'; err = mkdir(parent, 0700); - ASSERT_FALSE(err && errno != EEXIST) { - TH_LOG("Failed to create directory "%s": %s", - parent, strerror(errno)); + ASSERT_FALSE(err && errno != EEXIST) + { + TH_LOG("Failed to create directory "%s": %s", parent, + strerror(errno)); } walker[i] = '/'; } @@ -100,22 +101,24 @@ static void mkdir_parents(struct __test_ }
static void create_directory(struct __test_metadata *const _metadata, - const char *const path) + const char *const path) { mkdir_parents(_metadata, path); - ASSERT_EQ(0, mkdir(path, 0700)) { + ASSERT_EQ(0, mkdir(path, 0700)) + { TH_LOG("Failed to create directory "%s": %s", path, - strerror(errno)); + strerror(errno)); } }
static void create_file(struct __test_metadata *const _metadata, - const char *const path) + const char *const path) { mkdir_parents(_metadata, path); - ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0)) { + ASSERT_EQ(0, mknod(path, S_IFREG | 0700, 0)) + { TH_LOG("Failed to create file "%s": %s", path, - strerror(errno)); + strerror(errno)); } }
@@ -243,7 +246,8 @@ FIXTURE_TEARDOWN(layout1) * This helper enables to use the ASSERT_* macros and print the line number * pointing to the test caller. */ -static int test_open_rel(const int dirfd, const char *const path, const int flags) +static int test_open_rel(const int dirfd, const char *const path, + const int flags) { int fd;
@@ -292,23 +296,23 @@ TEST_F_FORK(layout1, inval) { struct landlock_path_beneath_attr path_beneath = { .allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, .parent_fd = -1, }; struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }; int ruleset_fd;
- path_beneath.parent_fd = open(dir_s1d2, O_PATH | O_DIRECTORY | - O_CLOEXEC); + path_beneath.parent_fd = + open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC); ASSERT_LE(0, path_beneath.parent_fd);
ruleset_fd = open(dir_s1d1, O_PATH | O_DIRECTORY | O_CLOEXEC); ASSERT_LE(0, ruleset_fd); ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); /* Returns EBADF because ruleset_fd is not a landlock-ruleset FD. */ ASSERT_EQ(EBADF, errno); ASSERT_EQ(0, close(ruleset_fd)); @@ -316,55 +320,55 @@ TEST_F_FORK(layout1, inval) ruleset_fd = open(dir_s1d1, O_DIRECTORY | O_CLOEXEC); ASSERT_LE(0, ruleset_fd); ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); /* Returns EBADFD because ruleset_fd is not a valid ruleset. */ ASSERT_EQ(EBADFD, errno); ASSERT_EQ(0, close(ruleset_fd));
/* Gets a real ruleset. */ - ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd); ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(0, close(path_beneath.parent_fd));
/* Tests without O_PATH. */ path_beneath.parent_fd = open(dir_s1d2, O_DIRECTORY | O_CLOEXEC); ASSERT_LE(0, path_beneath.parent_fd); ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(0, close(path_beneath.parent_fd));
/* Tests with a ruleset FD. */ path_beneath.parent_fd = ruleset_fd; ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(EBADFD, errno);
/* Checks unhandled allowed_access. */ - path_beneath.parent_fd = open(dir_s1d2, O_PATH | O_DIRECTORY | - O_CLOEXEC); + path_beneath.parent_fd = + open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC); ASSERT_LE(0, path_beneath.parent_fd);
/* Test with legitimate values. */ path_beneath.allowed_access |= LANDLOCK_ACCESS_FS_EXECUTE; ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(EINVAL, errno); path_beneath.allowed_access &= ~LANDLOCK_ACCESS_FS_EXECUTE;
/* Test with unknown (64-bits) value. */ path_beneath.allowed_access |= (1ULL << 60); ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(EINVAL, errno); path_beneath.allowed_access &= ~(1ULL << 60);
/* Test with no access. */ path_beneath.allowed_access = 0; ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(ENOMSG, errno); path_beneath.allowed_access &= ~(1ULL << 60);
@@ -409,8 +413,8 @@ TEST_F_FORK(layout1, file_access_rights) struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = ACCESS_ALL, }; - const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + const int ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
ASSERT_LE(0, ruleset_fd);
@@ -420,7 +424,7 @@ TEST_F_FORK(layout1, file_access_rights) for (access = 1; access <= ACCESS_LAST; access <<= 1) { path_beneath.allowed_access = access; err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0); + &path_beneath, 0); if ((access | ACCESS_FILE) == ACCESS_FILE) { ASSERT_EQ(0, err); } else { @@ -432,22 +436,24 @@ TEST_F_FORK(layout1, file_access_rights) }
static void add_path_beneath(struct __test_metadata *const _metadata, - const int ruleset_fd, const __u64 allowed_access, - const char *const path) + const int ruleset_fd, const __u64 allowed_access, + const char *const path) { struct landlock_path_beneath_attr path_beneath = { .allowed_access = allowed_access, };
path_beneath.parent_fd = open(path, O_PATH | O_CLOEXEC); - ASSERT_LE(0, path_beneath.parent_fd) { + ASSERT_LE(0, path_beneath.parent_fd) + { TH_LOG("Failed to open directory "%s": %s", path, - strerror(errno)); + strerror(errno)); } ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)) { + &path_beneath, 0)) + { TH_LOG("Failed to update the ruleset with "%s": %s", path, - strerror(errno)); + strerror(errno)); } ASSERT_EQ(0, close(path_beneath.parent_fd)); } @@ -470,38 +476,43 @@ struct rule { /* clang-format on */
static int create_ruleset(struct __test_metadata *const _metadata, - const __u64 handled_access_fs, const struct rule rules[]) + const __u64 handled_access_fs, + const struct rule rules[]) { int ruleset_fd, i; struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = handled_access_fs, };
- ASSERT_NE(NULL, rules) { + ASSERT_NE(NULL, rules) + { TH_LOG("No rule list"); } - ASSERT_NE(NULL, rules[0].path) { + ASSERT_NE(NULL, rules[0].path) + { TH_LOG("Empty rule list"); }
- ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); - ASSERT_LE(0, ruleset_fd) { + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd) + { TH_LOG("Failed to create a ruleset: %s", strerror(errno)); }
for (i = 0; rules[i].path; i++) { add_path_beneath(_metadata, ruleset_fd, rules[i].access, - rules[i].path); + rules[i].path); } return ruleset_fd; }
static void enforce_ruleset(struct __test_metadata *const _metadata, - const int ruleset_fd) + const int ruleset_fd) { ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); - ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)) { + ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)) + { TH_LOG("Failed to enforce ruleset: %s", strerror(errno)); } } @@ -512,13 +523,14 @@ TEST_F_FORK(layout1, proc_nsfs) { .path = "/dev/null", .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, {}, }; struct landlock_path_beneath_attr path_beneath; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access | - LANDLOCK_ACCESS_FS_READ_DIR, rules); + const int ruleset_fd = create_ruleset( + _metadata, rules[0].access | LANDLOCK_ACCESS_FS_READ_DIR, + rules);
ASSERT_LE(0, ruleset_fd); ASSERT_EQ(0, test_open("/proc/self/ns/mnt", O_RDONLY)); @@ -545,16 +557,17 @@ TEST_F_FORK(layout1, proc_nsfs) * references to a ruleset. */ path_beneath.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, path_beneath.parent_fd = open("/proc/self/ns/mnt", O_PATH | O_CLOEXEC); ASSERT_LE(0, path_beneath.parent_fd); ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)); + &path_beneath, 0)); ASSERT_EQ(EBADFD, errno); ASSERT_EQ(0, close(path_beneath.parent_fd)); }
-TEST_F_FORK(layout1, unpriv) { +TEST_F_FORK(layout1, unpriv) +{ const struct rule rules[] = { { .path = dir_s1d2, @@ -586,7 +599,7 @@ TEST_F_FORK(layout1, effective_access) { .path = file1_s2d2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, {}, }; @@ -662,12 +675,12 @@ TEST_F_FORK(layout1, ruleset_overlap) { .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, { .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_READ_DIR, + LANDLOCK_ACCESS_FS_READ_DIR, }, {}, }; @@ -717,8 +730,8 @@ TEST_F_FORK(layout1, non_overlapping_acc ASSERT_EQ(0, unlink(file1_s1d1)); ASSERT_EQ(0, unlink(file1_s1d2));
- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, - layer1); + ruleset_fd = + create_ruleset(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, layer1); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -729,7 +742,7 @@ TEST_F_FORK(layout1, non_overlapping_acc ASSERT_EQ(0, unlink(file1_s1d2));
ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_REMOVE_FILE, - layer2); + layer2); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -775,7 +788,7 @@ TEST_F_FORK(layout1, interleaved_masked_ { .path = dir_s1d3, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, /* ...but also denies read access via its grandparent directory. */ { @@ -839,7 +852,7 @@ TEST_F_FORK(layout1, interleaved_masked_ int ruleset_fd;
ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, - layer1_read); + layer1_read); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -849,8 +862,10 @@ TEST_F_FORK(layout1, interleaved_masked_ ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY)); ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, layer2_read_write); + ruleset_fd = create_ruleset(_metadata, + LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + layer2_read_write); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -861,7 +876,7 @@ TEST_F_FORK(layout1, interleaved_masked_ ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, - layer3_read); + layer3_read); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -872,8 +887,10 @@ TEST_F_FORK(layout1, interleaved_masked_ ASSERT_EQ(0, test_open(file2_s1d3, O_WRONLY));
/* This time, denies write access for the file hierarchy. */ - ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, layer4_read_write); + ruleset_fd = create_ruleset(_metadata, + LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + layer4_read_write); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -888,7 +905,7 @@ TEST_F_FORK(layout1, interleaved_masked_ ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY));
ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE, - layer5_read); + layer5_read); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -900,7 +917,7 @@ TEST_F_FORK(layout1, interleaved_masked_ ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_EXECUTE, - layer6_execute); + layer6_execute); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -911,8 +928,10 @@ TEST_F_FORK(layout1, interleaved_masked_ ASSERT_EQ(EACCES, test_open(file2_s1d3, O_WRONLY)); ASSERT_EQ(EACCES, test_open(file2_s1d3, O_RDONLY));
- ruleset_fd = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, layer7_read_write); + ruleset_fd = create_ruleset(_metadata, + LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + layer7_read_write); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd)); @@ -930,7 +949,7 @@ TEST_F_FORK(layout1, inherit_subset) { .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_READ_DIR, + LANDLOCK_ACCESS_FS_READ_DIR, }, {}, }; @@ -958,7 +977,7 @@ TEST_F_FORK(layout1, inherit_subset) * ANDed with the previous ones. */ add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE, - dir_s1d2); + dir_s1d2); /* * According to ruleset_fd, dir_s1d2 should now have the * LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE @@ -1013,7 +1032,7 @@ TEST_F_FORK(layout1, inherit_subset) * that there was no rule tied to it before. */ add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_WRITE_FILE, - dir_s1d3); + dir_s1d3); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd));
@@ -1063,8 +1082,10 @@ TEST_F_FORK(layout1, inherit_superset) ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
/* Now dir_s1d2, parent of dir_s1d3, gets a new rule tied to it. */ - add_path_beneath(_metadata, ruleset_fd, LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_READ_DIR, dir_s1d2); + add_path_beneath(_metadata, ruleset_fd, + LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_READ_DIR, + dir_s1d2); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd));
@@ -1106,15 +1127,15 @@ TEST_F_FORK(layout1, empty_or_same_rules int ruleset_fd;
/* Tests empty handled_access_fs. */ - ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(-1, ruleset_fd); ASSERT_EQ(ENOMSG, errno);
/* Enforces policy which deny read access to all files. */ ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE; - ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); @@ -1122,8 +1143,8 @@ TEST_F_FORK(layout1, empty_or_same_rules
/* Nests a policy which deny read access to all directories. */ ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR; - ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); @@ -1258,7 +1279,8 @@ TEST_F_FORK(layout1, rule_inside_mount_n int ruleset_fd;
set_cap(_metadata, CAP_SYS_ADMIN); - ASSERT_EQ(0, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3)) { + ASSERT_EQ(0, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3)) + { TH_LOG("Failed to pivot root: %s", strerror(errno)); }; ASSERT_EQ(0, chdir("/")); @@ -1311,12 +1333,13 @@ TEST_F_FORK(layout1, move_mount)
set_cap(_metadata, CAP_SYS_ADMIN); ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, - dir_s1d2, 0)) { + dir_s1d2, 0)) + { TH_LOG("Failed to move mount: %s", strerror(errno)); }
ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD, - dir_s3d2, 0)); + dir_s3d2, 0)); clear_cap(_metadata, CAP_SYS_ADMIN);
enforce_ruleset(_metadata, ruleset_fd); @@ -1324,7 +1347,7 @@ TEST_F_FORK(layout1, move_mount)
set_cap(_metadata, CAP_SYS_ADMIN); ASSERT_EQ(-1, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, - dir_s1d2, 0)); + dir_s1d2, 0)); ASSERT_EQ(EPERM, errno); clear_cap(_metadata, CAP_SYS_ADMIN); } @@ -1371,7 +1394,7 @@ enum relative_access { };
static void test_relative_path(struct __test_metadata *const _metadata, - const enum relative_access rel) + const enum relative_access rel) { /* * Common layer to check that chroot doesn't ignore it (i.e. a chroot @@ -1434,14 +1457,16 @@ static void test_relative_path(struct __ break; case REL_CHROOT_ONLY: /* Do chroot into dir_s1d2 (relative to dir_s2d2). */ - ASSERT_EQ(0, chroot("../../s1d1/s1d2")) { + ASSERT_EQ(0, chroot("../../s1d1/s1d2")) + { TH_LOG("Failed to chroot: %s", strerror(errno)); } dirfd = AT_FDCWD; break; case REL_CHROOT_CHDIR: /* Do chroot into dir_s1d2. */ - ASSERT_EQ(0, chroot(".")) { + ASSERT_EQ(0, chroot(".")) + { TH_LOG("Failed to chroot: %s", strerror(errno)); } dirfd = AT_FDCWD; @@ -1449,7 +1474,7 @@ static void test_relative_path(struct __ }
ASSERT_EQ((rel == REL_CHROOT_CHDIR) ? 0 : EACCES, - test_open_rel(dirfd, "..", O_RDONLY)); + test_open_rel(dirfd, "..", O_RDONLY)); ASSERT_EQ(0, test_open_rel(dirfd, ".", O_RDONLY));
if (rel == REL_CHROOT_ONLY) { @@ -1471,11 +1496,13 @@ static void test_relative_path(struct __ if (rel != REL_CHROOT_CHDIR) { ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s1d1", O_RDONLY)); ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2", O_RDONLY)); - ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3", O_RDONLY)); + ASSERT_EQ(0, test_open_rel(dirfd, "../../s1d1/s1d2/s1d3", + O_RDONLY));
ASSERT_EQ(EACCES, test_open_rel(dirfd, "../../s2d1", O_RDONLY)); ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2", O_RDONLY)); - ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3", O_RDONLY)); + ASSERT_EQ(0, test_open_rel(dirfd, "../../s2d1/s2d2/s2d3", + O_RDONLY)); }
if (rel == REL_OPEN) @@ -1504,40 +1531,42 @@ TEST_F_FORK(layout1, relative_chroot_chd }
static void copy_binary(struct __test_metadata *const _metadata, - const char *const dst_path) + const char *const dst_path) { int dst_fd, src_fd; struct stat statbuf;
dst_fd = open(dst_path, O_WRONLY | O_TRUNC | O_CLOEXEC); - ASSERT_LE(0, dst_fd) { - TH_LOG("Failed to open "%s": %s", dst_path, - strerror(errno)); + ASSERT_LE(0, dst_fd) + { + TH_LOG("Failed to open "%s": %s", dst_path, strerror(errno)); } src_fd = open(BINARY_PATH, O_RDONLY | O_CLOEXEC); - ASSERT_LE(0, src_fd) { + ASSERT_LE(0, src_fd) + { TH_LOG("Failed to open "" BINARY_PATH "": %s", - strerror(errno)); + strerror(errno)); } ASSERT_EQ(0, fstat(src_fd, &statbuf)); - ASSERT_EQ(statbuf.st_size, sendfile(dst_fd, src_fd, 0, - statbuf.st_size)); + ASSERT_EQ(statbuf.st_size, + sendfile(dst_fd, src_fd, 0, statbuf.st_size)); ASSERT_EQ(0, close(src_fd)); ASSERT_EQ(0, close(dst_fd)); }
-static void test_execute(struct __test_metadata *const _metadata, - const int err, const char *const path) +static void test_execute(struct __test_metadata *const _metadata, const int err, + const char *const path) { int status; - char *const argv[] = {(char *)path, NULL}; + char *const argv[] = { (char *)path, NULL }; const pid_t child = fork();
ASSERT_LE(0, child); if (child == 0) { - ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL)) { + ASSERT_EQ(err ? -1 : 0, execve(path, argv, NULL)) + { TH_LOG("Failed to execute "%s": %s", path, - strerror(errno)); + strerror(errno)); }; ASSERT_EQ(err, errno); _exit(_metadata->passed ? 2 : 1); @@ -1545,9 +1574,10 @@ static void test_execute(struct __test_m } ASSERT_EQ(child, waitpid(child, &status, 0)); ASSERT_EQ(1, WIFEXITED(status)); - ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status)) { + ASSERT_EQ(err ? 2 : 0, WEXITSTATUS(status)) + { TH_LOG("Unexpected return code for "%s": %s", path, - strerror(errno)); + strerror(errno)); }; }
@@ -1560,8 +1590,8 @@ TEST_F_FORK(layout1, execute) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd); copy_binary(_metadata, file1_s1d1); @@ -1593,8 +1623,8 @@ TEST_F_FORK(layout1, link) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd);
@@ -1630,8 +1660,8 @@ TEST_F_FORK(layout1, rename_file) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd);
@@ -1684,14 +1714,14 @@ TEST_F_FORK(layout1, rename_file)
/* Exchanges and renames files with same parent. */ ASSERT_EQ(0, renameat2(AT_FDCWD, file2_s2d3, AT_FDCWD, file1_s2d3, - RENAME_EXCHANGE)); + RENAME_EXCHANGE)); ASSERT_EQ(0, rename(file2_s2d3, file1_s2d3));
/* Exchanges files and directories with same parent, twice. */ ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3, - RENAME_EXCHANGE)); + RENAME_EXCHANGE)); ASSERT_EQ(0, renameat2(AT_FDCWD, file1_s2d2, AT_FDCWD, dir_s2d3, - RENAME_EXCHANGE)); + RENAME_EXCHANGE)); }
TEST_F_FORK(layout1, rename_dir) @@ -1707,8 +1737,8 @@ TEST_F_FORK(layout1, rename_dir) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd);
@@ -1745,7 +1775,7 @@ TEST_F_FORK(layout1, rename_dir) * directory removal. */ ASSERT_EQ(0, renameat2(AT_FDCWD, dir_s1d3, AT_FDCWD, file1_s1d2, - RENAME_EXCHANGE)); + RENAME_EXCHANGE)); ASSERT_EQ(0, unlink(dir_s1d3)); ASSERT_EQ(0, mkdir(dir_s1d3, 0700)); ASSERT_EQ(0, rename(file1_s1d2, dir_s1d3)); @@ -1761,8 +1791,8 @@ TEST_F_FORK(layout1, remove_dir) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd);
@@ -1798,8 +1828,8 @@ TEST_F_FORK(layout1, remove_file) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); @@ -1814,7 +1844,8 @@ TEST_F_FORK(layout1, remove_file) }
static void test_make_file(struct __test_metadata *const _metadata, - const __u64 access, const mode_t mode, const dev_t dev) + const __u64 access, const mode_t mode, + const dev_t dev) { const struct rule rules[] = { { @@ -1829,9 +1860,10 @@ static void test_make_file(struct __test
ASSERT_EQ(0, unlink(file1_s1d1)); ASSERT_EQ(0, unlink(file2_s1d1)); - ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev)) { - TH_LOG("Failed to make file "%s": %s", - file2_s1d1, strerror(errno)); + ASSERT_EQ(0, mknod(file2_s1d1, mode | 0400, dev)) + { + TH_LOG("Failed to make file "%s": %s", file2_s1d1, + strerror(errno)); };
ASSERT_EQ(0, unlink(file1_s1d2)); @@ -1850,9 +1882,10 @@ static void test_make_file(struct __test ASSERT_EQ(-1, rename(file2_s1d1, file1_s1d1)); ASSERT_EQ(EACCES, errno);
- ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev)) { - TH_LOG("Failed to make file "%s": %s", - file1_s1d2, strerror(errno)); + ASSERT_EQ(0, mknod(file1_s1d2, mode | 0400, dev)) + { + TH_LOG("Failed to make file "%s": %s", file1_s1d2, + strerror(errno)); }; ASSERT_EQ(0, link(file1_s1d2, file2_s1d2)); ASSERT_EQ(0, unlink(file2_s1d2)); @@ -1869,7 +1902,7 @@ TEST_F_FORK(layout1, make_char) /* Creates a /dev/null device. */ set_cap(_metadata, CAP_MKNOD); test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_CHAR, S_IFCHR, - makedev(1, 3)); + makedev(1, 3)); }
TEST_F_FORK(layout1, make_block) @@ -1877,7 +1910,7 @@ TEST_F_FORK(layout1, make_block) /* Creates a /dev/loop0 device. */ set_cap(_metadata, CAP_MKNOD); test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_BLOCK, S_IFBLK, - makedev(7, 0)); + makedev(7, 0)); }
TEST_F_FORK(layout1, make_reg_1) @@ -1909,8 +1942,8 @@ TEST_F_FORK(layout1, make_sym) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd);
@@ -1954,8 +1987,8 @@ TEST_F_FORK(layout1, make_dir) }, {}, }; - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd);
@@ -1974,12 +2007,12 @@ TEST_F_FORK(layout1, make_dir) }
static int open_proc_fd(struct __test_metadata *const _metadata, const int fd, - const int open_flags) + const int open_flags) { static const char path_template[] = "/proc/self/fd/%d"; char procfd_path[sizeof(path_template) + 10]; - const int procfd_path_size = snprintf(procfd_path, sizeof(procfd_path), - path_template, fd); + const int procfd_path_size = + snprintf(procfd_path, sizeof(procfd_path), path_template, fd);
ASSERT_LT(procfd_path_size, sizeof(procfd_path)); return open(procfd_path, open_flags); @@ -1995,9 +2028,10 @@ TEST_F_FORK(layout1, proc_unlinked_file) {}, }; int reg_fd, proc_fd; - const int ruleset_fd = create_ruleset(_metadata, - LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, rules); + const int ruleset_fd = create_ruleset( + _metadata, + LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE, + rules);
ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); @@ -2014,9 +2048,10 @@ TEST_F_FORK(layout1, proc_unlinked_file) ASSERT_EQ(0, close(proc_fd));
proc_fd = open_proc_fd(_metadata, reg_fd, O_RDWR | O_CLOEXEC); - ASSERT_EQ(-1, proc_fd) { - TH_LOG("Successfully opened /proc/self/fd/%d: %s", - reg_fd, strerror(errno)); + ASSERT_EQ(-1, proc_fd) + { + TH_LOG("Successfully opened /proc/self/fd/%d: %s", reg_fd, + strerror(errno)); } ASSERT_EQ(EACCES, errno);
@@ -2032,13 +2067,13 @@ TEST_F_FORK(layout1, proc_pipe) { .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, {}, }; /* Limits read and write access to files tied to the filesystem. */ - const int ruleset_fd = create_ruleset(_metadata, rules[0].access, - rules); + const int ruleset_fd = + create_ruleset(_metadata, rules[0].access, rules);
ASSERT_LE(0, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd); @@ -2050,7 +2085,8 @@ TEST_F_FORK(layout1, proc_pipe)
/* Checks access to pipes through FD. */ ASSERT_EQ(0, pipe2(pipe_fds, O_CLOEXEC)); - ASSERT_EQ(1, write(pipe_fds[1], ".", 1)) { + ASSERT_EQ(1, write(pipe_fds[1], ".", 1)) + { TH_LOG("Failed to write in pipe: %s", strerror(errno)); } ASSERT_EQ(1, read(pipe_fds[0], &buf, 1)); @@ -2059,9 +2095,10 @@ TEST_F_FORK(layout1, proc_pipe) /* Checks write access to pipe through /proc/self/fd . */ proc_fd = open_proc_fd(_metadata, pipe_fds[1], O_WRONLY | O_CLOEXEC); ASSERT_LE(0, proc_fd); - ASSERT_EQ(1, write(proc_fd, ".", 1)) { + ASSERT_EQ(1, write(proc_fd, ".", 1)) + { TH_LOG("Failed to write through /proc/self/fd/%d: %s", - pipe_fds[1], strerror(errno)); + pipe_fds[1], strerror(errno)); } ASSERT_EQ(0, close(proc_fd));
@@ -2069,9 +2106,10 @@ TEST_F_FORK(layout1, proc_pipe) proc_fd = open_proc_fd(_metadata, pipe_fds[0], O_RDONLY | O_CLOEXEC); ASSERT_LE(0, proc_fd); buf = '\0'; - ASSERT_EQ(1, read(proc_fd, &buf, 1)) { + ASSERT_EQ(1, read(proc_fd, &buf, 1)) + { TH_LOG("Failed to read through /proc/self/fd/%d: %s", - pipe_fds[1], strerror(errno)); + pipe_fds[1], strerror(errno)); } ASSERT_EQ(0, close(proc_fd));
@@ -2292,8 +2330,8 @@ TEST_F_FORK(layout1_bind, same_content_s ASSERT_EQ(EACCES, test_open(bind_file1_s1d3, O_WRONLY)); }
-#define LOWER_BASE TMP_DIR "/lower" -#define LOWER_DATA LOWER_BASE "/data" +#define LOWER_BASE TMP_DIR "/lower" +#define LOWER_DATA LOWER_BASE "/data" static const char lower_fl1[] = LOWER_DATA "/fl1"; static const char lower_dl1[] = LOWER_DATA "/dl1"; static const char lower_dl1_fl2[] = LOWER_DATA "/dl1/fl2"; @@ -2319,9 +2357,9 @@ static const char (*lower_sub_files[])[] NULL, };
-#define UPPER_BASE TMP_DIR "/upper" -#define UPPER_DATA UPPER_BASE "/data" -#define UPPER_WORK UPPER_BASE "/work" +#define UPPER_BASE TMP_DIR "/upper" +#define UPPER_DATA UPPER_BASE "/data" +#define UPPER_WORK UPPER_BASE "/work" static const char upper_fu1[] = UPPER_DATA "/fu1"; static const char upper_du1[] = UPPER_DATA "/du1"; static const char upper_du1_fu2[] = UPPER_DATA "/du1/fu2"; @@ -2347,8 +2385,8 @@ static const char (*upper_sub_files[])[] NULL, };
-#define MERGE_BASE TMP_DIR "/merge" -#define MERGE_DATA MERGE_BASE "/data" +#define MERGE_BASE TMP_DIR "/merge" +#define MERGE_DATA MERGE_BASE "/data" static const char merge_fl1[] = MERGE_DATA "/fl1"; static const char merge_dl1[] = MERGE_DATA "/dl1"; static const char merge_dl1_fl2[] = MERGE_DATA "/dl1/fl2"; @@ -2374,12 +2412,8 @@ static const char (*merge_base_directori NULL, }; static const char (*merge_sub_files[])[] = { - &merge_dl1_fl2, - &merge_du1_fu2, - &merge_do1_fo2, - &merge_do1_fl3, - &merge_do1_fu3, - NULL, + &merge_dl1_fl2, &merge_du1_fu2, &merge_do1_fo2, + &merge_do1_fl3, &merge_do1_fu3, NULL, };
/* @@ -2455,9 +2489,8 @@ FIXTURE_SETUP(layout2_overlay) set_cap(_metadata, CAP_SYS_ADMIN); set_cap(_metadata, CAP_DAC_OVERRIDE); ASSERT_EQ(0, mount("overlay", MERGE_DATA, "overlay", 0, - "lowerdir=" LOWER_DATA - ",upperdir=" UPPER_DATA - ",workdir=" UPPER_WORK)); + "lowerdir=" LOWER_DATA ",upperdir=" UPPER_DATA + ",workdir=" UPPER_WORK)); clear_cap(_metadata, CAP_DAC_OVERRIDE); clear_cap(_metadata, CAP_SYS_ADMIN); } @@ -2524,9 +2557,9 @@ TEST_F_FORK(layout2_overlay, no_restrict ASSERT_EQ(0, test_open(merge_do1_fu3, O_RDONLY)); }
-#define for_each_path(path_list, path_entry, i) \ - for (i = 0, path_entry = *path_list[i]; path_list[i]; \ - path_entry = *path_list[++i]) +#define for_each_path(path_list, path_entry, i) \ + for (i = 0, path_entry = *path_list[i]; path_list[i]; \ + path_entry = *path_list[++i])
TEST_F_FORK(layout2_overlay, same_content_different_file) { @@ -2622,27 +2655,27 @@ TEST_F_FORK(layout2_overlay, same_conten { .path = merge_dl1_fl2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, { .path = merge_du1_fu2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, { .path = merge_do1_fo2, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, { .path = merge_do1_fl3, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, { .path = merge_do1_fu3, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, {}, }; @@ -2650,7 +2683,7 @@ TEST_F_FORK(layout2_overlay, same_conten { .path = MERGE_DATA, .access = LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_WRITE_FILE, + LANDLOCK_ACCESS_FS_WRITE_FILE, }, {}, }; @@ -2670,7 +2703,8 @@ TEST_F_FORK(layout2_overlay, same_conten ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY)); } for_each_path(lower_base_directories, path_entry, i) { - ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); + ASSERT_EQ(EACCES, + test_open(path_entry, O_RDONLY | O_DIRECTORY)); } for_each_path(lower_sub_files, path_entry, i) { ASSERT_EQ(0, test_open(path_entry, O_RDONLY)); @@ -2682,7 +2716,8 @@ TEST_F_FORK(layout2_overlay, same_conten ASSERT_EQ(EACCES, test_open(path_entry, O_WRONLY)); } for_each_path(upper_base_directories, path_entry, i) { - ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); + ASSERT_EQ(EACCES, + test_open(path_entry, O_RDONLY | O_DIRECTORY)); } for_each_path(upper_sub_files, path_entry, i) { ASSERT_EQ(0, test_open(path_entry, O_RDONLY)); @@ -2767,7 +2802,8 @@ TEST_F_FORK(layout2_overlay, same_conten ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR)); } for_each_path(merge_base_directories, path_entry, i) { - ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); + ASSERT_EQ(EACCES, + test_open(path_entry, O_RDONLY | O_DIRECTORY)); } for_each_path(merge_sub_files, path_entry, i) { ASSERT_EQ(0, test_open(path_entry, O_RDWR)); @@ -2792,7 +2828,8 @@ TEST_F_FORK(layout2_overlay, same_conten ASSERT_EQ(EACCES, test_open(path_entry, O_RDWR)); } for_each_path(merge_base_directories, path_entry, i) { - ASSERT_EQ(EACCES, test_open(path_entry, O_RDONLY | O_DIRECTORY)); + ASSERT_EQ(EACCES, + test_open(path_entry, O_RDONLY | O_DIRECTORY)); } for_each_path(merge_sub_files, path_entry, i) { ASSERT_EQ(0, test_open(path_entry, O_RDWR)); --- a/tools/testing/selftests/landlock/ptrace_test.c +++ b/tools/testing/selftests/landlock/ptrace_test.c @@ -26,9 +26,10 @@ static void create_domain(struct __test_ .handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_BLOCK, };
- ruleset_fd = landlock_create_ruleset(&ruleset_attr, - sizeof(ruleset_attr), 0); - EXPECT_LE(0, ruleset_fd) { + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + EXPECT_LE(0, ruleset_fd) + { TH_LOG("Failed to create a ruleset: %s", strerror(errno)); } EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); @@ -43,7 +44,7 @@ static int test_ptrace_read(const pid_t int procenv_path_size, fd;
procenv_path_size = snprintf(procenv_path, sizeof(procenv_path), - path_template, pid); + path_template, pid); if (procenv_path_size >= sizeof(procenv_path)) return E2BIG;
@@ -63,7 +64,8 @@ static int test_ptrace_read(const pid_t FIXTURE(hierarchy) {}; /* clang-format on */
-FIXTURE_VARIANT(hierarchy) { +FIXTURE_VARIANT(hierarchy) +{ const bool domain_both; const bool domain_parent; const bool domain_child; @@ -217,10 +219,12 @@ FIXTURE_VARIANT_ADD(hierarchy, deny_with };
FIXTURE_SETUP(hierarchy) -{ } +{ +}
FIXTURE_TEARDOWN(hierarchy) -{ } +{ +}
/* Test PTRACE_TRACEME and PTRACE_ATTACH for parent and child. */ TEST_F(hierarchy, trace) @@ -348,7 +352,7 @@ TEST_F(hierarchy, trace) ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); ASSERT_EQ(child, waitpid(child, &status, 0)); if (WIFSIGNALED(status) || !WIFEXITED(status) || - WEXITSTATUS(status) != EXIT_SUCCESS) + WEXITSTATUS(status) != EXIT_SUCCESS) _metadata->passed = 0; }
From: Mickaël Salaün mic@digikod.net
commit 9805a722db071e1772b80e6e0ff33f35355639ac upstream.
In preparation to a following commit, add clang-format on and clang-format off stanzas around constant definitions. This enables to keep aligned values, which is much more readable than packed definitions.
Link: https://lore.kernel.org/r/20220506160513.523257-7-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- samples/landlock/sandboxer.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -70,11 +70,15 @@ static int parse_path(char *env_path, co return num_paths; }
+/* clang-format off */ + #define ACCESS_FILE ( \ LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_WRITE_FILE | \ LANDLOCK_ACCESS_FS_READ_FILE)
+/* clang-format on */ + static int populate_ruleset( const char *const env_var, const int ruleset_fd, const __u64 allowed_access) @@ -139,6 +143,8 @@ out_free_name: return ret; }
+/* clang-format off */ + #define ACCESS_FS_ROUGHLY_READ ( \ LANDLOCK_ACCESS_FS_EXECUTE | \ LANDLOCK_ACCESS_FS_READ_FILE | \ @@ -156,6 +162,8 @@ out_free_name: LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ LANDLOCK_ACCESS_FS_MAKE_SYM)
+/* clang-format on */ + int main(const int argc, char *const argv[], char *const *const envp) { const char *cmd_path;
From: Mickaël Salaün mic@digikod.net
commit 81709f3dccacf4104a4bc2daa80bdd767a9c4c54 upstream.
Let's follow a consistent and documented coding style. Everything may not be to our liking but it is better than tacit knowledge. Moreover, this will help maintain style consistency between different developers.
This contains only whitespace changes.
Automatically formatted with: clang-format-14 -i samples/landlock/*.[ch]
Link: https://lore.kernel.org/r/20220506160513.523257-8-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- samples/landlock/sandboxer.c | 96 +++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 44 deletions(-)
--- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -22,9 +22,9 @@ #include <unistd.h>
#ifndef landlock_create_ruleset -static inline int landlock_create_ruleset( - const struct landlock_ruleset_attr *const attr, - const size_t size, const __u32 flags) +static inline int +landlock_create_ruleset(const struct landlock_ruleset_attr *const attr, + const size_t size, const __u32 flags) { return syscall(__NR_landlock_create_ruleset, attr, size, flags); } @@ -32,17 +32,18 @@ static inline int landlock_create_rulese
#ifndef landlock_add_rule static inline int landlock_add_rule(const int ruleset_fd, - const enum landlock_rule_type rule_type, - const void *const rule_attr, const __u32 flags) + const enum landlock_rule_type rule_type, + const void *const rule_attr, + const __u32 flags) { - return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, - rule_attr, flags); + return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr, + flags); } #endif
#ifndef landlock_restrict_self static inline int landlock_restrict_self(const int ruleset_fd, - const __u32 flags) + const __u32 flags) { return syscall(__NR_landlock_restrict_self, ruleset_fd, flags); } @@ -79,9 +80,8 @@ static int parse_path(char *env_path, co
/* clang-format on */
-static int populate_ruleset( - const char *const env_var, const int ruleset_fd, - const __u64 allowed_access) +static int populate_ruleset(const char *const env_var, const int ruleset_fd, + const __u64 allowed_access) { int num_paths, i, ret = 1; char *env_path_name; @@ -111,12 +111,10 @@ static int populate_ruleset( for (i = 0; i < num_paths; i++) { struct stat statbuf;
- path_beneath.parent_fd = open(path_list[i], O_PATH | - O_CLOEXEC); + path_beneath.parent_fd = open(path_list[i], O_PATH | O_CLOEXEC); if (path_beneath.parent_fd < 0) { fprintf(stderr, "Failed to open "%s": %s\n", - path_list[i], - strerror(errno)); + path_list[i], strerror(errno)); goto out_free_name; } if (fstat(path_beneath.parent_fd, &statbuf)) { @@ -127,9 +125,10 @@ static int populate_ruleset( if (!S_ISDIR(statbuf.st_mode)) path_beneath.allowed_access &= ACCESS_FILE; if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0)) { - fprintf(stderr, "Failed to update the ruleset with "%s": %s\n", - path_list[i], strerror(errno)); + &path_beneath, 0)) { + fprintf(stderr, + "Failed to update the ruleset with "%s": %s\n", + path_list[i], strerror(errno)); close(path_beneath.parent_fd); goto out_free_name; } @@ -171,55 +170,64 @@ int main(const int argc, char *const arg int ruleset_fd; struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = ACCESS_FS_ROUGHLY_READ | - ACCESS_FS_ROUGHLY_WRITE, + ACCESS_FS_ROUGHLY_WRITE, };
if (argc < 2) { - fprintf(stderr, "usage: %s="..." %s="..." %s <cmd> [args]...\n\n", - ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); - fprintf(stderr, "Launch a command in a restricted environment.\n\n"); + fprintf(stderr, + "usage: %s="..." %s="..." %s <cmd> [args]...\n\n", + ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); + fprintf(stderr, + "Launch a command in a restricted environment.\n\n"); fprintf(stderr, "Environment variables containing paths, " "each separated by a colon:\n"); - fprintf(stderr, "* %s: list of paths allowed to be used in a read-only way.\n", - ENV_FS_RO_NAME); - fprintf(stderr, "* %s: list of paths allowed to be used in a read-write way.\n", - ENV_FS_RW_NAME); - fprintf(stderr, "\nexample:\n" - "%s="/bin:/lib:/usr:/proc:/etc:/dev/urandom" " - "%s="/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp" " - "%s bash -i\n", - ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); + fprintf(stderr, + "* %s: list of paths allowed to be used in a read-only way.\n", + ENV_FS_RO_NAME); + fprintf(stderr, + "* %s: list of paths allowed to be used in a read-write way.\n", + ENV_FS_RW_NAME); + fprintf(stderr, + "\nexample:\n" + "%s="/bin:/lib:/usr:/proc:/etc:/dev/urandom" " + "%s="/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp" " + "%s bash -i\n", + ENV_FS_RO_NAME, ENV_FS_RW_NAME, argv[0]); return 1; }
- ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); if (ruleset_fd < 0) { const int err = errno;
perror("Failed to create a ruleset"); switch (err) { case ENOSYS: - fprintf(stderr, "Hint: Landlock is not supported by the current kernel. " - "To support it, build the kernel with " - "CONFIG_SECURITY_LANDLOCK=y and prepend " - ""landlock," to the content of CONFIG_LSM.\n"); + fprintf(stderr, + "Hint: Landlock is not supported by the current kernel. " + "To support it, build the kernel with " + "CONFIG_SECURITY_LANDLOCK=y and prepend " + ""landlock," to the content of CONFIG_LSM.\n"); break; case EOPNOTSUPP: - fprintf(stderr, "Hint: Landlock is currently disabled. " - "It can be enabled in the kernel configuration by " - "prepending "landlock," to the content of CONFIG_LSM, " - "or at boot time by setting the same content to the " - ""lsm" kernel parameter.\n"); + fprintf(stderr, + "Hint: Landlock is currently disabled. " + "It can be enabled in the kernel configuration by " + "prepending "landlock," to the content of CONFIG_LSM, " + "or at boot time by setting the same content to the " + ""lsm" kernel parameter.\n"); break; } return 1; } if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd, - ACCESS_FS_ROUGHLY_READ)) { + ACCESS_FS_ROUGHLY_READ)) { goto err_close_ruleset; } if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd, - ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE)) { + ACCESS_FS_ROUGHLY_READ | + ACCESS_FS_ROUGHLY_WRITE)) { goto err_close_ruleset; } if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { @@ -236,7 +244,7 @@ int main(const int argc, char *const arg cmd_argv = argv + 1; execvpe(cmd_path, cmd_argv, envp); fprintf(stderr, "Failed to execute "%s": %s\n", cmd_path, - strerror(errno)); + strerror(errno)); fprintf(stderr, "Hint: access to the binary, the interpreter or " "shared libraries may be denied.\n"); return 1;
From: Mickaël Salaün mic@digikod.net
commit a13e248ff90e81e9322406c0e618cf2168702f4e upstream.
It is not mandatory to pass a file descriptor obtained with the O_PATH flag. Also, replace rule's accesses with ruleset's accesses.
Link: https://lore.kernel.org/r/20220506160820.524344-2-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/landlock.h | 5 +++-- security/landlock/syscalls.c | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-)
--- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -62,8 +62,9 @@ struct landlock_path_beneath_attr { */ __u64 allowed_access; /** - * @parent_fd: File descriptor, open with ``O_PATH``, which identifies - * the parent directory of a file hierarchy, or just a file. + * @parent_fd: File descriptor, preferably opened with ``O_PATH``, + * which identifies the parent directory of a file hierarchy, or just a + * file. */ __s32 parent_fd; /* --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -292,14 +292,13 @@ out_fdput: * * - EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; * - EINVAL: @flags is not 0, or inconsistent access in the rule (i.e. - * &landlock_path_beneath_attr.allowed_access is not a subset of the rule's - * accesses); + * &landlock_path_beneath_attr.allowed_access is not a subset of the + * ruleset handled accesses); * - ENOMSG: Empty accesses (e.g. &landlock_path_beneath_attr.allowed_access); * - EBADF: @ruleset_fd is not a file descriptor for the current thread, or a * member of @rule_attr is not a file descriptor as expected; * - EBADFD: @ruleset_fd is not a ruleset file descriptor, or a member of - * @rule_attr is not the expected file descriptor type (e.g. file open - * without O_PATH); + * @rule_attr is not the expected file descriptor type; * - EPERM: @ruleset_fd has no write access to the underlying ruleset; * - EFAULT: @rule_attr inconsistency. */
From: Mickaël Salaün mic@digikod.net
commit 87129ef13603ae46c82bcd09eed948acf0506dbb upstream.
Replace SYS_<syscall> with __NR_<syscall>. Using the __NR_<syscall> notation, provided by UAPI, is useful to build tests on systems without the SYS_<syscall> definitions.
Replace SYS_pivot_root with __NR_pivot_root, and SYS_move_mount with __NR_move_mount.
Define renameat2() and RENAME_EXCHANGE if they are unknown to old build systems.
Cc: Shuah Khan shuah@kernel.org Link: https://lore.kernel.org/r/20220506160820.524344-3-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/fs_test.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-)
--- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -22,6 +22,19 @@
#include "common.h"
+#ifndef renameat2 +int renameat2(int olddirfd, const char *oldpath, int newdirfd, + const char *newpath, unsigned int flags) +{ + return syscall(__NR_renameat2, olddirfd, oldpath, newdirfd, newpath, + flags); +} +#endif + +#ifndef RENAME_EXCHANGE +#define RENAME_EXCHANGE (1 << 1) +#endif + #define TMP_DIR "tmp" #define BINARY_PATH "./true"
@@ -1279,7 +1292,7 @@ TEST_F_FORK(layout1, rule_inside_mount_n int ruleset_fd;
set_cap(_metadata, CAP_SYS_ADMIN); - ASSERT_EQ(0, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3)) + ASSERT_EQ(0, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3)) { TH_LOG("Failed to pivot root: %s", strerror(errno)); }; @@ -1313,7 +1326,7 @@ TEST_F_FORK(layout1, mount_and_pivot) set_cap(_metadata, CAP_SYS_ADMIN); ASSERT_EQ(-1, mount(NULL, dir_s3d2, NULL, MS_RDONLY, NULL)); ASSERT_EQ(EPERM, errno); - ASSERT_EQ(-1, syscall(SYS_pivot_root, dir_s3d2, dir_s3d3)); + ASSERT_EQ(-1, syscall(__NR_pivot_root, dir_s3d2, dir_s3d3)); ASSERT_EQ(EPERM, errno); clear_cap(_metadata, CAP_SYS_ADMIN); } @@ -1332,13 +1345,13 @@ TEST_F_FORK(layout1, move_mount) ASSERT_LE(0, ruleset_fd);
set_cap(_metadata, CAP_SYS_ADMIN); - ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, + ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, dir_s1d2, 0)) { TH_LOG("Failed to move mount: %s", strerror(errno)); }
- ASSERT_EQ(0, syscall(SYS_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD, + ASSERT_EQ(0, syscall(__NR_move_mount, AT_FDCWD, dir_s1d2, AT_FDCWD, dir_s3d2, 0)); clear_cap(_metadata, CAP_SYS_ADMIN);
@@ -1346,7 +1359,7 @@ TEST_F_FORK(layout1, move_mount) ASSERT_EQ(0, close(ruleset_fd));
set_cap(_metadata, CAP_SYS_ADMIN); - ASSERT_EQ(-1, syscall(SYS_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, + ASSERT_EQ(-1, syscall(__NR_move_mount, AT_FDCWD, dir_s3d2, AT_FDCWD, dir_s1d2, 0)); ASSERT_EQ(EPERM, errno); clear_cap(_metadata, CAP_SYS_ADMIN);
From: Mickaël Salaün mic@digikod.net
commit 291865bd7e8bb4b4033d341fa02dafa728e6378c upstream.
This might be useful when the struct landlock_ruleset_attr will get more fields.
Cc: Shuah Khan shuah@kernel.org Link: https://lore.kernel.org/r/20220506160820.524344-4-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/base_test.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -35,6 +35,8 @@ TEST(inconsistent_attr) ASSERT_EQ(EINVAL, errno); ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 1, 0)); ASSERT_EQ(EINVAL, errno); + ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 7, 0)); + ASSERT_EQ(EINVAL, errno);
ASSERT_EQ(-1, landlock_create_ruleset(NULL, 1, 0)); /* The size if less than sizeof(struct landlock_attr_enforce). */ @@ -47,6 +49,9 @@ TEST(inconsistent_attr) ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0)); ASSERT_EQ(E2BIG, errno);
+ /* Checks minimal valid attribute size. */ + ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 8, 0)); + ASSERT_EQ(ENOMSG, errno); ASSERT_EQ(-1, landlock_create_ruleset( ruleset_attr, sizeof(struct landlock_ruleset_attr), 0));
From: Mickaël Salaün mic@digikod.net
commit c56b3bf566da5a0dd3b58ad97a614b0928b06ebf upstream.
Make sure that trying to use unknown access rights returns an error.
Cc: Shuah Khan shuah@kernel.org Link: https://lore.kernel.org/r/20220506160820.524344-5-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/fs_test.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
--- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -448,6 +448,22 @@ TEST_F_FORK(layout1, file_access_rights) ASSERT_EQ(0, close(path_beneath.parent_fd)); }
+TEST_F_FORK(layout1, unknown_access_rights) +{ + __u64 access_mask; + + for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST; + access_mask >>= 1) { + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = access_mask, + }; + + ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, + sizeof(ruleset_attr), 0)); + ASSERT_EQ(EINVAL, errno); + } +} + static void add_path_beneath(struct __test_metadata *const _metadata, const int ruleset_fd, const __u64 allowed_access, const char *const path)
From: Mickaël Salaün mic@digikod.net
commit d18955d094d09a220cf8f533f5e896a2fe31575a upstream.
Make sure that all filesystem access rights can be tied to directories.
Rename layout1.file_access_rights to layout1.file_and_dir_access_rights to reflect this change.
Cc: Shuah Khan shuah@kernel.org Link: https://lore.kernel.org/r/20220506160820.524344-6-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/fs_test.c | 30 +++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-)
--- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -418,11 +418,12 @@ TEST_F_FORK(layout1, inval)
/* clang-format on */
-TEST_F_FORK(layout1, file_access_rights) +TEST_F_FORK(layout1, file_and_dir_access_rights) { __u64 access; int err; - struct landlock_path_beneath_attr path_beneath = {}; + struct landlock_path_beneath_attr path_beneath_file = {}, + path_beneath_dir = {}; struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = ACCESS_ALL, }; @@ -432,20 +433,33 @@ TEST_F_FORK(layout1, file_access_rights) ASSERT_LE(0, ruleset_fd);
/* Tests access rights for files. */ - path_beneath.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC); - ASSERT_LE(0, path_beneath.parent_fd); + path_beneath_file.parent_fd = open(file1_s1d2, O_PATH | O_CLOEXEC); + ASSERT_LE(0, path_beneath_file.parent_fd); + + /* Tests access rights for directories. */ + path_beneath_dir.parent_fd = + open(dir_s1d2, O_PATH | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath_dir.parent_fd); + for (access = 1; access <= ACCESS_LAST; access <<= 1) { - path_beneath.allowed_access = access; + path_beneath_dir.allowed_access = access; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, + LANDLOCK_RULE_PATH_BENEATH, + &path_beneath_dir, 0)); + + path_beneath_file.allowed_access = access; err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, - &path_beneath, 0); - if ((access | ACCESS_FILE) == ACCESS_FILE) { + &path_beneath_file, 0); + if (access & ACCESS_FILE) { ASSERT_EQ(0, err); } else { ASSERT_EQ(-1, err); ASSERT_EQ(EINVAL, errno); } } - ASSERT_EQ(0, close(path_beneath.parent_fd)); + ASSERT_EQ(0, close(path_beneath_file.parent_fd)); + ASSERT_EQ(0, close(path_beneath_dir.parent_fd)); + ASSERT_EQ(0, close(ruleset_fd)); }
TEST_F_FORK(layout1, unknown_access_rights)
From: Mickaël Salaün mic@digikod.net
commit 6a1bdd4a0bfc30fa4fa2b3a979e6525f28996db9 upstream.
These tests were missing to check the check_access_path() call with all combinations of maybe_remove(old_dentry) and maybe_remove(new_dentry).
Extend layout1.link with a new complementary test and check that REMOVE_FILE is not required to link a file.
Cc: Shuah Khan shuah@kernel.org Link: https://lore.kernel.org/r/20220506160820.524344-7-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/fs_test.c | 41 ++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-)
--- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -1659,15 +1659,21 @@ TEST_F_FORK(layout1, execute)
TEST_F_FORK(layout1, link) { - const struct rule rules[] = { + const struct rule layer1[] = { { .path = dir_s1d2, .access = LANDLOCK_ACCESS_FS_MAKE_REG, }, {}, }; - const int ruleset_fd = - create_ruleset(_metadata, rules[0].access, rules); + const struct rule layer2[] = { + { + .path = dir_s1d3, + .access = LANDLOCK_ACCESS_FS_REMOVE_FILE, + }, + {}, + }; + int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
ASSERT_LE(0, ruleset_fd);
@@ -1680,14 +1686,30 @@ TEST_F_FORK(layout1, link)
ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1)); ASSERT_EQ(EACCES, errno); + /* Denies linking because of reparenting. */ ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2)); ASSERT_EQ(EXDEV, errno); ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3)); ASSERT_EQ(EXDEV, errno); + ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2)); + ASSERT_EQ(EXDEV, errno);
ASSERT_EQ(0, link(file2_s1d2, file1_s1d2)); ASSERT_EQ(0, link(file2_s1d3, file1_s1d3)); + + /* Prepares for next unlinks. */ + ASSERT_EQ(0, unlink(file2_s1d2)); + ASSERT_EQ(0, unlink(file2_s1d3)); + + ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Checks that linkind doesn't require the ability to delete a file. */ + ASSERT_EQ(0, link(file1_s1d2, file2_s1d2)); + ASSERT_EQ(0, link(file1_s1d3, file2_s1d3)); }
TEST_F_FORK(layout1, rename_file) @@ -1708,7 +1730,6 @@ TEST_F_FORK(layout1, rename_file)
ASSERT_LE(0, ruleset_fd);
- ASSERT_EQ(0, unlink(file1_s1d1)); ASSERT_EQ(0, unlink(file1_s1d2));
enforce_ruleset(_metadata, ruleset_fd); @@ -1744,9 +1765,15 @@ TEST_F_FORK(layout1, rename_file) ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1, RENAME_EXCHANGE)); ASSERT_EQ(EACCES, errno); + /* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */ + ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1)); + ASSERT_EQ(EACCES, errno); ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2, RENAME_EXCHANGE)); ASSERT_EQ(EACCES, errno); + /* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */ + ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2)); + ASSERT_EQ(EACCES, errno);
/* Renames files with different parents. */ ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2)); @@ -1809,9 +1836,15 @@ TEST_F_FORK(layout1, rename_dir) ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1, RENAME_EXCHANGE)); ASSERT_EQ(EACCES, errno); + /* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */ + ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1)); + ASSERT_EQ(EACCES, errno); ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2, RENAME_EXCHANGE)); ASSERT_EQ(EACCES, errno); + /* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */ + ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2)); + ASSERT_EQ(EACCES, errno);
/* * Exchanges and renames directory to the same parent, which allows
From: Mickaël Salaün mic@digikod.net
commit d1788ad990874734341b05ab8ccb6448c09c6422 upstream.
The O_PATH flag is currently not handled by Landlock. Let's make sure this behavior will remain consistent with the same ruleset over time.
Cc: Shuah Khan shuah@kernel.org Link: https://lore.kernel.org/r/20220506160820.524344-8-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/fs_test.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
--- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -654,17 +654,23 @@ TEST_F_FORK(layout1, effective_access) enforce_ruleset(_metadata, ruleset_fd); ASSERT_EQ(0, close(ruleset_fd));
- /* Tests on a directory. */ + /* Tests on a directory (with or without O_PATH). */ ASSERT_EQ(EACCES, test_open("/", O_RDONLY)); + ASSERT_EQ(0, test_open("/", O_RDONLY | O_PATH)); ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY)); + ASSERT_EQ(0, test_open(dir_s1d1, O_RDONLY | O_PATH)); ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); + ASSERT_EQ(0, test_open(file1_s1d1, O_RDONLY | O_PATH)); + ASSERT_EQ(0, test_open(dir_s1d2, O_RDONLY)); ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY)); ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY)); ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY));
- /* Tests on a file. */ + /* Tests on a file (with or without O_PATH). */ ASSERT_EQ(EACCES, test_open(dir_s2d2, O_RDONLY)); + ASSERT_EQ(0, test_open(dir_s2d2, O_RDONLY | O_PATH)); + ASSERT_EQ(0, test_open(file1_s2d2, O_RDONLY));
/* Checks effective read and write actions. */
From: Mickaël Salaün mic@digikod.net
commit 589172e5636c4d16c40b90e87543d43defe2d968 upstream.
This makes more sense to first check the ruleset FD and then the rule attribute. It will be useful to factor out code for other rule types.
Add inval_add_rule_arguments tests, extension of empty_path_beneath_attr tests, to also check error ordering for landlock_add_rule(2).
Link: https://lore.kernel.org/r/20220506160820.524344-9-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/landlock/syscalls.c | 22 ++++++++++------- tools/testing/selftests/landlock/base_test.c | 34 +++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 11 deletions(-)
--- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -318,20 +318,24 @@ SYSCALL_DEFINE4(landlock_add_rule, const if (flags) return -EINVAL;
- if (rule_type != LANDLOCK_RULE_PATH_BENEATH) - return -EINVAL; - - /* Copies raw user space buffer, only one type for now. */ - res = copy_from_user(&path_beneath_attr, rule_attr, - sizeof(path_beneath_attr)); - if (res) - return -EFAULT; - /* Gets and checks the ruleset. */ ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_WRITE); if (IS_ERR(ruleset)) return PTR_ERR(ruleset);
+ if (rule_type != LANDLOCK_RULE_PATH_BENEATH) { + err = -EINVAL; + goto out_put_ruleset; + } + + /* Copies raw user space buffer, only one type for now. */ + res = copy_from_user(&path_beneath_attr, rule_attr, + sizeof(path_beneath_attr)); + if (res) { + err = -EFAULT; + goto out_put_ruleset; + } + /* * Informs about useless rule: empty allowed_access (i.e. deny rules) * are ignored in path walks. --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -121,20 +121,50 @@ TEST(inval_create_ruleset_flags) ASSERT_EQ(EINVAL, errno); }
-TEST(empty_path_beneath_attr) +/* Tests ordering of syscall argument checks. */ +TEST(add_rule_checks_ordering) { const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, }; + struct landlock_path_beneath_attr path_beneath_attr = { + .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE, + .parent_fd = -1, + }; const int ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
ASSERT_LE(0, ruleset_fd);
- /* Similar to struct landlock_path_beneath_attr.parent_fd = 0 */ + /* Checks invalid flags. */ + ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 1)); + ASSERT_EQ(EINVAL, errno); + + /* Checks invalid ruleset FD. */ + ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 0)); + ASSERT_EQ(EBADF, errno); + + /* Checks invalid rule type. */ + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, 0, NULL, 0)); + ASSERT_EQ(EINVAL, errno); + + /* Checks invalid rule attr. */ ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, NULL, 0)); ASSERT_EQ(EFAULT, errno); + + /* Checks invalid path_beneath.parent_fd. */ + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, + &path_beneath_attr, 0)); + ASSERT_EQ(EBADF, errno); + + /* Checks valid call. */ + path_beneath_attr.parent_fd = + open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath_attr.parent_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, + &path_beneath_attr, 0)); + ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); ASSERT_EQ(0, close(ruleset_fd)); }
From: Mickaël Salaün mic@digikod.net
commit eba39ca4b155c54adf471a69e91799cc1727873f upstream.
According to the Landlock goal to be a security feature available to unprivileges processes, it makes more sense to first check for no_new_privs before checking anything else (i.e. syscall arguments).
Merge inval_fd_enforce and unpriv_enforce_without_no_new_privs tests into the new restrict_self_checks_ordering. This is similar to the previous commit checking other syscalls.
Link: https://lore.kernel.org/r/20220506160820.524344-10-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/landlock/syscalls.c | 8 ++-- tools/testing/selftests/landlock/base_test.c | 47 +++++++++++++++++++++------ 2 files changed, 41 insertions(+), 14 deletions(-)
--- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -405,10 +405,6 @@ SYSCALL_DEFINE2(landlock_restrict_self, if (!landlock_initialized) return -EOPNOTSUPP;
- /* No flag for now. */ - if (flags) - return -EINVAL; - /* * Similar checks as for seccomp(2), except that an -EPERM may be * returned. @@ -417,6 +413,10 @@ SYSCALL_DEFINE2(landlock_restrict_self, !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM;
+ /* No flag for now. */ + if (flags) + return -EINVAL; + /* Gets and checks the ruleset. */ ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ); if (IS_ERR(ruleset)) --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -168,22 +168,49 @@ TEST(add_rule_checks_ordering) ASSERT_EQ(0, close(ruleset_fd)); }
-TEST(inval_fd_enforce) +/* Tests ordering of syscall argument and permission checks. */ +TEST(restrict_self_checks_ordering) { + const struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, + }; + struct landlock_path_beneath_attr path_beneath_attr = { + .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE, + .parent_fd = -1, + }; + const int ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + + ASSERT_LE(0, ruleset_fd); + path_beneath_attr.parent_fd = + open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath_attr.parent_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, + &path_beneath_attr, 0)); + ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); + + /* Checks unprivileged enforcement without no_new_privs. */ + drop_caps(_metadata); + ASSERT_EQ(-1, landlock_restrict_self(-1, -1)); + ASSERT_EQ(EPERM, errno); + ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); + ASSERT_EQ(EPERM, errno); + ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0)); + ASSERT_EQ(EPERM, errno); + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
+ /* Checks invalid flags. */ + ASSERT_EQ(-1, landlock_restrict_self(-1, -1)); + ASSERT_EQ(EINVAL, errno); + + /* Checks invalid ruleset FD. */ ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); ASSERT_EQ(EBADF, errno); -} - -TEST(unpriv_enforce_without_no_new_privs) -{ - int err;
- drop_caps(_metadata); - err = landlock_restrict_self(-1, 0); - ASSERT_EQ(EPERM, errno); - ASSERT_EQ(err, -1); + /* Checks valid call. */ + ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); + ASSERT_EQ(0, close(ruleset_fd)); }
TEST(ruleset_fd_io)
From: Mickaël Salaün mic@digikod.net
commit 6533d0c3a86ee1cc74ff37ac92ca597deb87015c upstream.
Add inval_create_ruleset_arguments, extension of inval_create_ruleset_flags, to also check error ordering for landlock_create_ruleset(2).
This is similar to the previous commit checking landlock_add_rule(2).
Test coverage for security/landlock is 94.4% of 504 lines accorging to gcc/gcov-11.
Link: https://lore.kernel.org/r/20220506160820.524344-11-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/landlock/base_test.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
--- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -97,14 +97,17 @@ TEST(abi_version) ASSERT_EQ(EINVAL, errno); }
-TEST(inval_create_ruleset_flags) +/* Tests ordering of syscall argument checks. */ +TEST(create_ruleset_checks_ordering) { const int last_flag = LANDLOCK_CREATE_RULESET_VERSION; const int invalid_flag = last_flag << 1; + int ruleset_fd; const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, };
+ /* Checks priority for invalid flags. */ ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, invalid_flag)); ASSERT_EQ(EINVAL, errno);
@@ -119,6 +122,22 @@ TEST(inval_create_ruleset_flags) landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), invalid_flag)); ASSERT_EQ(EINVAL, errno); + + /* Checks too big ruleset_attr size. */ + ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, -1, 0)); + ASSERT_EQ(E2BIG, errno); + + /* Checks too small ruleset_attr size. */ + ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, 0)); + ASSERT_EQ(EINVAL, errno); + ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 1, 0)); + ASSERT_EQ(EINVAL, errno); + + /* Checks valid call. */ + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); }
/* Tests ordering of syscall argument checks. */
From: Mickaël Salaün mic@digikod.net
commit 5f2ff33e10843ef51275c8611bdb7b49537aba5d upstream.
Create and use the access_mask_t typedef to enforce a consistent access mask size and uniformly use a 16-bits type. This will helps transition to a 32-bits value one day.
Add a build check to make sure all (filesystem) access rights fit in. This will be extended with a following commit.
Reviewed-by: Paul Moore paul@paul-moore.com Link: https://lore.kernel.org/r/20220506161102.525323-2-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/landlock/fs.c | 19 +++++++++++-------- security/landlock/fs.h | 2 +- security/landlock/limits.h | 2 ++ security/landlock/ruleset.c | 6 ++++-- security/landlock/ruleset.h | 16 ++++++++++++---- 5 files changed, 30 insertions(+), 15 deletions(-)
--- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -152,7 +152,8 @@ retry: * @path: Should have been checked by get_path_from_fd(). */ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, - const struct path *const path, u32 access_rights) + const struct path *const path, + access_mask_t access_rights) { int err; struct landlock_object *object; @@ -184,7 +185,8 @@ int landlock_append_fs_rule(struct landl
static inline u64 unmask_layers(const struct landlock_ruleset *const domain, const struct path *const path, - const u32 access_request, u64 layer_mask) + const access_mask_t access_request, + u64 layer_mask) { const struct landlock_rule *rule; const struct inode *inode; @@ -224,7 +226,8 @@ static inline u64 unmask_layers(const st }
static int check_access_path(const struct landlock_ruleset *const domain, - const struct path *const path, u32 access_request) + const struct path *const path, + const access_mask_t access_request) { bool allowed = false; struct path walker_path; @@ -309,7 +312,7 @@ jump_up: }
static inline int current_check_access_path(const struct path *const path, - const u32 access_request) + const access_mask_t access_request) { const struct landlock_ruleset *const dom = landlock_get_current_domain(); @@ -512,7 +515,7 @@ static int hook_sb_pivotroot(const struc
/* Path hooks */
-static inline u32 get_mode_access(const umode_t mode) +static inline access_mask_t get_mode_access(const umode_t mode) { switch (mode & S_IFMT) { case S_IFLNK: @@ -565,7 +568,7 @@ static int hook_path_link(struct dentry get_mode_access(d_backing_inode(old_dentry)->i_mode)); }
-static inline u32 maybe_remove(const struct dentry *const dentry) +static inline access_mask_t maybe_remove(const struct dentry *const dentry) { if (d_is_negative(dentry)) return 0; @@ -635,9 +638,9 @@ static int hook_path_rmdir(const struct
/* File hooks */
-static inline u32 get_file_access(const struct file *const file) +static inline access_mask_t get_file_access(const struct file *const file) { - u32 access = 0; + access_mask_t access = 0;
if (file->f_mode & FMODE_READ) { /* A directory can only be opened in read mode. */ --- a/security/landlock/fs.h +++ b/security/landlock/fs.h @@ -66,6 +66,6 @@ __init void landlock_add_fs_hooks(void);
int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, const struct path *const path, - u32 access_hierarchy); + access_mask_t access_hierarchy);
#endif /* _SECURITY_LANDLOCK_FS_H */ --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -9,6 +9,7 @@ #ifndef _SECURITY_LANDLOCK_LIMITS_H #define _SECURITY_LANDLOCK_LIMITS_H
+#include <linux/bitops.h> #include <linux/limits.h> #include <uapi/linux/landlock.h>
@@ -19,6 +20,7 @@
#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_SYM #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1) +#define LANDLOCK_NUM_ACCESS_FS __const_hweight64(LANDLOCK_MASK_ACCESS_FS)
/* clang-format on */
--- a/security/landlock/ruleset.c +++ b/security/landlock/ruleset.c @@ -45,7 +45,8 @@ static struct landlock_ruleset *create_r return new_ruleset; }
-struct landlock_ruleset *landlock_create_ruleset(const u32 fs_access_mask) +struct landlock_ruleset * +landlock_create_ruleset(const access_mask_t fs_access_mask) { struct landlock_ruleset *new_ruleset;
@@ -228,7 +229,8 @@ static void build_check_layer(void)
/* @ruleset must be locked by the caller. */ int landlock_insert_rule(struct landlock_ruleset *const ruleset, - struct landlock_object *const object, const u32 access) + struct landlock_object *const object, + const access_mask_t access) { struct landlock_layer layers[] = { { .access = access, --- a/security/landlock/ruleset.h +++ b/security/landlock/ruleset.h @@ -9,13 +9,20 @@ #ifndef _SECURITY_LANDLOCK_RULESET_H #define _SECURITY_LANDLOCK_RULESET_H
+#include <linux/bitops.h> +#include <linux/build_bug.h> #include <linux/mutex.h> #include <linux/rbtree.h> #include <linux/refcount.h> #include <linux/workqueue.h>
+#include "limits.h" #include "object.h"
+typedef u16 access_mask_t; +/* Makes sure all filesystem access rights can be stored. */ +static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS); + /** * struct landlock_layer - Access rights for a given layer */ @@ -28,7 +35,7 @@ struct landlock_layer { * @access: Bitfield of allowed actions on the kernel object. They are * relative to the object type (e.g. %LANDLOCK_ACTION_FS_READ). */ - u16 access; + access_mask_t access; };
/** @@ -135,19 +142,20 @@ struct landlock_ruleset { * layers are set once and never changed for the * lifetime of the ruleset. */ - u16 fs_access_masks[]; + access_mask_t fs_access_masks[]; }; }; };
-struct landlock_ruleset *landlock_create_ruleset(const u32 fs_access_mask); +struct landlock_ruleset * +landlock_create_ruleset(const access_mask_t fs_access_mask);
void landlock_put_ruleset(struct landlock_ruleset *const ruleset); void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset);
int landlock_insert_rule(struct landlock_ruleset *const ruleset, struct landlock_object *const object, - const u32 access); + const access_mask_t access);
struct landlock_ruleset * landlock_merge_ruleset(struct landlock_ruleset *const parent,
From: Mickaël Salaün mic@digikod.net
commit 75c542d6c6cc48720376862d5496d51509160dfd upstream.
The maximum number of nested Landlock domains is currently 64. Because of the following fix and to help reduce the stack size, let's reduce it to 16. This seems large enough for a lot of use cases (e.g. sandboxed init service, spawning a sandboxed SSH service, in nested sandboxed containers). Reducing the number of nested domains may also help to discover misuse of Landlock (e.g. creating a domain per rule).
Add and use a dedicated layer_mask_t typedef to fit with the number of layers. This might be useful when changing it and to keep it consistent with the maximum number of layers.
Reviewed-by: Paul Moore paul@paul-moore.com Link: https://lore.kernel.org/r/20220506161102.525323-3-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/userspace-api/landlock.rst | 4 ++-- security/landlock/fs.c | 17 +++++++---------- security/landlock/limits.h | 2 +- security/landlock/ruleset.h | 4 ++++ tools/testing/selftests/landlock/fs_test.c | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-)
--- a/Documentation/userspace-api/landlock.rst +++ b/Documentation/userspace-api/landlock.rst @@ -267,8 +267,8 @@ restrict such paths with dedicated rules Ruleset layers --------------
-There is a limit of 64 layers of stacked rulesets. This can be an issue for a -task willing to enforce a new ruleset in complement to its 64 inherited +There is a limit of 16 layers of stacked rulesets. This can be an issue for a +task willing to enforce a new ruleset in complement to its 16 inherited rulesets. Once this limit is reached, sys_landlock_restrict_self() returns E2BIG. It is then strongly suggested to carefully build rulesets once in the life of a thread, especially for applications able to launch other applications --- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -183,10 +183,10 @@ int landlock_append_fs_rule(struct landl
/* Access-control management */
-static inline u64 unmask_layers(const struct landlock_ruleset *const domain, - const struct path *const path, - const access_mask_t access_request, - u64 layer_mask) +static inline layer_mask_t +unmask_layers(const struct landlock_ruleset *const domain, + const struct path *const path, const access_mask_t access_request, + layer_mask_t layer_mask) { const struct landlock_rule *rule; const struct inode *inode; @@ -212,11 +212,11 @@ static inline u64 unmask_layers(const st */ for (i = 0; i < rule->num_layers; i++) { const struct landlock_layer *const layer = &rule->layers[i]; - const u64 layer_level = BIT_ULL(layer->level - 1); + const layer_mask_t layer_bit = BIT_ULL(layer->level - 1);
/* Checks that the layer grants access to the full request. */ if ((layer->access & access_request) == access_request) { - layer_mask &= ~layer_level; + layer_mask &= ~layer_bit;
if (layer_mask == 0) return layer_mask; @@ -231,12 +231,9 @@ static int check_access_path(const struc { bool allowed = false; struct path walker_path; - u64 layer_mask; + layer_mask_t layer_mask; size_t i;
- /* Make sure all layers can be checked. */ - BUILD_BUG_ON(BITS_PER_TYPE(layer_mask) < LANDLOCK_MAX_NUM_LAYERS); - if (!access_request) return 0; if (WARN_ON_ONCE(!domain || !path)) --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -15,7 +15,7 @@
/* clang-format off */
-#define LANDLOCK_MAX_NUM_LAYERS 64 +#define LANDLOCK_MAX_NUM_LAYERS 16 #define LANDLOCK_MAX_NUM_RULES U32_MAX
#define LANDLOCK_LAST_ACCESS_FS LANDLOCK_ACCESS_FS_MAKE_SYM --- a/security/landlock/ruleset.h +++ b/security/landlock/ruleset.h @@ -23,6 +23,10 @@ typedef u16 access_mask_t; /* Makes sure all filesystem access rights can be stored. */ static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS);
+typedef u16 layer_mask_t; +/* Makes sure all layers can be checked. */ +static_assert(BITS_PER_TYPE(layer_mask_t) >= LANDLOCK_MAX_NUM_LAYERS); + /** * struct landlock_layer - Access rights for a given layer */ --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -1159,7 +1159,7 @@ TEST_F_FORK(layout1, max_layers) const int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, rules);
ASSERT_LE(0, ruleset_fd); - for (i = 0; i < 64; i++) + for (i = 0; i < 16; i++) enforce_ruleset(_metadata, ruleset_fd);
for (i = 0; i < 2; i++) {
From: Mickaël Salaün mic@digikod.net
commit 2cd7cd6eed88b8383cfddce589afe9c0ae1d19b4 upstream.
This refactoring will be useful in a following commit.
Reviewed-by: Paul Moore paul@paul-moore.com Link: https://lore.kernel.org/r/20220506161102.525323-4-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/landlock/fs.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-)
--- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -183,23 +183,36 @@ int landlock_append_fs_rule(struct landl
/* Access-control management */
-static inline layer_mask_t -unmask_layers(const struct landlock_ruleset *const domain, - const struct path *const path, const access_mask_t access_request, - layer_mask_t layer_mask) +/* + * The lifetime of the returned rule is tied to @domain. + * + * Returns NULL if no rule is found or if @dentry is negative. + */ +static inline const struct landlock_rule * +find_rule(const struct landlock_ruleset *const domain, + const struct dentry *const dentry) { const struct landlock_rule *rule; const struct inode *inode; - size_t i;
- if (d_is_negative(path->dentry)) - /* Ignore nonexistent leafs. */ - return layer_mask; - inode = d_backing_inode(path->dentry); + /* Ignores nonexistent leafs. */ + if (d_is_negative(dentry)) + return NULL; + + inode = d_backing_inode(dentry); rcu_read_lock(); rule = landlock_find_rule( domain, rcu_dereference(landlock_inode(inode)->object)); rcu_read_unlock(); + return rule; +} + +static inline layer_mask_t unmask_layers(const struct landlock_rule *const rule, + const access_mask_t access_request, + layer_mask_t layer_mask) +{ + size_t layer_level; + if (!rule) return layer_mask;
@@ -210,8 +223,9 @@ unmask_layers(const struct landlock_rule * the remaining layers for each inode, from the first added layer to * the last one. */ - for (i = 0; i < rule->num_layers; i++) { - const struct landlock_layer *const layer = &rule->layers[i]; + for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { + const struct landlock_layer *const layer = + &rule->layers[layer_level]; const layer_mask_t layer_bit = BIT_ULL(layer->level - 1);
/* Checks that the layer grants access to the full request. */ @@ -269,8 +283,9 @@ static int check_access_path(const struc while (true) { struct dentry *parent_dentry;
- layer_mask = unmask_layers(domain, &walker_path, access_request, - layer_mask); + layer_mask = + unmask_layers(find_rule(domain, walker_path.dentry), + access_request, layer_mask); if (layer_mask == 0) { /* Stops when a rule from each layer grants access. */ allowed = true;
From: Mickaël Salaün mic@digikod.net
commit 8ba0005ff418ec356e176b26eaa04a6ac755d05b upstream.
The original behavior was to check if the full set of requested accesses was allowed by at least a rule of every relevant layer. This didn't take into account requests for multiple accesses and same-layer rules allowing the union of these accesses in a complementary way. As a result, multiple accesses requested on a file hierarchy matching rules that, together, allowed these accesses, but without a unique rule allowing all of them, was illegitimately denied. This case should be rare in practice and it can only be triggered by the path_rename or file_open hook implementations.
For instance, if, for the same layer, a rule allows execution beneath /a/b and another rule allows read beneath /a, requesting access to read and execute at the same time for /a/b should be allowed for this layer.
This was an inconsistency because the union of same-layer rule accesses was already allowed if requested once at a time anyway.
This fix changes the way allowed accesses are gathered over a path walk. To take into account all these rule accesses, we store in a matrix all layer granting the set of requested accesses, according to the handled accesses. To avoid heap allocation, we use an array on the stack which is 2*13 bytes. A following commit bringing the LANDLOCK_ACCESS_FS_REFER access right will increase this size to reach 112 bytes (2*14*4) in case of link or rename actions.
Add a new layout1.layer_rule_unions test to check that accesses from different rules pertaining to the same layer are ORed in a file hierarchy. Also test that it is not the case for rules from different layers.
Reviewed-by: Paul Moore paul@paul-moore.com Link: https://lore.kernel.org/r/20220506161102.525323-5-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün mic@digikod.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/landlock/fs.c | 80 ++++++++++++++------- security/landlock/ruleset.h | 2 tools/testing/selftests/landlock/fs_test.c | 107 +++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 27 deletions(-)
--- a/security/landlock/fs.c +++ b/security/landlock/fs.c @@ -207,45 +207,67 @@ find_rule(const struct landlock_ruleset return rule; }
-static inline layer_mask_t unmask_layers(const struct landlock_rule *const rule, - const access_mask_t access_request, - layer_mask_t layer_mask) +/* + * @layer_masks is read and may be updated according to the access request and + * the matching rule. + * + * Returns true if the request is allowed (i.e. relevant layer masks for the + * request are empty). + */ +static inline bool +unmask_layers(const struct landlock_rule *const rule, + const access_mask_t access_request, + layer_mask_t (*const layer_masks)[LANDLOCK_NUM_ACCESS_FS]) { size_t layer_level;
+ if (!access_request || !layer_masks) + return true; if (!rule) - return layer_mask; + return false;
/* * An access is granted if, for each policy layer, at least one rule - * encountered on the pathwalk grants the requested accesses, - * regardless of their position in the layer stack. We must then check + * encountered on the pathwalk grants the requested access, + * regardless of its position in the layer stack. We must then check * the remaining layers for each inode, from the first added layer to - * the last one. + * the last one. When there is multiple requested accesses, for each + * policy layer, the full set of requested accesses may not be granted + * by only one rule, but by the union (binary OR) of multiple rules. + * E.g. /a/b <execute> + /a <read> => /a/b <execute + read> */ for (layer_level = 0; layer_level < rule->num_layers; layer_level++) { const struct landlock_layer *const layer = &rule->layers[layer_level]; const layer_mask_t layer_bit = BIT_ULL(layer->level - 1); - - /* Checks that the layer grants access to the full request. */ - if ((layer->access & access_request) == access_request) { - layer_mask &= ~layer_bit; - - if (layer_mask == 0) - return layer_mask; + const unsigned long access_req = access_request; + unsigned long access_bit; + bool is_empty; + + /* + * Records in @layer_masks which layer grants access to each + * requested access. + */ + is_empty = true; + for_each_set_bit(access_bit, &access_req, + ARRAY_SIZE(*layer_masks)) { + if (layer->access & BIT_ULL(access_bit)) + (*layer_masks)[access_bit] &= ~layer_bit; + is_empty = is_empty && !(*layer_masks)[access_bit]; } + if (is_empty) + return true; } - return layer_mask; + return false; }
static int check_access_path(const struct landlock_ruleset *const domain, const struct path *const path, const access_mask_t access_request) { - bool allowed = false; + layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; + bool allowed = false, has_access = false; struct path walker_path; - layer_mask_t layer_mask; size_t i;
if (!access_request) @@ -265,13 +287,20 @@ static int check_access_path(const struc return -EACCES;
/* Saves all layers handling a subset of requested accesses. */ - layer_mask = 0; for (i = 0; i < domain->num_layers; i++) { - if (domain->fs_access_masks[i] & access_request) - layer_mask |= BIT_ULL(i); + const unsigned long access_req = access_request; + unsigned long access_bit; + + for_each_set_bit(access_bit, &access_req, + ARRAY_SIZE(layer_masks)) { + if (domain->fs_access_masks[i] & BIT_ULL(access_bit)) { + layer_masks[access_bit] |= BIT_ULL(i); + has_access = true; + } + } } /* An access request not handled by the domain is allowed. */ - if (layer_mask == 0) + if (!has_access) return 0;
walker_path = *path; @@ -283,14 +312,11 @@ static int check_access_path(const struc while (true) { struct dentry *parent_dentry;
- layer_mask = - unmask_layers(find_rule(domain, walker_path.dentry), - access_request, layer_mask); - if (layer_mask == 0) { + allowed = unmask_layers(find_rule(domain, walker_path.dentry), + access_request, &layer_masks); + if (allowed) /* Stops when a rule from each layer grants access. */ - allowed = true; break; - }
jump_up: if (walker_path.dentry == walker_path.mnt->mnt_root) { --- a/security/landlock/ruleset.h +++ b/security/landlock/ruleset.h @@ -22,6 +22,8 @@ typedef u16 access_mask_t; /* Makes sure all filesystem access rights can be stored. */ static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS); +/* Makes sure for_each_set_bit() and for_each_clear_bit() calls are OK. */ +static_assert(sizeof(unsigned long) >= sizeof(access_mask_t));
typedef u16 layer_mask_t; /* Makes sure all layers can be checked. */ --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c @@ -758,6 +758,113 @@ TEST_F_FORK(layout1, ruleset_overlap) ASSERT_EQ(0, test_open(dir_s1d3, O_RDONLY | O_DIRECTORY)); }
+TEST_F_FORK(layout1, layer_rule_unions) +{ + const struct rule layer1[] = { + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE, + }, + /* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */ + { + .path = dir_s1d3, + .access = LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; + const struct rule layer2[] = { + /* Doesn't change anything from layer1. */ + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; + const struct rule layer3[] = { + /* Only allows write (but not read) to dir_s1d3. */ + { + .path = dir_s1d2, + .access = LANDLOCK_ACCESS_FS_WRITE_FILE, + }, + {}, + }; + int ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer1); + + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Checks s1d1 hierarchy with layer1. */ + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Checks s1d2 hierarchy with layer1. */ + ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Checks s1d3 hierarchy with layer1. */ + ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY)); + ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY)); + /* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */ + ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Doesn't change anything from layer1. */ + ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer2); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Checks s1d1 hierarchy with layer2. */ + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Checks s1d2 hierarchy with layer2. */ + ASSERT_EQ(0, test_open(file1_s1d2, O_RDONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Checks s1d3 hierarchy with layer2. */ + ASSERT_EQ(0, test_open(file1_s1d3, O_RDONLY)); + ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY)); + /* dir_s1d3 should allow READ_FILE and WRITE_FILE (O_RDWR). */ + ASSERT_EQ(0, test_open(file1_s1d3, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Only allows write (but not read) to dir_s1d3. */ + ruleset_fd = create_ruleset(_metadata, ACCESS_RW, layer3); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + ASSERT_EQ(0, close(ruleset_fd)); + + /* Checks s1d1 hierarchy with layer3. */ + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d1, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Checks s1d2 hierarchy with layer3. */ + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_WRONLY)); + ASSERT_EQ(EACCES, test_open(file1_s1d2, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); + + /* Checks s1d3 hierarchy with layer3. */ + ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDONLY)); + ASSERT_EQ(0, test_open(file1_s1d3, O_WRONLY)); + /* dir_s1d3 should now deny READ_FILE and WRITE_FILE (O_RDWR). */ + ASSERT_EQ(EACCES, test_open(file1_s1d3, O_RDWR)); + ASSERT_EQ(EACCES, test_open(dir_s1d1, O_RDONLY | O_DIRECTORY)); +} + TEST_F_FORK(layout1, non_overlapping_accesses) { const struct rule layer1[] = {
From: Dave Airlie airlied@redhat.com
commit 31ab27b14daaa75541a415c6794d6f3567fea44a upstream.
Submitting a cs with 0 chunks, causes an oops later, found trying to execute the wrong userspace driver.
MESA_LOADER_DRIVER_OVERRIDE=v3d glxinfo
[172536.665184] BUG: kernel NULL pointer dereference, address: 00000000000001d8 [172536.665188] #PF: supervisor read access in kernel mode [172536.665189] #PF: error_code(0x0000) - not-present page [172536.665191] PGD 6712a0067 P4D 6712a0067 PUD 5af9ff067 PMD 0 [172536.665195] Oops: 0000 [#1] SMP NOPTI [172536.665197] CPU: 7 PID: 2769838 Comm: glxinfo Tainted: P O 5.10.81 #1-NixOS [172536.665199] Hardware name: To be filled by O.E.M. To be filled by O.E.M./CROSSHAIR V FORMULA-Z, BIOS 2201 03/23/2015 [172536.665272] RIP: 0010:amdgpu_cs_ioctl+0x96/0x1ce0 [amdgpu] [172536.665274] Code: 75 18 00 00 4c 8b b2 88 00 00 00 8b 46 08 48 89 54 24 68 49 89 f7 4c 89 5c 24 60 31 d2 4c 89 74 24 30 85 c0 0f 85 c0 01 00 00 <48> 83 ba d8 01 00 00 00 48 8b b4 24 90 00 00 00 74 16 48 8b 46 10 [172536.665276] RSP: 0018:ffffb47c0e81bbe0 EFLAGS: 00010246 [172536.665277] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [172536.665278] RDX: 0000000000000000 RSI: ffffb47c0e81be28 RDI: ffffb47c0e81bd68 [172536.665279] RBP: ffff936524080010 R08: 0000000000000000 R09: ffffb47c0e81be38 [172536.665281] R10: ffff936524080010 R11: ffff936524080000 R12: ffffb47c0e81bc40 [172536.665282] R13: ffffb47c0e81be28 R14: ffff9367bc410000 R15: ffffb47c0e81be28 [172536.665283] FS: 00007fe35e05d740(0000) GS:ffff936c1edc0000(0000) knlGS:0000000000000000 [172536.665284] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [172536.665286] CR2: 00000000000001d8 CR3: 0000000532e46000 CR4: 00000000000406e0 [172536.665287] Call Trace: [172536.665322] ? amdgpu_cs_find_mapping+0x110/0x110 [amdgpu] [172536.665332] drm_ioctl_kernel+0xaa/0xf0 [drm] [172536.665338] drm_ioctl+0x201/0x3b0 [drm] [172536.665369] ? amdgpu_cs_find_mapping+0x110/0x110 [amdgpu] [172536.665372] ? selinux_file_ioctl+0x135/0x230 [172536.665399] amdgpu_drm_ioctl+0x49/0x80 [amdgpu] [172536.665403] __x64_sys_ioctl+0x83/0xb0 [172536.665406] do_syscall_64+0x33/0x40 [172536.665409] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2018 Signed-off-by: Dave Airlie airlied@redhat.com Cc: stable@vger.kernel.org Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -116,7 +116,7 @@ static int amdgpu_cs_parser_init(struct int ret;
if (cs->in.num_chunks == 0) - return 0; + return -EINVAL;
chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL); if (!chunk_array)
From: Lyude Paul lyude@redhat.com
commit 9887bda0c831df0c044d6de147d002e48024fb4a upstream.
There's plenty of ways to fudge the GPU when developing on nouveau by mistake, some of which can result in nouveau seriously spamming dmesg with fault errors. This can be somewhat annoying, as it can quickly overrun the message buffer (or your terminal emulator's buffer) and get rid of actually useful feedback from the driver. While working on my new atomic only MST branch, I ran into this issue a couple of times.
So, let's fix this by adding nvkm_error_ratelimited(), and using it to ratelimit errors from faults. This should be fine for developers, since it's nearly always only the first few faults that we care about seeing. Plus, you can turn off rate limiting in the kernel if you really need to.
Signed-off-by: Lyude Paul lyude@redhat.com Reviewed-by: Karol Herbst kherbst@redhat.com Cc: stable@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20220429195350.85620-1-lyude@r... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 2 ++ drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c | 14 +++++++------- drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c | 6 +++--- drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-)
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h @@ -62,4 +62,6 @@ void nvkm_subdev_intr(struct nvkm_subdev #define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG, info, f, ##a) #define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE, info, f, ##a) #define nvkm_spam(s,f,a...) nvkm_printk((s), SPAM, dbg, f, ##a) + +#define nvkm_error_ratelimited(s,f,a...) nvkm_printk((s), ERROR, err_ratelimited, f, ##a) #endif --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/gf100.c @@ -35,13 +35,13 @@ gf100_bus_intr(struct nvkm_bus *bus) u32 addr = nvkm_rd32(device, 0x009084); u32 data = nvkm_rd32(device, 0x009088);
- nvkm_error(subdev, - "MMIO %s of %08x FAULT at %06x [ %s%s%s]\n", - (addr & 0x00000002) ? "write" : "read", data, - (addr & 0x00fffffc), - (stat & 0x00000002) ? "!ENGINE " : "", - (stat & 0x00000004) ? "PRIVRING " : "", - (stat & 0x00000008) ? "TIMEOUT " : ""); + nvkm_error_ratelimited(subdev, + "MMIO %s of %08x FAULT at %06x [ %s%s%s]\n", + (addr & 0x00000002) ? "write" : "read", data, + (addr & 0x00fffffc), + (stat & 0x00000002) ? "!ENGINE " : "", + (stat & 0x00000004) ? "PRIVRING " : "", + (stat & 0x00000008) ? "TIMEOUT " : "");
nvkm_wr32(device, 0x009084, 0x00000000); nvkm_wr32(device, 0x001100, (stat & 0x0000000e)); --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv31.c @@ -45,9 +45,9 @@ nv31_bus_intr(struct nvkm_bus *bus) u32 addr = nvkm_rd32(device, 0x009084); u32 data = nvkm_rd32(device, 0x009088);
- nvkm_error(subdev, "MMIO %s of %08x FAULT at %06x\n", - (addr & 0x00000002) ? "write" : "read", data, - (addr & 0x00fffffc)); + nvkm_error_ratelimited(subdev, "MMIO %s of %08x FAULT at %06x\n", + (addr & 0x00000002) ? "write" : "read", data, + (addr & 0x00fffffc));
stat &= ~0x00000008; nvkm_wr32(device, 0x001100, 0x00000008); --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv50.c @@ -60,9 +60,9 @@ nv50_bus_intr(struct nvkm_bus *bus) u32 addr = nvkm_rd32(device, 0x009084); u32 data = nvkm_rd32(device, 0x009088);
- nvkm_error(subdev, "MMIO %s of %08x FAULT at %06x\n", - (addr & 0x00000002) ? "write" : "read", data, - (addr & 0x00fffffc)); + nvkm_error_ratelimited(subdev, "MMIO %s of %08x FAULT at %06x\n", + (addr & 0x00000002) ? "write" : "read", data, + (addr & 0x00fffffc));
stat &= ~0x00000008; nvkm_wr32(device, 0x001100, 0x00000008);
From: Lucas Stach l.stach@pengutronix.de
commit e168c25526cd0368af098095c2ded4a008007e1b upstream.
When the mapping is already reaped the unmap must be a no-op, as we would otherwise try to remove the mapping twice, corrupting the involved data structures.
Cc: stable@vger.kernel.org # 5.4 Signed-off-by: Lucas Stach l.stach@pengutronix.de Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Tested-by: Guido Günther agx@sigxcpu.org Acked-by: Guido Günther agx@sigxcpu.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -286,6 +286,12 @@ void etnaviv_iommu_unmap_gem(struct etna
mutex_lock(&context->lock);
+ /* Bail if the mapping has been reaped by another thread */ + if (!mapping->context) { + mutex_unlock(&context->lock); + return; + } + /* If the vram node is on the mm, unmap and remove the node */ if (mapping->vram_node.mm == &context->mm) etnaviv_iommu_remove_mapping(context, mapping);
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 1c3b2a27def609473ed13b1cd668cb10deab49b4 upstream.
The bug is here: if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp)) return cstate;
The list iterator value 'cstate' will *always* be set and non-NULL by list_for_each_entry_from_reverse(), so it is incorrect to assume that the iterator value will be unchanged if the list is empty or no element is found (In fact, it will be a bogus pointer to an invalid structure object containing the HEAD). Also it missed a NULL check at callsite and may lead to invalid memory access after that.
To fix this bug, just return 'encoder' when found, otherwise return NULL. And add the NULL check.
Cc: stable@vger.kernel.org Fixes: 1f7f3d91ad38a ("drm/nouveau/clk: Respect voltage limits in nvkm_cstate_prog") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Reviewed-by: Lyude Paul lyude@redhat.com Signed-off-by: Lyude Paul lyude@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220327075824.11806-1-xiam0nd... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -135,10 +135,10 @@ nvkm_cstate_find_best(struct nvkm_clk *c
list_for_each_entry_from_reverse(cstate, &pstate->list, head) { if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp)) - break; + return cstate; }
- return cstate; + return NULL; }
static struct nvkm_cstate * @@ -169,6 +169,8 @@ nvkm_cstate_prog(struct nvkm_clk *clk, s if (!list_empty(&pstate->list)) { cstate = nvkm_cstate_get(clk, pstate, cstatei); cstate = nvkm_cstate_find_best(clk, pstate, cstate); + if (!cstate) + return -EINVAL; } else { cstate = &pstate->base; }
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 6ce4431c7ba7954c4fa6a96ce16ca1b2943e1a83 upstream.
The bug is here: return encoder;
The list iterator value 'encoder' will *always* be set and non-NULL by drm_for_each_encoder_mask(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element found. Otherwise it will bypass some NULL checks and lead to invalid memory access passing the check.
To fix this bug, just return 'encoder' when found, otherwise return NULL.
Cc: stable@vger.kernel.org Fixes: 12885ecbfe62d ("drm/nouveau/kms/nvd9-: Add CRC support") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Reviewed-by: Lyude Paul lyude@redhat.com [Changed commit title] Signed-off-by: Lyude Paul lyude@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20220327073925.11121-1-xiam0nd... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/dispnv50/atom.h | 6 +++--- drivers/gpu/drm/nouveau/dispnv50/crc.c | 27 ++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -160,14 +160,14 @@ nv50_head_atom_get(struct drm_atomic_sta static inline struct drm_encoder * nv50_head_atom_get_encoder(struct nv50_head_atom *atom) { - struct drm_encoder *encoder = NULL; + struct drm_encoder *encoder;
/* We only ever have a single encoder */ drm_for_each_encoder_mask(encoder, atom->state.crtc->dev, atom->state.encoder_mask) - break; + return encoder;
- return encoder; + return NULL; }
#define nv50_wndw_atom(p) container_of((p), struct nv50_wndw_atom, state) --- a/drivers/gpu/drm/nouveau/dispnv50/crc.c +++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c @@ -390,9 +390,18 @@ void nv50_crc_atomic_check_outp(struct n struct nv50_head_atom *armh = nv50_head_atom(old_crtc_state); struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); struct nv50_outp_atom *outp_atom; - struct nouveau_encoder *outp = - nv50_real_outp(nv50_head_atom_get_encoder(armh)); - struct drm_encoder *encoder = &outp->base.base; + struct nouveau_encoder *outp; + struct drm_encoder *encoder, *enc; + + enc = nv50_head_atom_get_encoder(armh); + if (!enc) + continue; + + outp = nv50_real_outp(enc); + if (!outp) + continue; + + encoder = &outp->base.base;
if (!asyh->clr.crc) continue; @@ -443,8 +452,16 @@ void nv50_crc_atomic_set(struct nv50_hea struct drm_device *dev = crtc->dev; struct nv50_crc *crc = &head->crc; const struct nv50_crc_func *func = nv50_disp(dev)->core->func->crc; - struct nouveau_encoder *outp = - nv50_real_outp(nv50_head_atom_get_encoder(asyh)); + struct nouveau_encoder *outp; + struct drm_encoder *encoder; + + encoder = nv50_head_atom_get_encoder(asyh); + if (!encoder) + return; + + outp = nv50_real_outp(encoder); + if (!outp) + return;
func->set_src(head, outp->or, nv50_crc_source_type(outp, asyh->crc.src), &crc->ctx[crc->ctx_idx]);
From: Brian Norris briannorris@chromium.org
commit 8fb6c44fe8468f92ac7b8bbfcca4404a4e88645f upstream.
If the display is not enable()d, then we aren't holding a runtime PM reference here. Thus, it's easy to accidentally cause a hang, if user space is poking around at /dev/drm_dp_aux0 at the "wrong" time.
Let's get a runtime PM reference, and check that we "see" the panel. Don't force any panel power-up, etc., because that can be intrusive, and that's not what other drivers do (see drivers/gpu/drm/bridge/ti-sn65dsi86.c and drivers/gpu/drm/bridge/parade-ps8640.c.)
Fixes: 0d97ad03f422 ("drm/bridge: analogix_dp: Remove duplicated code") Cc: stable@vger.kernel.org Cc: Tomeu Vizoso tomeu.vizoso@collabora.com Signed-off-by: Brian Norris briannorris@chromium.org Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20220301181107.v4.1.I773a08785... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1632,8 +1632,19 @@ static ssize_t analogix_dpaux_transfer(s struct drm_dp_aux_msg *msg) { struct analogix_dp_device *dp = to_dp(aux); + int ret;
- return analogix_dp_transfer(dp, msg); + pm_runtime_get_sync(dp->dev); + + ret = analogix_dp_detect_hpd(dp); + if (ret) + goto out; + + ret = analogix_dp_transfer(dp, msg); +out: + pm_runtime_put(dp->dev); + + return ret; }
struct analogix_dp_device *
From: Jani Nikula jani.nikula@intel.com
commit 0ea917819d12fed41ea4662cc26ffa0060a5c354 upstream.
The VBT send packet port selection was never updated for ICL+ where the 2nd link is on port B instead of port C as in VLV+ DSI.
First, single link DSI needs to use the configured port instead of relying on the VBT sequence block port. Remove the hard-coded port C check here and make it generic. For reference, see commit f915084edc5a ("drm/i915: Changes related to the sequence port no for") for the original VLV specific fix.
Second, the sequence block port number is either 0 or 1, where 1 indicates the 2nd link. Remove the hard-coded port C here for 2nd link. (This could be a "find second set bit" on DSI ports, but just check the two possible options.)
Third, sanity check the result with a warning to avoid a NULL pointer dereference.
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5984 Cc: stable@vger.kernel.org # v4.19+ Cc: Ville Syrjala 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/20220520094600.2066945-1-jani.... (cherry picked from commit 08c59dde71b73a0ac94e3ed2d431345b01f20485) Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-)
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -124,9 +124,25 @@ struct i2c_adapter_lookup { #define ICL_GPIO_DDPA_CTRLCLK_2 8 #define ICL_GPIO_DDPA_CTRLDATA_2 9
-static enum port intel_dsi_seq_port_to_port(u8 port) +static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi, + u8 seq_port) { - return port ? PORT_C : PORT_A; + /* + * If single link DSI is being used on any port, the VBT sequence block + * send packet apparently always has 0 for the port. Just use the port + * we have configured, and ignore the sequence block port. + */ + if (hweight8(intel_dsi->ports) == 1) + return ffs(intel_dsi->ports) - 1; + + if (seq_port) { + if (intel_dsi->ports & PORT_B) + return PORT_B; + else if (intel_dsi->ports & PORT_C) + return PORT_C; + } + + return PORT_A; }
static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, @@ -148,15 +164,10 @@ static const u8 *mipi_exec_send_packet(s
seq_port = (flags >> MIPI_PORT_SHIFT) & 3;
- /* For DSI single link on Port A & C, the seq_port value which is - * parsed from Sequence Block#53 of VBT has been set to 0 - * Now, read/write of packets for the DSI single link on Port A and - * Port C will based on the DVO port from VBT block 2. - */ - if (intel_dsi->ports == (1 << PORT_C)) - port = PORT_C; - else - port = intel_dsi_seq_port_to_port(seq_port); + port = intel_dsi_seq_port_to_port(intel_dsi, seq_port); + + if (drm_WARN_ON(&dev_priv->drm, !intel_dsi->dsi_hosts[port])) + goto out;
dsi_device = intel_dsi->dsi_hosts[port]->device; if (!dsi_device) {
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit fc8738343eefc4ea8afb6122826dea48eacde514 upstream.
The bug is here: if (!rdev)
The list iterator value 'rdev' will *always* be set and non-NULL by rdev_for_each(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element found. Otherwise it will bypass the NULL check and lead to invalid memory access passing the check.
To fix the bug, use a new variable 'iter' as the list iterator, while using the original variable 'rdev' as a dedicated pointer to point to the found element.
Cc: stable@vger.kernel.org Fixes: 2aa82191ac36 ("md-cluster: Perform a lazy update") Acked-by: Guoqing Jiang guoqing.jiang@linux.dev Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Acked-by: Goldwyn Rodrigues rgoldwyn@suse.com Signed-off-by: Song Liu song@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/md.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2627,14 +2627,16 @@ static void sync_sbs(struct mddev *mddev
static bool does_sb_need_changing(struct mddev *mddev) { - struct md_rdev *rdev; + struct md_rdev *rdev = NULL, *iter; struct mdp_superblock_1 *sb; int role;
/* Find a good rdev */ - rdev_for_each(rdev, mddev) - if ((rdev->raid_disk >= 0) && !test_bit(Faulty, &rdev->flags)) + rdev_for_each(iter, mddev) + if ((iter->raid_disk >= 0) && !test_bit(Faulty, &iter->flags)) { + rdev = iter; break; + }
/* No good device found. */ if (!rdev)
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 64c54d9244a4efe9bc6e9c98e13c4bbb8bb39083 upstream.
The bug is here: if (!rdev || rdev->desc_nr != nr) {
The list iterator value 'rdev' will *always* be set and non-NULL by rdev_for_each_rcu(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element found (In fact, it will be a bogus pointer to an invalid struct object containing the HEAD). Otherwise it will bypass the check and lead to invalid memory access passing the check.
To fix the bug, use a new variable 'iter' as the list iterator, while using the original variable 'pdev' as a dedicated pointer to point to the found element.
Cc: stable@vger.kernel.org Fixes: 70bcecdb1534 ("md-cluster: Improve md_reload_sb to be less error prone") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Signed-off-by: Song Liu song@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/md.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -9793,16 +9793,18 @@ static int read_rdev(struct mddev *mddev
void md_reload_sb(struct mddev *mddev, int nr) { - struct md_rdev *rdev; + struct md_rdev *rdev = NULL, *iter; int err;
/* Find the rdev */ - rdev_for_each_rcu(rdev, mddev) { - if (rdev->desc_nr == nr) + rdev_for_each_rcu(iter, mddev) { + if (iter->desc_nr == nr) { + rdev = iter; break; + } }
- if (!rdev || rdev->desc_nr != nr) { + if (!rdev) { pr_warn("%s: %d Could not find rdev with nr %d\n", __func__, __LINE__, nr); return; }
From: Tokunori Ikegami ikegami.t@gmail.com
commit 083084df578a8bdb18334f69e7b32d690aaa3247 upstream.
This is a preparation patch for the S29GL064N buffer writes fix. There is no functional change.
Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.d... Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value") Signed-off-by: Tokunori Ikegami ikegami.t@gmail.com Cc: stable@vger.kernel.org Acked-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220323170458.5608-2-ikegami.t@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/chips/cfi_cmdset_0002.c | 95 ++++++++++++------------------------ 1 file changed, 32 insertions(+), 63 deletions(-)
--- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -802,21 +802,25 @@ static struct mtd_info *cfi_amdstd_setup }
/* - * Return true if the chip is ready. + * Return true if the chip is ready and has the correct value. * * Ready is one of: read mode, query mode, erase-suspend-read mode (in any * non-suspended sector) and is indicated by no toggle bits toggling. * + * Error are indicated by toggling bits or bits held with the wrong value, + * or with bits toggling. + * * Note that anything more complicated than checking if no bits are toggling * (including checking DQ5 for an error status) is tricky to get working * correctly and is therefore not done (particularly with interleaved chips * as each chip must be checked independently of the others). */ static int __xipram chip_ready(struct map_info *map, struct flchip *chip, - unsigned long addr) + unsigned long addr, map_word *expected) { struct cfi_private *cfi = map->fldrv_priv; map_word d, t; + int ret;
if (cfi_use_status_reg(cfi)) { map_word ready = CMD(CFI_SR_DRB); @@ -826,57 +830,20 @@ static int __xipram chip_ready(struct ma */ cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); - d = map_read(map, addr); + t = map_read(map, addr);
- return map_word_andequal(map, d, ready, ready); + return map_word_andequal(map, t, ready, ready); }
d = map_read(map, addr); t = map_read(map, addr);
- return map_word_equal(map, d, t); -} - -/* - * Return true if the chip is ready and has the correct value. - * - * Ready is one of: read mode, query mode, erase-suspend-read mode (in any - * non-suspended sector) and it is indicated by no bits toggling. - * - * Error are indicated by toggling bits or bits held with the wrong value, - * or with bits toggling. - * - * Note that anything more complicated than checking if no bits are toggling - * (including checking DQ5 for an error status) is tricky to get working - * correctly and is therefore not done (particularly with interleaved chips - * as each chip must be checked independently of the others). - * - */ -static int __xipram chip_good(struct map_info *map, struct flchip *chip, - unsigned long addr, map_word expected) -{ - struct cfi_private *cfi = map->fldrv_priv; - map_word oldd, curd; - - if (cfi_use_status_reg(cfi)) { - map_word ready = CMD(CFI_SR_DRB); - - /* - * For chips that support status register, check device - * ready bit - */ - cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi, - cfi->device_type, NULL); - curd = map_read(map, addr); - - return map_word_andequal(map, curd, ready, ready); - } + ret = map_word_equal(map, d, t);
- oldd = map_read(map, addr); - curd = map_read(map, addr); + if (!ret || !expected) + return ret;
- return map_word_equal(map, oldd, curd) && - map_word_equal(map, curd, expected); + return map_word_equal(map, t, *expected); }
static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) @@ -893,7 +860,7 @@ static int get_chip(struct map_info *map
case FL_STATUS: for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break;
if (time_after(jiffies, timeo)) { @@ -932,7 +899,7 @@ static int get_chip(struct map_info *map chip->state = FL_ERASE_SUSPENDING; chip->erase_suspended = 1; for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break;
if (time_after(jiffies, timeo)) { @@ -1463,7 +1430,7 @@ static int do_otp_lock(struct map_info * /* wait for chip to become ready */ timeo = jiffies + msecs_to_jiffies(2); for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break;
if (time_after(jiffies, timeo)) { @@ -1695,11 +1662,11 @@ static int __xipram do_write_oneword_onc }
/* - * We check "time_after" and "!chip_good" before checking - * "chip_good" to avoid the failure due to scheduling. + * We check "time_after" and "!chip_ready" before checking + * "chip_ready" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_good(map, chip, adr, datum)) { + !chip_ready(map, chip, adr, &datum)) { xip_enable(map, chip, adr); printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); xip_disable(map, chip, adr); @@ -1707,7 +1674,7 @@ static int __xipram do_write_oneword_onc break; }
- if (chip_good(map, chip, adr, datum)) { + if (chip_ready(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -1975,18 +1942,18 @@ static int __xipram do_write_buffer_wait }
/* - * We check "time_after" and "!chip_good" before checking - * "chip_good" to avoid the failure due to scheduling. + * We check "time_after" and "!chip_ready" before checking + * "chip_ready" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_good(map, chip, adr, datum)) { + !chip_ready(map, chip, adr, &datum)) { pr_err("MTD %s(): software timeout, address:0x%.8lx.\n", __func__, adr); ret = -EIO; break; }
- if (chip_good(map, chip, adr, datum)) { + if (chip_ready(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -2195,7 +2162,7 @@ static int cfi_amdstd_panic_wait(struct * If the driver thinks the chip is idle, and no toggle bits * are changing, then the chip is actually idle for sure. */ - if (chip->state == FL_READY && chip_ready(map, chip, adr)) + if (chip->state == FL_READY && chip_ready(map, chip, adr, NULL)) return 0;
/* @@ -2212,7 +2179,7 @@ static int cfi_amdstd_panic_wait(struct
/* wait for the chip to become ready */ for (i = 0; i < jiffies_to_usecs(timeo); i++) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) return 0;
udelay(1); @@ -2276,13 +2243,13 @@ retry: map_write(map, datum, adr);
for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break;
udelay(1); }
- if (!chip_good(map, chip, adr, datum) || + if (!chip_ready(map, chip, adr, &datum) || cfi_check_err_status(map, chip, adr)) { /* reset on all failures. */ map_write(map, CMD(0xF0), chip->start); @@ -2424,6 +2391,7 @@ static int __xipram do_erase_chip(struct DECLARE_WAITQUEUE(wait, current); int ret; int retry_cnt = 0; + map_word datum = map_word_ff(map);
adr = cfi->addr_unlock1;
@@ -2478,7 +2446,7 @@ static int __xipram do_erase_chip(struct chip->erase_suspended = 0; }
- if (chip_good(map, chip, adr, map_word_ff(map))) { + if (chip_ready(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -2523,6 +2491,7 @@ static int __xipram do_erase_oneblock(st DECLARE_WAITQUEUE(wait, current); int ret; int retry_cnt = 0; + map_word datum = map_word_ff(map);
adr += chip->start;
@@ -2577,7 +2546,7 @@ static int __xipram do_erase_oneblock(st chip->erase_suspended = 0; }
- if (chip_good(map, chip, adr, map_word_ff(map))) { + if (chip_ready(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -2771,7 +2740,7 @@ static int __maybe_unused do_ppb_xxlock( */ timeo = jiffies + msecs_to_jiffies(2000); /* 2s max (un)locking */ for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break;
if (time_after(jiffies, timeo)) {
From: Tokunori Ikegami ikegami.t@gmail.com
commit 0a8e98305f63deaf0a799d5cf5532cc83af035d1 upstream.
Since commit dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value") buffered writes fail on S29GL064N. This is because, on S29GL064N, reads return 0xFF at the end of DQ polling for write completion, where as, chip_good() check expects actual data written to the last location to be returned post DQ polling completion. Fix is to revert to using chip_good() for S29GL064N which only checks for DQ lines to settle down to determine write completion.
Link: https://lore.kernel.org/r/b687c259-6413-26c9-d4c9-b3afa69ea124@pengutronix.d... Fixes: dfeae1073583("mtd: cfi_cmdset_0002: Change write buffer to check correct value") Cc: stable@vger.kernel.org Signed-off-by: Tokunori Ikegami ikegami.t@gmail.com Acked-by: Vignesh Raghavendra vigneshr@ti.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20220323170458.5608-3-ikegami.t@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/chips/cfi_cmdset_0002.c | 42 +++++++++++++++++++++++++++++------- include/linux/mtd/cfi.h | 1 2 files changed, 35 insertions(+), 8 deletions(-)
--- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -59,6 +59,10 @@ #define CFI_SR_WBASB BIT(3) #define CFI_SR_SLSB BIT(1)
+enum cfi_quirks { + CFI_QUIRK_DQ_TRUE_DATA = BIT(0), +}; + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); #if !FORCE_WORD_WRITE @@ -436,6 +440,15 @@ static void fixup_s29ns512p_sectors(stru mtd->name); }
+static void fixup_quirks(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + if (cfi->mfr == CFI_MFR_AMD && cfi->id == 0x0c01) + cfi->quirks |= CFI_QUIRK_DQ_TRUE_DATA; +} + /* Used to fix CFI-Tables of chips without Extended Query Tables */ static struct cfi_fixup cfi_nopri_fixup_table[] = { { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */ @@ -474,6 +487,7 @@ static struct cfi_fixup cfi_fixup_table[ #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers }, #endif + { CFI_MFR_ANY, CFI_ID_ANY, fixup_quirks }, { 0, 0, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { @@ -846,6 +860,18 @@ static int __xipram chip_ready(struct ma return map_word_equal(map, t, *expected); }
+static int __xipram chip_good(struct map_info *map, struct flchip *chip, + unsigned long addr, map_word *expected) +{ + struct cfi_private *cfi = map->fldrv_priv; + map_word *datum = expected; + + if (cfi->quirks & CFI_QUIRK_DQ_TRUE_DATA) + datum = NULL; + + return chip_ready(map, chip, addr, datum); +} + static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) { DECLARE_WAITQUEUE(wait, current); @@ -1662,11 +1688,11 @@ static int __xipram do_write_oneword_onc }
/* - * We check "time_after" and "!chip_ready" before checking - * "chip_ready" to avoid the failure due to scheduling. + * We check "time_after" and "!chip_good" before checking + * "chip_good" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_ready(map, chip, adr, &datum)) { + !chip_good(map, chip, adr, &datum)) { xip_enable(map, chip, adr); printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); xip_disable(map, chip, adr); @@ -1674,7 +1700,7 @@ static int __xipram do_write_oneword_onc break; }
- if (chip_ready(map, chip, adr, &datum)) { + if (chip_good(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; @@ -1942,18 +1968,18 @@ static int __xipram do_write_buffer_wait }
/* - * We check "time_after" and "!chip_ready" before checking - * "chip_ready" to avoid the failure due to scheduling. + * We check "time_after" and "!chip_good" before checking + * "chip_good" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_ready(map, chip, adr, &datum)) { + !chip_good(map, chip, adr, &datum)) { pr_err("MTD %s(): software timeout, address:0x%.8lx.\n", __func__, adr); ret = -EIO; break; }
- if (chip_ready(map, chip, adr, &datum)) { + if (chip_good(map, chip, adr, &datum)) { if (cfi_check_err_status(map, chip, adr)) ret = -EIO; break; --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -286,6 +286,7 @@ struct cfi_private { map_word sector_erase_cmd; unsigned long chipshift; /* Because they're of the same type */ const char *im_name; /* inter_module name for cmdset_setup */ + unsigned long quirks; struct flchip chips[]; /* per-chip data structure for each chip */ };
From: Nicolas Dufresne nicolas.dufresne@collabora.com
commit 7110c08ea71953a7fc342f0b76046f72442cf26c upstream.
The CODA960 manual states that ASO/FMO features of baseline are not supported, so for this reason this driver should only report constrained baseline support.
This fixes negotiation issue with constrained baseline content on GStreamer 1.17.1.
ASO/FMO features are unsupported for the encoder and untested for the decoder because there is currently no userspace support. Neither GStreamer parsers nor FFMPEG parsers support ASO/FMO.
Cc: stable@vger.kernel.org Fixes: 42a68012e67c2 ("media: coda: add read-only h.264 decoder profile/level controls") Signed-off-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Tested-by: Pascal Speck kernel@iktek.de Signed-off-by: Fabio Estevam festevam@denx.de Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/platform/chips-media/coda-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/media/platform/chips-media/coda-common.c +++ b/drivers/media/platform/chips-media/coda-common.c @@ -2352,8 +2352,8 @@ static void coda_encode_ctrls(struct cod V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, -12, 12, 1, 0); v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, - V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 0x0, - V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE, 0x0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE); if (ctx->dev->devtype->product == CODA_HX4 || ctx->dev->devtype->product == CODA_7541) { v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, @@ -2434,7 +2434,7 @@ static void coda_decode_ctrls(struct cod ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, - ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
From: Nicolas Dufresne nicolas.dufresne@collabora.com
commit eb2fd187abc878a2dfad46902becb74963473c7d upstream.
Add H264 level 1.0, 4.1, 4.2 to the list of supported formats. While the hardware does not fully support these levels, it does support most of them. The constraints on frame size and pixel formats already cover the limitation.
This fixes negotiation of level on GStreamer 1.17.1.
Cc: stable@vger.kernel.org Fixes: 42a68012e67c2 ("media: coda: add read-only h.264 decoder profile/level controls") Suggested-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Ezequiel Garcia ezequiel@collabora.com Signed-off-by: Fabio Estevam festevam@denx.de Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/platform/chips-media/coda-common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/media/platform/chips-media/coda-common.c +++ b/drivers/media/platform/chips-media/coda-common.c @@ -2367,12 +2367,15 @@ static void coda_encode_ctrls(struct cod if (ctx->dev->devtype->product == CODA_960) { v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, - V4L2_MPEG_VIDEO_H264_LEVEL_4_0, - ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), V4L2_MPEG_VIDEO_H264_LEVEL_4_0); } v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
From: GUO Zihua guozihua@huawei.com
commit 891163adf180bc369b2f11c9dfce6d2758d2a5bd upstream.
The original 'ima' measurement list template contains a hash, defined as 20 bytes, and a null terminated pathname, limited to 255 characters. Other measurement list templates permit both larger hashes and longer pathnames. When the "ima" template is configured as the default, a new measurement list template (ima_template=) must be specified before specifying a larger hash algorithm (ima_hash=) on the boot command line.
To avoid this boot command line ordering issue, remove the legacy "ima" template configuration option, allowing it to still be specified on the boot command line.
The root cause of this issue is that during the processing of ima_hash, we would try to check whether the hash algorithm is compatible with the template. If the template is not set at the moment we do the check, we check the algorithm against the configured default template. If the default template is "ima", then we reject any hash algorithm other than sha1 and md5.
For example, if the compiled default template is "ima", and the default algorithm is sha1 (which is the current default). In the cmdline, we put in "ima_hash=sha256 ima_template=ima-ng". The expected behavior would be that ima starts with ima-ng as the template and sha256 as the hash algorithm. However, during the processing of "ima_hash=", "ima_template=" has not been processed yet, and hash_setup would check the configured hash algorithm against the compiled default: ima, and reject sha256. So at the end, the hash algorithm that is actually used will be sha1.
With template "ima" removed from the configured default, we ensure that the default tempalte would at least be "ima-ng" which allows for basically any hash algorithm.
This change would not break the algorithm compatibility checks for IMA.
Fixes: 4286587dccd43 ("ima: add Kconfig default measurement list template") Signed-off-by: GUO Zihua guozihua@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/integrity/ima/Kconfig | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
--- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -69,10 +69,9 @@ choice hash, defined as 20 bytes, and a null terminated pathname, limited to 255 characters. The 'ima-ng' measurement list template permits both larger hash digests and longer - pathnames. + pathnames. The configured default template can be replaced + by specifying "ima_template=" on the boot command line.
- config IMA_TEMPLATE - bool "ima" config IMA_NG_TEMPLATE bool "ima-ng (default)" config IMA_SIG_TEMPLATE @@ -82,7 +81,6 @@ endchoice config IMA_DEFAULT_TEMPLATE string depends on IMA - default "ima" if IMA_TEMPLATE default "ima-ng" if IMA_NG_TEMPLATE default "ima-sig" if IMA_SIG_TEMPLATE
@@ -102,19 +100,19 @@ choice
config IMA_DEFAULT_HASH_SHA256 bool "SHA256" - depends on CRYPTO_SHA256=y && !IMA_TEMPLATE + depends on CRYPTO_SHA256=y
config IMA_DEFAULT_HASH_SHA512 bool "SHA512" - depends on CRYPTO_SHA512=y && !IMA_TEMPLATE + depends on CRYPTO_SHA512=y
config IMA_DEFAULT_HASH_WP512 bool "WP512" - depends on CRYPTO_WP512=y && !IMA_TEMPLATE + depends on CRYPTO_WP512=y
config IMA_DEFAULT_HASH_SM3 bool "SM3" - depends on CRYPTO_SM3=y && !IMA_TEMPLATE + depends on CRYPTO_SM3=y endchoice
config IMA_DEFAULT_HASH
From: Sean Christopherson seanjc@google.com
commit 1aa0e8b144b6474c4914439d232d15bfe883636b upstream.
Add a config option to guard (future) usage of asm_volatile_goto() that includes "tied outputs", i.e. "+" constraints that specify both an input and output parameter. clang-13 has a bug[1] that causes compilation of such inline asm to fail, and KVM wants to use a "+m" constraint to implement a uaccess form of CMPXCHG[2]. E.g. the test code fails with
<stdin>:1:29: error: invalid operand in inline asm: '.long (${1:l}) - .' int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; } ^ <stdin>:1:29: error: unknown token in expression <inline asm>:1:9: note: instantiated into assembly here .long () - . ^ 2 errors generated.
on clang-13, but passes on gcc (with appropriate asm goto support). The bug is fixed in clang-14, but won't be backported to clang-13 as the changes are too invasive/risky.
gcc also had a similar bug[3], fixed in gcc-11, where gcc failed to account for its behavior of assigning two numbers to tied outputs (one for input, one for output) when evaluating symbolic references.
[1] https://github.com/ClangBuiltLinux/linux/issues/1512 [2] https://lore.kernel.org/all/YfMruK8%2F1izZ2VHS@google.com [3] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98096
Suggested-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20220202004945.2540433-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- init/Kconfig | 5 +++++ 1 file changed, 5 insertions(+)
--- a/init/Kconfig +++ b/init/Kconfig @@ -77,6 +77,11 @@ config CC_HAS_ASM_GOTO_OUTPUT depends on CC_HAS_ASM_GOTO def_bool $(success,echo 'int foo(int x) { asm goto ("": "=r"(x) ::: bar); return x; bar: return 0; }' | $(CC) -x c - -c -o /dev/null)
+config CC_HAS_ASM_GOTO_TIED_OUTPUT + depends on CC_HAS_ASM_GOTO_OUTPUT + # Detect buggy gcc and clang, fixed in gcc-11 clang-14. + def_bool $(success,echo 'int foo(int *x) { asm goto (".long (%l[bar]) - .\n": "+m"(*x) ::: bar); return *x; bar: return 0; }' | $CC -x c - -c -o /dev/null) + config TOOLS_SUPPORT_RELR def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
From: Puyou Lu puyou.lu@gmail.com
commit cd290a9839cee2f6641558877e707bd373c8f6f1 upstream.
Add allocated strarray to device's resource list. This is a must to automatically release strarray when the device disappears.
Without this fix we have a memory leak in the few drivers which use devm_kasprintf_strarray().
Link: https://lkml.kernel.org/r/20220506044409.30066-1-puyou.lu@gmail.com Link: https://lkml.kernel.org/r/20220506073623.2679-1-puyou.lu@gmail.com Fixes: acdb89b6c87a ("lib/string_helpers: Introduce managed variant of kasprintf_strarray()") Signed-off-by: Puyou Lu puyou.lu@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Cc: Tejun Heo tj@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/string_helpers.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -757,6 +757,9 @@ char **devm_kasprintf_strarray(struct de return ERR_PTR(-ENOMEM); }
+ ptr->n = n; + devres_add(dev, ptr); + return ptr->array; } EXPORT_SYMBOL_GPL(devm_kasprintf_strarray);
From: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com
commit f93e91a0372c922c20d5bee260b0f43b4b8a1bee upstream.
When multiplying of different types, an overflow is possible even when storing the result in a larger type. This is because the conversion is done after the multiplication. So arithmetic overflow and thus in incorrect value is possible.
Correct an instance of this in the inter packet delay calculation. Fix by ensuring one of the operands is u64 which will promote the other to u64 as well ensuring no overflow.
Cc: stable@vger.kernel.org Fixes: 7724105686e7 ("IB/hfi1: add driver files") Link: https://lore.kernel.org/r/20220520183712.48973.29855.stgit@awfm-01.cornelisn... Reviewed-by: Mike Marciniszyn mike.marciniszyn@cornelisnetworks.com Signed-off-by: Dennis Dalessandro dennis.dalessandro@cornelisnetworks.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/infiniband/hw/hfi1/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -489,7 +489,7 @@ void set_link_ipg(struct hfi1_pportdata u16 shift, mult; u64 src; u32 current_egress_rate; /* Mbits /sec */ - u32 max_pkt_time; + u64 max_pkt_time; /* * max_pkt_time is the maximum packet egress time in units * of the fabric clock period 1/(805 MHz).
From: Bean Huo beanhuo@micron.com
commit 23e09be254f95a5b75cd87f91a4014f3b46dda3f upstream.
Occasionally, user-land applications initiate longer timeout values for certain commands through ioctl() system call. But so far we are still using a fixed timeout of 10 seconds in mmc_poll_for_busy() on the ioctl() path, even if a custom timeout is specified in the userspace application. This patch allows custom timeout values to override this default timeout values on the ioctl path.
Cc: stable stable@vger.kernel.org Signed-off-by: Bean Huo beanhuo@micron.com Acked-by: Avri Altman avri.altman@wdc.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Link: https://lore.kernel.org/r/20220423221623.1074556-3-huobean@gmail.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/core/block.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -609,11 +609,11 @@ static int __mmc_blk_ioctl_cmd(struct mm
if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { /* - * Ensure RPMB/R1B command has completed by polling CMD13 - * "Send Status". + * Ensure RPMB/R1B command has completed by polling CMD13 "Send Status". Here we + * allow to override the default timeout value if a custom timeout is specified. */ - err = mmc_poll_for_busy(card, MMC_BLK_TIMEOUT_MS, false, - MMC_BUSY_IO); + err = mmc_poll_for_busy(card, idata->ic.cmd_timeout_ms ? : MMC_BLK_TIMEOUT_MS, + false, MMC_BUSY_IO); }
return err;
From: Guo Ren guoren@linux.alibaba.com
commit 8c4d16471e2babe9bdfe41d6ef724526629696cb upstream.
These patch_text implementations are using stop_machine_cpuslocked infrastructure with atomic cpu_count. The original idea: When the master CPU patch_text, the others should wait for it. But current implementation is using the first CPU as master, which couldn't guarantee the remaining CPUs are waiting. This patch changes the last CPU as the master to solve the potential risk.
Fixes: 33e53ae1ce41 ("csky: Add kprobes supported") Signed-off-by: Guo Ren guoren@linux.alibaba.com Signed-off-by: Guo Ren guoren@kernel.org Reviewed-by: Masami Hiramatsu mhiramat@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/csky/kernel/probes/kprobes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/csky/kernel/probes/kprobes.c +++ b/arch/csky/kernel/probes/kprobes.c @@ -30,7 +30,7 @@ static int __kprobes patch_text_cb(void struct csky_insn_patch *param = priv; unsigned int addr = (unsigned int)param->addr;
- if (atomic_inc_return(¶m->cpu_count) == 1) { + if (atomic_inc_return(¶m->cpu_count) == num_online_cpus()) { *(u16 *) addr = cpu_to_le16(param->opcode); dcache_wb_range(addr, addr + 2); atomic_inc(¶m->cpu_count);
From: Pali Rohár pali@kernel.org
commit a3d66a76348daf559873f19afc912a2a7c2ccdaf upstream.
Register ARMADA_370_XP_INT_FABRIC_MASK_OFFS is Armada 370 and XP specific and on new Armada platforms it has different meaning. It does not configure Performance Counter Overflow interrupt masking. So do not touch this register on non-A370/XP platforms (A375, A38x and A39x).
Signed-off-by: Pali Rohár pali@kernel.org Cc: stable@vger.kernel.org Fixes: 28da06dfd9e4 ("irqchip: armada-370-xp: Enable the PMU interrupts") Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20220425113706.29310-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/irqchip/irq-armada-370-xp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -308,7 +308,16 @@ static inline int armada_370_xp_msi_init
static void armada_xp_mpic_perf_init(void) { - unsigned long cpuid = cpu_logical_map(smp_processor_id()); + unsigned long cpuid; + + /* + * This Performance Counter Overflow interrupt is specific for + * Armada 370 and XP. It is not available on Armada 375, 38x and 39x. + */ + if (!of_machine_is_compatible("marvell,armada-370-xp")) + return; + + cpuid = cpu_logical_map(smp_processor_id());
/* Enable Performance Counter Overflow interrupts */ writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid),
From: Max Filippov jcmvbkbc@gmail.com
commit a255ee29252066d621df5d6b420bf534c6ba5bc0 upstream.
When irq-xtensa-mx chip is used in non-SMP configuration its irq_set_affinity callback is not called leaving IRQ affinity set empty. As a result IRQ delivery does not work in that configuration. Initialize IRQ affinity of the xtensa MX interrupt distributor to CPU 0 for all external IRQ lines.
Cc: stable@vger.kernel.org Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/irqchip/irq-xtensa-mx.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
--- a/drivers/irqchip/irq-xtensa-mx.c +++ b/drivers/irqchip/irq-xtensa-mx.c @@ -151,14 +151,25 @@ static struct irq_chip xtensa_mx_irq_chi .irq_set_affinity = xtensa_mx_irq_set_affinity, };
+static void __init xtensa_mx_init_common(struct irq_domain *root_domain) +{ + unsigned int i; + + irq_set_default_host(root_domain); + secondary_init_irq(); + + /* Initialize default IRQ routing to CPU 0 */ + for (i = 0; i < XCHAL_NUM_EXTINTERRUPTS; ++i) + set_er(1, MIROUT(i)); +} + int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent) { struct irq_domain *root_domain = irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0, &xtensa_mx_irq_domain_ops, &xtensa_mx_irq_chip); - irq_set_default_host(root_domain); - secondary_init_irq(); + xtensa_mx_init_common(root_domain); return 0; }
@@ -168,8 +179,7 @@ static int __init xtensa_mx_init(struct struct irq_domain *root_domain = irq_domain_add_linear(np, NR_IRQS, &xtensa_mx_irq_domain_ops, &xtensa_mx_irq_chip); - irq_set_default_host(root_domain); - secondary_init_irq(); + xtensa_mx_init_common(root_domain); return 0; } IRQCHIP_DECLARE(xtensa_mx_irq_chip, "cdns,xtensa-mx", xtensa_mx_init);
From: Kant Fan kant@allwinnertech.com
commit b947769b8f778db130aad834257fcaca25df2edc upstream.
Fix access illegal address problem in following condition:
There are multiple devfreq cooling devices in system, some of them has EM model but others do not. Energy model ops such as state2power will append to global devfreq_cooling_ops when the cooling device with EM model is registered. It makes the cooling device without EM model also use devfreq_cooling_ops after appending when registered later by of_devfreq_cooling_register_power() or of_devfreq_cooling_register().
The IPA governor regards the cooling devices without EM model as a power actor, because they also have energy model ops, and will access illegal address at dfc->em_pd when execute cdev->ops->get_requested_power, cdev->ops->state2power or cdev->ops->power2state.
Fixes: 615510fe13bd2 ("thermal: devfreq_cooling: remove old power model and use EM") Cc: 5.13+ stable@vger.kernel.org # 5.13+ Signed-off-by: Kant Fan kant@allwinnertech.com Reviewed-by: Lukasz Luba lukasz.luba@arm.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/thermal/devfreq_cooling.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
--- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -358,21 +358,28 @@ of_devfreq_cooling_register_power(struct struct thermal_cooling_device *cdev; struct device *dev = df->dev.parent; struct devfreq_cooling_device *dfc; + struct thermal_cooling_device_ops *ops; char *name; int err, num_opps;
- dfc = kzalloc(sizeof(*dfc), GFP_KERNEL); - if (!dfc) + ops = kmemdup(&devfreq_cooling_ops, sizeof(*ops), GFP_KERNEL); + if (!ops) return ERR_PTR(-ENOMEM);
+ dfc = kzalloc(sizeof(*dfc), GFP_KERNEL); + if (!dfc) { + err = -ENOMEM; + goto free_ops; + } + dfc->devfreq = df;
dfc->em_pd = em_pd_get(dev); if (dfc->em_pd) { - devfreq_cooling_ops.get_requested_power = + ops->get_requested_power = devfreq_cooling_get_requested_power; - devfreq_cooling_ops.state2power = devfreq_cooling_state2power; - devfreq_cooling_ops.power2state = devfreq_cooling_power2state; + ops->state2power = devfreq_cooling_state2power; + ops->power2state = devfreq_cooling_power2state;
dfc->power_ops = dfc_power;
@@ -407,8 +414,7 @@ of_devfreq_cooling_register_power(struct if (!name) goto remove_qos_req;
- cdev = thermal_of_cooling_device_register(np, name, dfc, - &devfreq_cooling_ops); + cdev = thermal_of_cooling_device_register(np, name, dfc, ops); kfree(name);
if (IS_ERR(cdev)) { @@ -429,6 +435,8 @@ free_table: kfree(dfc->freq_table); free_dfc: kfree(dfc); +free_ops: + kfree(ops);
return ERR_PTR(err); } @@ -510,11 +518,13 @@ EXPORT_SYMBOL_GPL(devfreq_cooling_em_reg void devfreq_cooling_unregister(struct thermal_cooling_device *cdev) { struct devfreq_cooling_device *dfc; + const struct thermal_cooling_device_ops *ops; struct device *dev;
if (IS_ERR_OR_NULL(cdev)) return;
+ ops = cdev->ops; dfc = cdev->devdata; dev = dfc->devfreq->dev.parent;
@@ -525,5 +535,6 @@ void devfreq_cooling_unregister(struct t
kfree(dfc->freq_table); kfree(dfc); + kfree(ops); } EXPORT_SYMBOL_GPL(devfreq_cooling_unregister);
From: Felix Fietkau nbd@nbd.name
commit 51fb1278aa57ae0fc54adaa786e1965362bed4fb upstream.
Fixes an issue caught by KASAN about use-after-free in mt76_txq_schedule by protecting mtxq->wcid with rcu_lock between mt76_txq_schedule and sta_info_[alloc, free].
[18853.876689] ================================================================== [18853.876751] BUG: KASAN: use-after-free in mt76_txq_schedule+0x204/0xaf8 [mt76] [18853.876773] Read of size 8 at addr ffffffaf989a2138 by task mt76-tx phy0/883 [18853.876786] [18853.876810] CPU: 5 PID: 883 Comm: mt76-tx phy0 Not tainted 5.10.100-fix-510-56778d365941-kasan #5 0b01fbbcf41a530f52043508fec2e31a4215
[18853.876840] Call trace: [18853.876861] dump_backtrace+0x0/0x3ec [18853.876878] show_stack+0x20/0x2c [18853.876899] dump_stack+0x11c/0x1ac [18853.876918] print_address_description+0x74/0x514 [18853.876934] kasan_report+0x134/0x174 [18853.876948] __asan_report_load8_noabort+0x44/0x50 [18853.876976] mt76_txq_schedule+0x204/0xaf8 [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877002] mt76_txq_schedule_all+0x2c/0x48 [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877030] mt7921_tx_worker+0xa0/0x1cc [mt7921_common f0875ebac9d7b4754e1010549e7db50fbd90a047] [18853.877054] __mt76_worker_fn+0x190/0x22c [mt76 074e03e4640e97fe7405ee1fab547b81c4fa45d2] [18853.877071] kthread+0x2f8/0x3b8 [18853.877087] ret_from_fork+0x10/0x30 [18853.877098] [18853.877112] Allocated by task 941: [18853.877131] kasan_save_stack+0x38/0x68 [18853.877147] __kasan_kmalloc+0xd4/0xfc [18853.877163] kasan_kmalloc+0x10/0x1c [18853.877177] __kmalloc+0x264/0x3c4 [18853.877294] sta_info_alloc+0x460/0xf88 [mac80211] [18853.877410] ieee80211_prep_connection+0x204/0x1ee0 [mac80211] [18853.877523] ieee80211_mgd_auth+0x6c4/0xa4c [mac80211] [18853.877635] ieee80211_auth+0x20/0x2c [mac80211] [18853.877733] rdev_auth+0x7c/0x438 [cfg80211] [18853.877826] cfg80211_mlme_auth+0x26c/0x390 [cfg80211] [18853.877919] nl80211_authenticate+0x6d4/0x904 [cfg80211] [18853.877938] genl_rcv_msg+0x748/0x93c [18853.877954] netlink_rcv_skb+0x160/0x2a8 [18853.877969] genl_rcv+0x3c/0x54 [18853.877985] netlink_unicast_kernel+0x104/0x1ec [18853.877999] netlink_unicast+0x178/0x268 [18853.878015] netlink_sendmsg+0x3cc/0x5f0 [18853.878030] sock_sendmsg+0xb4/0xd8 [18853.878043] ____sys_sendmsg+0x2f8/0x53c [18853.878058] ___sys_sendmsg+0xe8/0x150 [18853.878071] __sys_sendmsg+0xc4/0x1f4 [18853.878087] __arm64_compat_sys_sendmsg+0x88/0x9c [18853.878101] el0_svc_common+0x1b4/0x390 [18853.878115] do_el0_svc_compat+0x8c/0xdc [18853.878131] el0_svc_compat+0x10/0x1c [18853.878146] el0_sync_compat_handler+0xa8/0xcc [18853.878161] el0_sync_compat+0x188/0x1c0 [18853.878171] [18853.878183] Freed by task 10927: [18853.878200] kasan_save_stack+0x38/0x68 [18853.878215] kasan_set_track+0x28/0x3c [18853.878228] kasan_set_free_info+0x24/0x48 [18853.878244] __kasan_slab_free+0x11c/0x154 [18853.878259] kasan_slab_free+0x14/0x24 [18853.878273] slab_free_freelist_hook+0xac/0x1b0 [18853.878287] kfree+0x104/0x390 [18853.878402] sta_info_free+0x198/0x210 [mac80211] [18853.878515] __sta_info_destroy_part2+0x230/0x2d4 [mac80211] [18853.878628] __sta_info_flush+0x300/0x37c [mac80211] [18853.878740] ieee80211_set_disassoc+0x2cc/0xa7c [mac80211] [18853.878851] ieee80211_mgd_deauth+0x4a4/0x10a0 [mac80211] [18853.878962] ieee80211_deauth+0x20/0x2c [mac80211] [18853.879057] rdev_deauth+0x7c/0x438 [cfg80211] [18853.879150] cfg80211_mlme_deauth+0x274/0x414 [cfg80211] [18853.879243] cfg80211_mlme_down+0xe4/0x118 [cfg80211] [18853.879335] cfg80211_disconnect+0x218/0x2d8 [cfg80211] [18853.879427] __cfg80211_leave+0x17c/0x240 [cfg80211] [18853.879519] cfg80211_leave+0x3c/0x58 [cfg80211] [18853.879611] wiphy_suspend+0xdc/0x200 [cfg80211] [18853.879628] dpm_run_callback+0x58/0x408 [18853.879642] __device_suspend+0x4cc/0x864 [18853.879658] async_suspend+0x34/0xf4 [18853.879673] async_run_entry_fn+0xe0/0x37c [18853.879689] process_one_work+0x508/0xb98 [18853.879702] worker_thread+0x7f4/0xcd4 [18853.879717] kthread+0x2f8/0x3b8 [18853.879731] ret_from_fork+0x10/0x30 [18853.879741] [18853.879757] The buggy address belongs to the object at ffffffaf989a2000 [18853.879757] which belongs to the cache kmalloc-8k of size 8192 [18853.879774] The buggy address is located 312 bytes inside of [18853.879774] 8192-byte region [ffffffaf989a2000, ffffffaf989a4000) [18853.879787] The buggy address belongs to the page: [18853.879807] page:000000004bda2a59 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1d89a0 [18853.879823] head:000000004bda2a59 order:3 compound_mapcount:0 compound_pincount:0 [18853.879839] flags: 0x8000000000010200(slab|head) [18853.879857] raw: 8000000000010200 ffffffffbc89e208 ffffffffb7fb5208 ffffffaec000cc80 [18853.879873] raw: 0000000000000000 0000000000010001 00000001ffffffff 0000000000000000 [18853.879885] page dumped because: kasan: bad access detected [18853.879896] [18853.879907] Memory state around the buggy address: [18853.879922] ffffffaf989a2000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879935] ffffffaf989a2080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879948] >ffffffaf989a2100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879961] ^ [18853.879973] ffffffaf989a2180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879986] ffffffaf989a2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [18853.879998] ==================================================================
Cc: stable@vger.kernel.org Reported-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 +++- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 9 ++++----- 8 files changed, 13 insertions(+), 12 deletions(-)
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1303,7 +1303,7 @@ mt76_sta_add(struct mt76_dev *dev, struc continue;
mtxq = (struct mt76_txq *)sta->txq[i]->drv_priv; - mtxq->wcid = wcid; + mtxq->wcid = wcid->idx; }
ewma_signal_init(&wcid->rssi); --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -275,7 +275,7 @@ struct mt76_wcid { };
struct mt76_txq { - struct mt76_wcid *wcid; + u16 wcid;
u16 agg_ssn; bool send_bar; --- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -75,7 +75,7 @@ mt7603_add_interface(struct ieee80211_hw mt7603_wtbl_init(dev, idx, mvif->idx, bc_addr);
mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
out: --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -234,7 +234,7 @@ static int mt7615_add_interface(struct i rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; }
ret = mt7615_mcu_add_dev_info(phy, vif, true); --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -292,7 +292,8 @@ mt76x02_vif_init(struct mt76x02_dev *dev mt76_packet_id_init(&mvif->group_wcid);
mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->group_wcid; + rcu_assign_pointer(dev->mt76.wcid[MT_VIF_WCID(idx)], &mvif->group_wcid); + mtxq->wcid = MT_VIF_WCID(idx); }
int @@ -345,6 +346,7 @@ void mt76x02_remove_interface(struct iee struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
dev->mt76.vif_mask &= ~BIT(mvif->idx); + rcu_assign_pointer(dev->mt76.wcid[mvif->group_wcid.idx], NULL); mt76_packet_id_flush(&dev->mt76, &mvif->group_wcid); } EXPORT_SYMBOL_GPL(mt76x02_remove_interface); --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -246,7 +246,7 @@ static int mt7915_add_interface(struct i rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; }
if (vif->type != NL80211_IFTYPE_AP && --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -330,7 +330,7 @@ static int mt7921_add_interface(struct i rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); if (vif->txq) { mtxq = (struct mt76_txq *)vif->txq->drv_priv; - mtxq->wcid = &mvif->sta.wcid; + mtxq->wcid = idx; }
out: --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -436,12 +436,11 @@ mt76_txq_stopped(struct mt76_queue *q)
static int mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q, - struct mt76_txq *mtxq) + struct mt76_txq *mtxq, struct mt76_wcid *wcid) { struct mt76_dev *dev = phy->dev; struct ieee80211_txq *txq = mtxq_to_txq(mtxq); enum mt76_txq_id qid = mt76_txq_get_qid(txq); - struct mt76_wcid *wcid = mtxq->wcid; struct ieee80211_tx_info *info; struct sk_buff *skb; int n_frames = 1; @@ -521,8 +520,8 @@ mt76_txq_schedule_list(struct mt76_phy * break;
mtxq = (struct mt76_txq *)txq->drv_priv; - wcid = mtxq->wcid; - if (wcid && test_bit(MT_WCID_FLAG_PS, &wcid->flags)) + wcid = rcu_dereference(dev->wcid[mtxq->wcid]); + if (!wcid || test_bit(MT_WCID_FLAG_PS, &wcid->flags)) continue;
spin_lock_bh(&q->lock); @@ -541,7 +540,7 @@ mt76_txq_schedule_list(struct mt76_phy * }
if (!mt76_txq_stopped(q)) - n_frames = mt76_txq_send_burst(phy, q, mtxq); + n_frames = mt76_txq_send_burst(phy, q, mtxq, wcid);
spin_unlock_bh(&q->lock);
From: Dimitri John Ledkov dimitri.ledkov@canonical.com
commit 7bc7981eeebe1b8e603ad2ffc5e84f4df76920dd upstream.
Add MODULE_FIRMWARE declarations for regulatory.db and regulatory.db.p7s such that userspace tooling can discover and include these files.
Cc: stable@vger.kernel.org Signed-off-by: Dimitri John Ledkov dimitri.ledkov@canonical.com Link: https://lore.kernel.org/r/20220414125004.267819-1-dimitri.ledkov@canonical.c... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/wireless/reg.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -807,6 +807,8 @@ static int __init load_builtin_regdb_key return 0; }
+MODULE_FIRMWARE("regulatory.db.p7s"); + static bool regdb_has_valid_signature(const u8 *data, unsigned int size) { const struct firmware *sig; @@ -1078,6 +1080,8 @@ static void regdb_fw_cb(const struct fir release_firmware(fw); }
+MODULE_FIRMWARE("regulatory.db"); + static int query_regdb_file(const char *alpha2) { ASSERT_RTNL();
From: Felix Fietkau nbd@nbd.name
commit b041b7b9de6e1d4362de855ab90f9d03ef323edd upstream.
In client mode, we can't connect to hidden SSID APs or SSIDs not advertised in beacons on DFS channels, since we're forced to passive scan. Fix this by sending out a probe request immediately after the first beacon, if active scan was requested by the user.
Cc: stable@vger.kernel.org Reported-by: Catrinel Catrinescu cc@80211.de Signed-off-by: Felix Fietkau nbd@nbd.name Link: https://lore.kernel.org/r/20220420104907.36275-1-nbd@nbd.name Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mac80211/ieee80211_i.h | 5 +++++ net/mac80211/scan.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+)
--- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1148,6 +1148,9 @@ struct tpt_led_trigger { * a scan complete for an aborted scan. * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being * cancelled. + * @SCAN_BEACON_WAIT: Set whenever we're passive scanning because of radar/no-IR + * and could send a probe request after receiving a beacon. + * @SCAN_BEACON_DONE: Beacon received, we can now send a probe request */ enum { SCAN_SW_SCANNING, @@ -1156,6 +1159,8 @@ enum { SCAN_COMPLETED, SCAN_ABORTED, SCAN_HW_CANCELLED, + SCAN_BEACON_WAIT, + SCAN_BEACON_DONE, };
/** --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -281,6 +281,16 @@ void ieee80211_scan_rx(struct ieee80211_ if (likely(!sdata1 && !sdata2)) return;
+ if (test_and_clear_bit(SCAN_BEACON_WAIT, &local->scanning)) { + /* + * we were passive scanning because of radar/no-IR, but + * the beacon/proberesp rx gives us an opportunity to upgrade + * to active scan + */ + set_bit(SCAN_BEACON_DONE, &local->scanning); + ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); + } + if (ieee80211_is_probe_resp(mgmt->frame_control)) { struct cfg80211_scan_request *scan_req; struct cfg80211_sched_scan_request *sched_scan_req; @@ -787,6 +797,8 @@ static int __ieee80211_start_scan(struct IEEE80211_CHAN_RADAR)) || !req->n_ssids) { next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; + if (req->n_ssids) + set_bit(SCAN_BEACON_WAIT, &local->scanning); } else { ieee80211_scan_state_send_probe(local, &next_delay); next_delay = IEEE80211_CHANNEL_TIME; @@ -998,6 +1010,8 @@ set_channel: !scan_req->n_ssids) { *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; local->next_scan_state = SCAN_DECISION; + if (scan_req->n_ssids) + set_bit(SCAN_BEACON_WAIT, &local->scanning); return; }
@@ -1090,6 +1104,8 @@ void ieee80211_scan_work(struct work_str goto out; }
+ clear_bit(SCAN_BEACON_WAIT, &local->scanning); + /* * as long as no delay is required advance immediately * without scheduling a new work @@ -1100,6 +1116,10 @@ void ieee80211_scan_work(struct work_str goto out_complete; }
+ if (test_and_clear_bit(SCAN_BEACON_DONE, &local->scanning) && + local->next_scan_state == SCAN_DECISION) + local->next_scan_state = SCAN_SEND_PROBE; + switch (local->next_scan_state) { case SCAN_DECISION: /* if no more bands/channels left, complete scan */
From: Johannes Berg johannes.berg@intel.com
commit af9fb41ed315ce95f659f0b10b4d59a71975381d upstream.
If a device implementation crashes, virtio_uml will mark it as dead by calling virtio_break_device() and scheduling the work that will remove it.
This still seems like the right thing to do, but it's done directly while reading the message, and if time-travel is used, this is in the time-travel handler, outside of the normal Linux machinery. Therefore, we cannot acquire locks or do normal "linux-y" things because e.g. lockdep will be confused about the context.
Move handling this situation out of the read function and into the actual IRQ handler and response handling instead, so that in the case of time-travel we don't call it in the wrong context.
Chances are the system will still crash immediately, since the device implementation crashing may also cause the time- travel controller to go down, but at least all of that now happens without strange warnings from lockdep.
Fixes: c8177aba37ca ("um: time-travel: rework interrupt handling in ext mode") Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/drivers/virtio_uml.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
--- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -63,6 +63,7 @@ struct virtio_uml_device {
u8 config_changed_irq:1; uint64_t vq_irq_vq_map; + int recv_rc; };
struct virtio_uml_vq_info { @@ -148,14 +149,6 @@ static int vhost_user_recv(struct virtio
rc = vhost_user_recv_header(fd, msg);
- if (rc == -ECONNRESET && vu_dev->registered) { - struct virtio_uml_platform_data *pdata; - - pdata = vu_dev->pdata; - - virtio_break_device(&vu_dev->vdev); - schedule_work(&pdata->conn_broken_wk); - } if (rc) return rc; size = msg->header.size; @@ -164,6 +157,21 @@ static int vhost_user_recv(struct virtio return full_read(fd, &msg->payload, size, false); }
+static void vhost_user_check_reset(struct virtio_uml_device *vu_dev, + int rc) +{ + struct virtio_uml_platform_data *pdata = vu_dev->pdata; + + if (rc != -ECONNRESET) + return; + + if (!vu_dev->registered) + return; + + virtio_break_device(&vu_dev->vdev); + schedule_work(&pdata->conn_broken_wk); +} + static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev, struct vhost_user_msg *msg, size_t max_payload_size) @@ -171,8 +179,10 @@ static int vhost_user_recv_resp(struct v int rc = vhost_user_recv(vu_dev, vu_dev->sock, msg, max_payload_size, true);
- if (rc) + if (rc) { + vhost_user_check_reset(vu_dev, rc); return rc; + }
if (msg->header.flags != (VHOST_USER_FLAG_REPLY | VHOST_USER_VERSION)) return -EPROTO; @@ -369,6 +379,7 @@ static irqreturn_t vu_req_read_message(s sizeof(msg.msg.payload) + sizeof(msg.extra_payload));
+ vu_dev->recv_rc = rc; if (rc) return IRQ_NONE;
@@ -412,7 +423,9 @@ static irqreturn_t vu_req_interrupt(int if (!um_irq_timetravel_handler_used()) ret = vu_req_read_message(vu_dev, NULL);
- if (vu_dev->vq_irq_vq_map) { + if (vu_dev->recv_rc) { + vhost_user_check_reset(vu_dev, vu_dev->recv_rc); + } else if (vu_dev->vq_irq_vq_map) { struct virtqueue *vq;
virtio_device_for_each_vq((&vu_dev->vdev), vq) {
From: Johannes Berg johannes.berg@intel.com
commit 365719035526e8eda214a1cedb2e1c96e969a0d7 upstream.
If DMA (PCI over virtio) is enabled, then some drivers may enable CONFIG_DMA_OPS as well, and then we pull in the x86 definition of get_arch_dma_ops(), which uses the dma_ops symbol, which isn't defined.
Since we don't have real DMA ops nor any kind of IOMMU fix this in the simplest possible way: pull in the asm-generic file instead of inheriting the x86 one. It's not clear why those drivers that do (e.g. VDPA) "select DMA_OPS", and if they'd even work with this, but chances are nobody will be wanting to do that anyway, so fixing the build failure is good enough.
Reported-by: Randy Dunlap rdunlap@infradead.org Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Johannes Berg johannes.berg@intel.com Tested-by: Randy Dunlap rdunlap@infradead.org Acked-by: Randy Dunlap rdunlap@infradead.org Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/include/asm/Kbuild | 1 + 1 file changed, 1 insertion(+)
--- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -4,6 +4,7 @@ generic-y += bug.h generic-y += compat.h generic-y += current.h generic-y += device.h +generic-y += dma-mapping.h generic-y += emergency-restart.h generic-y += exec.h generic-y += extable.h
From: Johannes Berg johannes.berg@intel.com
commit 57ae0b67b747031bc41fb44643aa5344ab58607e upstream.
The previous fix here was only partially correct, it did result in returning a proper error value in case of error, but it also clobbered the pid that we need to return from this function (not just zero for success).
As a result, it returned 0 here, but later this is treated as a pid and used to kill the process, but since it's now 0 we kill(0, SIGKILL), which makes UML kill itself rather than just the helper thread.
Fix that and make it more obvious by using a separate variable for the pid.
Fixes: ccf1236ecac4 ("um: fix error return code in winch_tramp()") Reported-and-tested-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Johannes Berg johannes.berg@intel.com Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/um/drivers/chan_user.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -220,7 +220,7 @@ static int winch_tramp(int fd, struct tt unsigned long *stack_out) { struct winch_data data; - int fds[2], n, err; + int fds[2], n, err, pid; char c;
err = os_pipe(fds, 1, 1); @@ -238,8 +238,9 @@ static int winch_tramp(int fd, struct tt * problem with /dev/net/tun, which if held open by this * thread, prevents the TUN/TAP device from being reused. */ - err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); - if (err < 0) { + pid = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); + if (pid < 0) { + err = pid; printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n", -err); goto out_close; @@ -263,7 +264,7 @@ static int winch_tramp(int fd, struct tt goto out_close; }
- return err; + return pid;
out_close: close(fds[1]);
From: Vincent Whitchurch vincent.whitchurch@axis.com
commit 2a4a62a14be1947fa945c5c11ebf67326381a568 upstream.
syscall_stub_data() expects the data_count parameter to be the number of longs, not bytes.
================================================================== BUG: KASAN: stack-out-of-bounds in syscall_stub_data+0x70/0xe0 Read of size 128 at addr 000000006411f6f0 by task swapper/1
CPU: 0 PID: 1 Comm: swapper Not tainted 5.18.0+ #18 Call Trace: show_stack.cold+0x166/0x2a7 __dump_stack+0x3a/0x43 dump_stack_lvl+0x1f/0x27 print_report.cold+0xdb/0xf81 kasan_report+0x119/0x1f0 kasan_check_range+0x3a3/0x440 memcpy+0x52/0x140 syscall_stub_data+0x70/0xe0 write_ldt_entry+0xac/0x190 init_new_ldt+0x515/0x960 init_new_context+0x2c4/0x4d0 mm_init.constprop.0+0x5ed/0x760 mm_alloc+0x118/0x170 0x60033f48 do_one_initcall+0x1d7/0x860 0x60003e7b kernel_init+0x6e/0x3d4 new_thread_handler+0x1e7/0x2c0
The buggy address belongs to stack of task swapper/1 and is located at offset 64 in frame: init_new_ldt+0x0/0x960
This frame has 2 objects: [32, 40) 'addr' [64, 80) 'desc' ==================================================================
Fixes: 858259cf7d1c443c83 ("uml: maintain own LDT entries") Signed-off-by: Vincent Whitchurch vincent.whitchurch@axis.com Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger richard@nod.at Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/um/ldt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/arch/x86/um/ldt.c +++ b/arch/x86/um/ldt.c @@ -23,9 +23,11 @@ static long write_ldt_entry(struct mm_id { long res; void *stub_addr; + + BUILD_BUG_ON(sizeof(*desc) % sizeof(long)); + res = syscall_stub_data(mm_idp, (unsigned long *)desc, - (sizeof(*desc) + sizeof(long) - 1) & - ~(sizeof(long) - 1), + sizeof(*desc) / sizeof(long), addr, &stub_addr); if (!res) { unsigned long args[] = { func,
From: Maciej W. Rozycki macro@orcam.me.uk
commit 424c3781dd1cb401857585331eaaa425a13f2429 upstream.
Remove unsupported forcing of `cpu_has_fpu' to 1, which makes the `nofpu' kernel parameter non-functional, and also causes a link error:
ld: arch/mips/kernel/traps.o: in function `trap_init': ./arch/mips/include/asm/msa.h:(.init.text+0x348): undefined reference to `handle_fpe' ld: ./arch/mips/include/asm/msa.h:(.init.text+0x354): undefined reference to `handle_fpe' ld: ./arch/mips/include/asm/msa.h:(.init.text+0x360): undefined reference to `handle_fpe'
where the CONFIG_MIPS_FP_SUPPORT configuration option has been disabled.
Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Reported-by: Stephen Zhang starzhangzsd@gmail.com Fixes: 0ebb2f4159af ("MIPS: IP27: Update/restructure CPU overrides") Cc: stable@vger.kernel.org # v4.2+ Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h | 1 - 1 file changed, 1 deletion(-)
--- a/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h @@ -25,7 +25,6 @@ #define cpu_has_4kex 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 -#define cpu_has_fpu 1 #define cpu_has_nofpuex 0 #define cpu_has_32fpr 1 #define cpu_has_counter 1
From: Maciej W. Rozycki macro@orcam.me.uk
commit f44b3e74c33fe04defeff24ebcae98c3bcc5b285 upstream.
Remove unsupported forcing of `cpu_has_fpu' to 1, which makes the `nofpu' kernel parameter non-functional, and also causes a link error:
ld: arch/mips/kernel/traps.o: in function `trap_init': ./arch/mips/include/asm/msa.h:(.init.text+0x348): undefined reference to `handle_fpe' ld: ./arch/mips/include/asm/msa.h:(.init.text+0x354): undefined reference to `handle_fpe' ld: ./arch/mips/include/asm/msa.h:(.init.text+0x360): undefined reference to `handle_fpe'
where the CONFIG_MIPS_FP_SUPPORT configuration option has been disabled.
Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Reported-by: Stephen Zhang starzhangzsd@gmail.com Fixes: 7505576d1c1a ("MIPS: add support for SGI Octane (IP30)") Cc: stable@vger.kernel.org # v5.5+ Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/include/asm/mach-ip30/cpu-feature-overrides.h | 1 - 1 file changed, 1 deletion(-)
--- a/arch/mips/include/asm/mach-ip30/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-ip30/cpu-feature-overrides.h @@ -28,7 +28,6 @@ #define cpu_has_4kex 1 #define cpu_has_3k_cache 0 #define cpu_has_4k_cache 1 -#define cpu_has_fpu 1 #define cpu_has_nofpuex 0 #define cpu_has_32fpr 1 #define cpu_has_counter 1
From: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com
commit 3e35142ef99fe6b4fe5d834ad43ee13cca10a2dc upstream.
Since commit d1bcae833b32f1 ("ELF: Don't generate unused section symbols") [1], binutils (v2.36+) started dropping section symbols that it thought were unused. This isn't an issue in general, but with kexec_file.c, gcc is placing kexec_arch_apply_relocations[_add] into a separate .text.unlikely section and the section symbol ".text.unlikely" is being dropped. Due to this, recordmcount is unable to find a non-weak symbol in .text.unlikely to generate a relocation record against.
Address this by dropping the weak attribute from these functions. Instead, follow the existing pattern of having architectures #define the name of the function they want to override in their headers.
[1] https://sourceware.org/git/?p=binutils-gdb.git%3Ba=commit%3Bh=d1bcae833b32f1
[akpm@linux-foundation.org: arch/s390/include/asm/kexec.h needs linux/module.h] Link: https://lkml.kernel.org/r/20220519091237.676736-1-naveen.n.rao@linux.vnet.ib... Signed-off-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Cc: "Eric W. Biederman" ebiederm@xmission.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/include/asm/kexec.h | 10 +++++++++ arch/x86/include/asm/kexec.h | 8 +++++++ include/linux/kexec.h | 46 ++++++++++++++++++++++++++++++++++-------- kernel/kexec_file.c | 34 ------------------------------- 4 files changed, 56 insertions(+), 42 deletions(-)
--- a/arch/s390/include/asm/kexec.h +++ b/arch/s390/include/asm/kexec.h @@ -9,6 +9,8 @@ #ifndef _S390_KEXEC_H #define _S390_KEXEC_H
+#include <linux/module.h> + #include <asm/processor.h> #include <asm/page.h> #include <asm/setup.h> @@ -83,4 +85,12 @@ struct kimage_arch { extern const struct kexec_file_ops s390_kexec_image_ops; extern const struct kexec_file_ops s390_kexec_elf_ops;
+#ifdef CONFIG_KEXEC_FILE +struct purgatory_info; +int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + Elf_Shdr *section, + const Elf_Shdr *relsec, + const Elf_Shdr *symtab); +#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add +#endif #endif /*_S390_KEXEC_H */ --- a/arch/x86/include/asm/kexec.h +++ b/arch/x86/include/asm/kexec.h @@ -186,6 +186,14 @@ extern int arch_kexec_post_alloc_pages(v extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages); #define arch_kexec_pre_free_pages arch_kexec_pre_free_pages
+#ifdef CONFIG_KEXEC_FILE +struct purgatory_info; +int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + Elf_Shdr *section, + const Elf_Shdr *relsec, + const Elf_Shdr *symtab); +#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add +#endif #endif
typedef void crash_vmclear_fn(void); --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -193,14 +193,6 @@ void *kexec_purgatory_get_symbol_addr(st int arch_kexec_kernel_image_probe(struct kimage *image, void *buf, unsigned long buf_len); void *arch_kexec_kernel_image_load(struct kimage *image); -int arch_kexec_apply_relocations_add(struct purgatory_info *pi, - Elf_Shdr *section, - const Elf_Shdr *relsec, - const Elf_Shdr *symtab); -int arch_kexec_apply_relocations(struct purgatory_info *pi, - Elf_Shdr *section, - const Elf_Shdr *relsec, - const Elf_Shdr *symtab); int arch_kimage_file_post_load_cleanup(struct kimage *image); #ifdef CONFIG_KEXEC_SIG int arch_kexec_kernel_verify_sig(struct kimage *image, void *buf, @@ -229,6 +221,44 @@ extern int crash_exclude_mem_range(struc unsigned long long mend); extern int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map, void **addr, unsigned long *sz); + +#ifndef arch_kexec_apply_relocations_add +/* + * arch_kexec_apply_relocations_add - apply relocations of type RELA + * @pi: Purgatory to be relocated. + * @section: Section relocations applying to. + * @relsec: Section containing RELAs. + * @symtab: Corresponding symtab. + * + * Return: 0 on success, negative errno on error. + */ +static inline int +arch_kexec_apply_relocations_add(struct purgatory_info *pi, Elf_Shdr *section, + const Elf_Shdr *relsec, const Elf_Shdr *symtab) +{ + pr_err("RELA relocation unsupported.\n"); + return -ENOEXEC; +} +#endif + +#ifndef arch_kexec_apply_relocations +/* + * arch_kexec_apply_relocations - apply relocations of type REL + * @pi: Purgatory to be relocated. + * @section: Section relocations applying to. + * @relsec: Section containing RELs. + * @symtab: Corresponding symtab. + * + * Return: 0 on success, negative errno on error. + */ +static inline int +arch_kexec_apply_relocations(struct purgatory_info *pi, Elf_Shdr *section, + const Elf_Shdr *relsec, const Elf_Shdr *symtab) +{ + pr_err("REL relocation unsupported.\n"); + return -ENOEXEC; +} +#endif #endif /* CONFIG_KEXEC_FILE */
#ifdef CONFIG_KEXEC_ELF --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -109,40 +109,6 @@ int __weak arch_kexec_kernel_verify_sig( #endif
/* - * arch_kexec_apply_relocations_add - apply relocations of type RELA - * @pi: Purgatory to be relocated. - * @section: Section relocations applying to. - * @relsec: Section containing RELAs. - * @symtab: Corresponding symtab. - * - * Return: 0 on success, negative errno on error. - */ -int __weak -arch_kexec_apply_relocations_add(struct purgatory_info *pi, Elf_Shdr *section, - const Elf_Shdr *relsec, const Elf_Shdr *symtab) -{ - pr_err("RELA relocation unsupported.\n"); - return -ENOEXEC; -} - -/* - * arch_kexec_apply_relocations - apply relocations of type REL - * @pi: Purgatory to be relocated. - * @section: Section relocations applying to. - * @relsec: Section containing RELs. - * @symtab: Corresponding symtab. - * - * Return: 0 on success, negative errno on error. - */ -int __weak -arch_kexec_apply_relocations(struct purgatory_info *pi, Elf_Shdr *section, - const Elf_Shdr *relsec, const Elf_Shdr *symtab) -{ - pr_err("REL relocation unsupported.\n"); - return -ENOEXEC; -} - -/* * Free up memory used by kernel, initrd, and command line. This is temporary * memory allocation which is not needed any more after these buffers have * been loaded into separate segments and have been copied elsewhere.
From: Song Liu song@kernel.org
commit 7d54c15cb89a29a5f59e5ffc9ee62e6591769ef1 upstream.
We see the following GPF when register_ftrace_direct fails:
[ ] general protection fault, probably for non-canonical address \ 0x200000000000010: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI [...] [ ] RIP: 0010:ftrace_find_rec_direct+0x53/0x70 [ ] Code: 48 c1 e0 03 48 03 42 08 48 8b 10 31 c0 48 85 d2 74 [...] [ ] RSP: 0018:ffffc9000138bc10 EFLAGS: 00010206 [ ] RAX: 0000000000000000 RBX: ffffffff813e0df0 RCX: 000000000000003b [ ] RDX: 0200000000000000 RSI: 000000000000000c RDI: ffffffff813e0df0 [ ] RBP: ffffffffa00a3000 R08: ffffffff81180ce0 R09: 0000000000000001 [ ] R10: ffffc9000138bc18 R11: 0000000000000001 R12: ffffffff813e0df0 [ ] R13: ffffffff813e0df0 R14: ffff888171b56400 R15: 0000000000000000 [ ] FS: 00007fa9420c7780(0000) GS:ffff888ff6a00000(0000) knlGS:000000000 [ ] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ ] CR2: 000000000770d000 CR3: 0000000107d50003 CR4: 0000000000370ee0 [ ] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ ] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ ] Call Trace: [ ] <TASK> [ ] register_ftrace_direct+0x54/0x290 [ ] ? render_sigset_t+0xa0/0xa0 [ ] bpf_trampoline_update+0x3f5/0x4a0 [ ] ? 0xffffffffa00a3000 [ ] bpf_trampoline_link_prog+0xa9/0x140 [ ] bpf_tracing_prog_attach+0x1dc/0x450 [ ] bpf_raw_tracepoint_open+0x9a/0x1e0 [ ] ? find_held_lock+0x2d/0x90 [ ] ? lock_release+0x150/0x430 [ ] __sys_bpf+0xbd6/0x2700 [ ] ? lock_is_held_type+0xd8/0x130 [ ] __x64_sys_bpf+0x1c/0x20 [ ] do_syscall_64+0x3a/0x80 [ ] entry_SYSCALL_64_after_hwframe+0x44/0xae [ ] RIP: 0033:0x7fa9421defa9 [ ] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 9 f8 [...] [ ] RSP: 002b:00007ffed743bd78 EFLAGS: 00000246 ORIG_RAX: 0000000000000141 [ ] RAX: ffffffffffffffda RBX: 00000000069d2480 RCX: 00007fa9421defa9 [ ] RDX: 0000000000000078 RSI: 00007ffed743bd80 RDI: 0000000000000011 [ ] RBP: 00007ffed743be00 R08: 0000000000bb7270 R09: 0000000000000000 [ ] R10: 00000000069da210 R11: 0000000000000246 R12: 0000000000000001 [ ] R13: 00007ffed743c4b0 R14: 00000000069d2480 R15: 0000000000000001 [ ] </TASK> [ ] Modules linked in: klp_vm(OK) [ ] ---[ end trace 0000000000000000 ]---
One way to trigger this is: 1. load a livepatch that patches kernel function xxx; 2. run bpftrace -e 'kfunc:xxx {}', this will fail (expected for now); 3. repeat #2 => gpf.
This is because the entry is added to direct_functions, but not removed. Fix this by remove the entry from direct_functions when register_ftrace_direct fails.
Also remove the last trailing space from ftrace.c, so we don't have to worry about it anymore.
Link: https://lkml.kernel.org/r/20220524170839.900849-1-song@kernel.org
Cc: stable@vger.kernel.org Fixes: 763e34e74bb7 ("ftrace: Add register_ftrace_direct()") Signed-off-by: Song Liu song@kernel.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ftrace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -4465,7 +4465,7 @@ int ftrace_func_mapper_add_ip(struct ftr * @ip: The instruction pointer address to remove the data from * * Returns the data if it is found, otherwise NULL. - * Note, if the data pointer is used as the data itself, (see + * Note, if the data pointer is used as the data itself, (see * ftrace_func_mapper_find_ip(), then the return value may be meaningless, * if the data pointer was set to zero. */ @@ -5195,8 +5195,6 @@ int register_ftrace_direct(unsigned long goto out_unlock;
ret = ftrace_set_filter_ip(&direct_ops, ip, 0, 0); - if (ret) - remove_hash_entry(direct_functions, entry);
if (!ret && !(direct_ops.flags & FTRACE_OPS_FL_ENABLED)) { ret = register_ftrace_function(&direct_ops); @@ -5205,6 +5203,7 @@ int register_ftrace_direct(unsigned long }
if (ret) { + remove_hash_entry(direct_functions, entry); kfree(entry); if (!direct->count) { list_del_rcu(&direct->next);
From: Hyunchul Lee hyc.lee@gmail.com
commit 376b9133826865568167b4091ef92a68c4622b87 upstream.
outstanding credits must be initialized to 0, because it means the sum of credits consumed by in-flight requests. And outstanding credits must be compared with total credits in smb2_validate_credit_charge(), because total credits are the sum of credits granted by ksmbd.
This patch fix the following error, while frametest with Windows clients:
Limits exceeding the maximum allowable outstanding requests, given : 128, pending : 8065
Fixes: b589f5db6d4a ("ksmbd: limits exceeding the maximum allowable outstanding requests") Cc: stable@vger.kernel.org Signed-off-by: Hyunchul Lee hyc.lee@gmail.com Reported-by: Yufan Chen wiz.chen@gmail.com Tested-by: Yufan Chen wiz.chen@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/connection.c | 2 +- fs/ksmbd/smb2misc.c | 2 +- fs/ksmbd/smb_common.c | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-)
--- a/fs/ksmbd/connection.c +++ b/fs/ksmbd/connection.c @@ -62,7 +62,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void atomic_set(&conn->req_running, 0); atomic_set(&conn->r_count, 0); conn->total_credits = 1; - conn->outstanding_credits = 1; + conn->outstanding_credits = 0;
init_waitqueue_head(&conn->req_running_q); INIT_LIST_HEAD(&conn->conns_list); --- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -338,7 +338,7 @@ static int smb2_validate_credit_charge(s ret = 1; }
- if ((u64)conn->outstanding_credits + credit_charge > conn->vals->max_credits) { + if ((u64)conn->outstanding_credits + credit_charge > conn->total_credits) { ksmbd_debug(SMB, "Limits exceeding the maximum allowable outstanding requests, given : %u, pending : %u\n", credit_charge, conn->outstanding_credits); ret = 1; --- a/fs/ksmbd/smb_common.c +++ b/fs/ksmbd/smb_common.c @@ -140,8 +140,10 @@ int ksmbd_verify_smb_message(struct ksmb
hdr = work->request_buf; if (*(__le32 *)hdr->Protocol == SMB1_PROTO_NUMBER && - hdr->Command == SMB_COM_NEGOTIATE) + hdr->Command == SMB_COM_NEGOTIATE) { + work->conn->outstanding_credits++; return 0; + }
return -EINVAL; }
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 8b9ad480bd1dd25f4ff4854af5685fa334a2f57a upstream.
The bug is here: if (!iommu || iommu->dev->of_node != spec->np) {
The list iterator value 'iommu' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found (in fact, it will point to a invalid structure object containing HEAD).
To fix the bug, use a new value 'iter' as the list iterator, while use the old value 'iommu' as a dedicated variable to point to the found one, and remove the unneeded check for 'iommu->dev->of_node != spec->np' outside the loop.
Cc: stable@vger.kernel.org Fixes: f78ebca8ff3d6 ("iommu/msm: Add support for generic master bindings") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Link: https://lore.kernel.org/r/20220501132823.12714-1-xiam0nd.tong@gmail.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iommu/msm_iommu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -610,16 +610,19 @@ static void insert_iommu_master(struct d static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *spec) { - struct msm_iommu_dev *iommu; + struct msm_iommu_dev *iommu = NULL, *iter; unsigned long flags; int ret = 0;
spin_lock_irqsave(&msm_iommu_lock, flags); - list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) - if (iommu->dev->of_node == spec->np) + list_for_each_entry(iter, &qcom_iommu_devices, dev_node) { + if (iter->dev->of_node == spec->np) { + iommu = iter; break; + } + }
- if (!iommu || iommu->dev->of_node != spec->np) { + if (!iommu) { ret = -ENODEV; goto fail; }
From: Yunfei Wang yf.wang@mediatek.com
commit a3884774d731f03d3a3dd4fb70ec2d9341ceb39d upstream.
The data type of the return value of the iommu_map_sg_atomic is ssize_t, but the data type of iova size is size_t, e.g. one is int while the other is unsigned int.
When iommu_map_sg_atomic return value is compared with iova size, it will force the signed int to be converted to unsigned int, if iova map fails and iommu_map_sg_atomic return error code is less than 0, then (ret < iova_len) is false, which will to cause not do free iova, and the master can still successfully get the iova of map fail, which is not expected.
Therefore, we need to check the return value of iommu_map_sg_atomic in two cases according to whether it is less than 0.
Fixes: ad8f36e4b6b1 ("iommu: return full error code from iommu_map_sg[_atomic]()") Signed-off-by: Yunfei Wang yf.wang@mediatek.com Cc: stable@vger.kernel.org # 5.15.* Reviewed-by: Robin Murphy robin.murphy@arm.com Reviewed-by: Miles Chen miles.chen@mediatek.com Link: https://lore.kernel.org/r/20220507085204.16914-1-yf.wang@mediatek.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iommu/dma-iommu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -776,6 +776,7 @@ static struct page **__iommu_dma_alloc_n unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap; struct page **pages; dma_addr_t iova; + ssize_t ret;
if (static_branch_unlikely(&iommu_deferred_attach_enabled) && iommu_deferred_attach(dev, domain)) @@ -813,8 +814,8 @@ static struct page **__iommu_dma_alloc_n arch_dma_prep_coherent(sg_page(sg), sg->length); }
- if (iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, ioprot) - < size) + ret = iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, ioprot); + if (ret < 0 || ret < size) goto out_free_sg;
sgt->sgl->dma_address = iova; @@ -1209,7 +1210,7 @@ static int iommu_dma_map_sg(struct devic * implementation - it knows better than we do. */ ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot); - if (ret < iova_len) + if (ret < 0 || ret < iova_len) goto out_free_iova;
return __finalise_sg(dev, sg, nents, iova);
From: Masami Hiramatsu mhiramat@kernel.org
commit 43994049180704fd1faf78623fabd9a5cd443708 upstream.
Max Filippov reported:
When building kernel with CONFIG_KRETPROBES=n kernel/kprobes.c compilation fails with the following messages:
kernel/kprobes.c: In function ‘recycle_rp_inst’: kernel/kprobes.c:1273:32: error: implicit declaration of function ‘get_kretprobe’
kernel/kprobes.c: In function ‘kprobe_flush_task’: kernel/kprobes.c:1299:35: error: ‘struct task_struct’ has no member named ‘kretprobe_instances’
This came from the commit d741bf41d7c7 ("kprobes: Remove kretprobe hash") which introduced get_kretprobe() and kretprobe_instances member in task_struct when CONFIG_KRETPROBES=y, but did not make recycle_rp_inst() and kprobe_flush_task() depending on CONFIG_KRETPORBES.
Since those functions are only used for kretprobe, move those functions into #ifdef CONFIG_KRETPROBE area.
Link: https://lkml.kernel.org/r/165163539094.74407.3838114721073251225.stgit@devno...
Reported-by: Max Filippov jcmvbkbc@gmail.com Fixes: d741bf41d7c7 ("kprobes: Remove kretprobe hash") Cc: "Naveen N . Rao" naveen.n.rao@linux.ibm.com Cc: Anil S Keshavamurthy anil.s.keshavamurthy@intel.com Cc: "David S . Miller" davem@davemloft.net Cc: Peter Zijlstra peterz@infradead.org Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Tested-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/kprobes.h | 2 kernel/kprobes.c | 144 +++++++++++++++++++++++------------------------- 2 files changed, 72 insertions(+), 74 deletions(-)
--- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -424,7 +424,7 @@ void unregister_kretprobe(struct kretpro int register_kretprobes(struct kretprobe **rps, int num); void unregister_kretprobes(struct kretprobe **rps, int num);
-#ifdef CONFIG_KRETPROBE_ON_RETHOOK +#if defined(CONFIG_KRETPROBE_ON_RETHOOK) || !defined(CONFIG_KRETPROBES) #define kprobe_flush_task(tk) do {} while (0) #else void kprobe_flush_task(struct task_struct *tk); --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -1257,79 +1257,6 @@ void kprobe_busy_end(void) preempt_enable(); }
-#if !defined(CONFIG_KRETPROBE_ON_RETHOOK) -static void free_rp_inst_rcu(struct rcu_head *head) -{ - struct kretprobe_instance *ri = container_of(head, struct kretprobe_instance, rcu); - - if (refcount_dec_and_test(&ri->rph->ref)) - kfree(ri->rph); - kfree(ri); -} -NOKPROBE_SYMBOL(free_rp_inst_rcu); - -static void recycle_rp_inst(struct kretprobe_instance *ri) -{ - struct kretprobe *rp = get_kretprobe(ri); - - if (likely(rp)) - freelist_add(&ri->freelist, &rp->freelist); - else - call_rcu(&ri->rcu, free_rp_inst_rcu); -} -NOKPROBE_SYMBOL(recycle_rp_inst); - -/* - * This function is called from delayed_put_task_struct() when a task is - * dead and cleaned up to recycle any kretprobe instances associated with - * this task. These left over instances represent probed functions that - * have been called but will never return. - */ -void kprobe_flush_task(struct task_struct *tk) -{ - struct kretprobe_instance *ri; - struct llist_node *node; - - /* Early boot, not yet initialized. */ - if (unlikely(!kprobes_initialized)) - return; - - kprobe_busy_begin(); - - node = __llist_del_all(&tk->kretprobe_instances); - while (node) { - ri = container_of(node, struct kretprobe_instance, llist); - node = node->next; - - recycle_rp_inst(ri); - } - - kprobe_busy_end(); -} -NOKPROBE_SYMBOL(kprobe_flush_task); - -static inline void free_rp_inst(struct kretprobe *rp) -{ - struct kretprobe_instance *ri; - struct freelist_node *node; - int count = 0; - - node = rp->freelist.head; - while (node) { - ri = container_of(node, struct kretprobe_instance, freelist); - node = node->next; - - kfree(ri); - count++; - } - - if (refcount_sub_and_test(count, &rp->rph->ref)) { - kfree(rp->rph); - rp->rph = NULL; - } -} -#endif /* !CONFIG_KRETPROBE_ON_RETHOOK */ - /* Add the new probe to 'ap->list'. */ static int add_new_kprobe(struct kprobe *ap, struct kprobe *p) { @@ -1928,6 +1855,77 @@ static struct notifier_block kprobe_exce #ifdef CONFIG_KRETPROBES
#if !defined(CONFIG_KRETPROBE_ON_RETHOOK) +static void free_rp_inst_rcu(struct rcu_head *head) +{ + struct kretprobe_instance *ri = container_of(head, struct kretprobe_instance, rcu); + + if (refcount_dec_and_test(&ri->rph->ref)) + kfree(ri->rph); + kfree(ri); +} +NOKPROBE_SYMBOL(free_rp_inst_rcu); + +static void recycle_rp_inst(struct kretprobe_instance *ri) +{ + struct kretprobe *rp = get_kretprobe(ri); + + if (likely(rp)) + freelist_add(&ri->freelist, &rp->freelist); + else + call_rcu(&ri->rcu, free_rp_inst_rcu); +} +NOKPROBE_SYMBOL(recycle_rp_inst); + +/* + * This function is called from delayed_put_task_struct() when a task is + * dead and cleaned up to recycle any kretprobe instances associated with + * this task. These left over instances represent probed functions that + * have been called but will never return. + */ +void kprobe_flush_task(struct task_struct *tk) +{ + struct kretprobe_instance *ri; + struct llist_node *node; + + /* Early boot, not yet initialized. */ + if (unlikely(!kprobes_initialized)) + return; + + kprobe_busy_begin(); + + node = __llist_del_all(&tk->kretprobe_instances); + while (node) { + ri = container_of(node, struct kretprobe_instance, llist); + node = node->next; + + recycle_rp_inst(ri); + } + + kprobe_busy_end(); +} +NOKPROBE_SYMBOL(kprobe_flush_task); + +static inline void free_rp_inst(struct kretprobe *rp) +{ + struct kretprobe_instance *ri; + struct freelist_node *node; + int count = 0; + + node = rp->freelist.head; + while (node) { + ri = container_of(node, struct kretprobe_instance, freelist); + node = node->next; + + kfree(ri); + count++; + } + + if (refcount_sub_and_test(count, &rp->rph->ref)) { + kfree(rp->rph); + rp->rph = NULL; + } +} + /* This assumes the 'tsk' is the current task or the is not running. */ static kprobe_opcode_t *__kretprobe_find_ret_addr(struct task_struct *tsk, struct llist_node **cur)
From: Dong Aisheng aisheng.dong@nxp.com
commit 60a60e32cf91169840abcb4a80f0b0df31708ba7 upstream.
This reverts commit a4efc174b382fcdb which introduced a regression issue that when there're multiple processes allocating dma memory in parallel by calling dma_alloc_coherent(), it may fail sometimes as follows:
Error log: cma: cma_alloc: linux,cma: alloc failed, req-size: 148 pages, ret: -16 cma: number of available pages: 3@125+20@172+12@236+4@380+32@736+17@2287+23@2473+20@36076+99@40477+108@40852+44@41108+20@41196+108@41364+108@41620+ 108@42900+108@43156+483@44061+1763@45341+1440@47712+20@49324+20@49388+5076@49452+2304@55040+35@58141+20@58220+20@58284+ 7188@58348+84@66220+7276@66452+227@74525+6371@75549=> 33161 free of 81920 total pages
When issue happened, we saw there were still 33161 pages (129M) free CMA memory and a lot available free slots for 148 pages in CMA bitmap that we want to allocate.
When dumping memory info, we found that there was also ~342M normal memory, but only 1352K CMA memory left in buddy system while a lot of pageblocks were isolated.
Memory info log: Normal free:351096kB min:30000kB low:37500kB high:45000kB reserved_highatomic:0KB active_anon:98060kB inactive_anon:98948kB active_file:60864kB inactive_file:31776kB unevictable:0kB writepending:0kB present:1048576kB managed:1018328kB mlocked:0kB bounce:0kB free_pcp:220kB local_pcp:192kB free_cma:1352kB lowmem_reserve[]: 0 0 0 Normal: 78*4kB (UECI) 1772*8kB (UMECI) 1335*16kB (UMECI) 360*32kB (UMECI) 65*64kB (UMCI) 36*128kB (UMECI) 16*256kB (UMCI) 6*512kB (EI) 8*1024kB (UEI) 4*2048kB (MI) 8*4096kB (EI) 8*8192kB (UI) 3*16384kB (EI) 8*32768kB (M) = 489288kB
The root cause of this issue is that since commit a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock"), CMA supports concurrent memory allocation. It's possible that the memory range process A trying to alloc has already been isolated by the allocation of process B during memory migration.
The problem here is that the memory range isolated during one allocation by start_isolate_page_range() could be much bigger than the real size we want to alloc due to the range is aligned to MAX_ORDER_NR_PAGES.
Taking an ARMv7 platform with 1G memory as an example, when MAX_ORDER_NR_PAGES is big (e.g. 32M with max_order 14) and CMA memory is relatively small (e.g. 128M), there're only 4 MAX_ORDER slot, then it's very easy that all CMA memory may have already been isolated by other processes when one trying to allocate memory using dma_alloc_coherent(). Since current CMA code will only scan one time of whole available CMA memory, then dma_alloc_coherent() may easy fail due to contention with other processes.
This patch simply falls back to the original method that using cma_mutex to make alloc_contig_range() run sequentially to avoid the issue.
Link: https://lkml.kernel.org/r/20220509094551.3596244-1-aisheng.dong@nxp.com Link: https://lore.kernel.org/all/20220315144521.3810298-2-aisheng.dong@nxp.com/ Fixes: a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock") Signed-off-by: Dong Aisheng aisheng.dong@nxp.com Acked-by: Minchan Kim minchan@kernel.org Acked-by: David Hildenbrand david@redhat.com Cc: Marek Szyprowski m.szyprowski@samsung.com Cc: Lecopzer Chen lecopzer.chen@mediatek.com Cc: Vlastimil Babka vbabka@suse.cz Cc: stable@vger.kernel.org [5.11+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/cma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/mm/cma.c +++ b/mm/cma.c @@ -37,6 +37,7 @@
struct cma cma_areas[MAX_CMA_AREAS]; unsigned cma_area_count; +static DEFINE_MUTEX(cma_mutex);
phys_addr_t cma_get_base(const struct cma *cma) { @@ -468,9 +469,10 @@ struct page *cma_alloc(struct cma *cma, spin_unlock_irq(&cma->lock);
pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); + mutex_lock(&cma_mutex); ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, GFP_KERNEL | (no_warn ? __GFP_NOWARN : 0)); - + mutex_unlock(&cma_mutex); if (ret == 0) { page = pfn_to_page(pfn); break;
From: Eric Dumazet edumazet@google.com
commit cd8c1fd8cdd14158f2d8bea2d1bfe8015dccfa3a upstream.
current->comm[] is not a string (no guarantee for a zero byte in it).
strlcpy(s1, s2, l) is calling strlen(s2), potentially causing out-of-bound access, as reported by syzbot:
detected buffer overflow in __fortify_strlen ------------[ cut here ]------------ kernel BUG at lib/string_helpers.c:980! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 4087 Comm: dhcpcd-run-hooks Not tainted 5.18.0-rc3-syzkaller-01537-g20b87e7c29df #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:fortify_panic+0x18/0x1a lib/string_helpers.c:980 Code: 8c e8 c5 ba e1 fa e9 23 0f bf fa e8 0b 5d 8c f8 eb db 55 48 89 fd e8 e0 49 40 f8 48 89 ee 48 c7 c7 80 f5 26 8a e8 99 09 f1 ff <0f> 0b e8 ca 49 40 f8 48 8b 54 24 18 4c 89 f1 48 c7 c7 00 00 27 8a RSP: 0018:ffffc900000074a8 EFLAGS: 00010286
RAX: 000000000000002c RBX: ffff88801226b728 RCX: 0000000000000000 RDX: ffff8880198e0000 RSI: ffffffff81600458 RDI: fffff52000000e87 RBP: ffffffff89da2aa0 R08: 000000000000002c R09: 0000000000000000 R10: ffffffff815fae2e R11: 0000000000000000 R12: ffff88801226b700 R13: ffff8880198e0830 R14: 0000000000000000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff8880b9c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f5876ad6ff8 CR3: 000000001a48c000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600 Call Trace: <IRQ> __fortify_strlen include/linux/fortify-string.h:128 [inline] strlcpy include/linux/fortify-string.h:143 [inline] __set_page_owner_handle+0x2b1/0x3e0 mm/page_owner.c:171 __set_page_owner+0x3e/0x50 mm/page_owner.c:190 prep_new_page mm/page_alloc.c:2441 [inline] get_page_from_freelist+0xba2/0x3e00 mm/page_alloc.c:4182 __alloc_pages+0x1b2/0x500 mm/page_alloc.c:5408 alloc_pages+0x1aa/0x310 mm/mempolicy.c:2272 alloc_slab_page mm/slub.c:1799 [inline] allocate_slab+0x26c/0x3c0 mm/slub.c:1944 new_slab mm/slub.c:2004 [inline] ___slab_alloc+0x8df/0xf20 mm/slub.c:3005 __slab_alloc.constprop.0+0x4d/0xa0 mm/slub.c:3092 slab_alloc_node mm/slub.c:3183 [inline] slab_alloc mm/slub.c:3225 [inline] __kmem_cache_alloc_lru mm/slub.c:3232 [inline] kmem_cache_alloc+0x360/0x3b0 mm/slub.c:3242 dst_alloc+0x146/0x1f0 net/core/dst.c:92
Link: https://lkml.kernel.org/r/20220509145949.265184-1-eric.dumazet@gmail.com Fixes: 865ed6a32786 ("mm/page_owner: record task command name") Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Acked-by: Waiman Long longman@redhat.com Acked-by: Shakeel Butt shakeelb@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/page_owner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -168,7 +168,7 @@ static inline void __set_page_owner_hand page_owner->pid = current->pid; page_owner->tgid = current->tgid; page_owner->ts_nsec = local_clock(); - strlcpy(page_owner->comm, current->comm, + strscpy(page_owner->comm, current->comm, sizeof(page_owner->comm)); __set_bit(PAGE_EXT_OWNER, &page_ext->flags); __set_bit(PAGE_EXT_OWNER_ALLOCATED, &page_ext->flags);
From: Mel Gorman mgorman@techsingularity.net
commit c572e4888ad1be123c1516ec577ad30a700bbec4 upstream.
Peter Pavlisko reported the following problem on kernel bugzilla 216007.
When I try to extract an uncompressed tar archive (2.6 milion files, 760.3 GiB in size) on newly created (empty) XFS file system, after first low tens of gigabytes extracted the process hangs in iowait indefinitely. One CPU core is 100% occupied with iowait, the other CPU core is idle (on 2-core Intel Celeron G1610T).
It was bisected to c9fa563072e1 ("xfs: use alloc_pages_bulk_array() for buffers") but XFS is only the messenger. The problem is that nothing is waking kswapd to reclaim some pages at a time the PCP lists cannot be refilled until some reclaim happens. The bulk allocator checks that there are some pages in the array and the original intent was that a bulk allocator did not necessarily need all the requested pages and it was best to return as quickly as possible.
This was fine for the first user of the API but both NFS and XFS require the requested number of pages be available before making progress. Both could be adjusted to call the page allocator directly if a bulk allocation fails but it puts a burden on users of the API. Adjust the semantics to attempt at least one allocation via __alloc_pages() before returning so kswapd is woken if necessary.
It was reported via bugzilla that the patch addressed the problem and that the tar extraction completed successfully. This may also address bug 215975 but has yet to be confirmed.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=216007 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215975 Link: https://lkml.kernel.org/r/20220526091210.GC3441@techsingularity.net Fixes: 387ba26fb1cb ("mm/page_alloc: add a bulk page allocator") Signed-off-by: Mel Gorman mgorman@techsingularity.net Cc: "Darrick J. Wong" djwong@kernel.org Cc: Dave Chinner dchinner@redhat.com Cc: Jan Kara jack@suse.cz Cc: Vlastimil Babka vbabka@suse.cz Cc: Jesper Dangaard Brouer brouer@redhat.com Cc: Chuck Lever chuck.lever@oracle.com Cc: stable@vger.kernel.org [5.13+] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5324,8 +5324,8 @@ unsigned long __alloc_pages_bulk(gfp_t g page = __rmqueue_pcplist(zone, 0, ac.migratetype, alloc_flags, pcp, pcp_list); if (unlikely(!page)) { - /* Try and get at least one page */ - if (!nr_populated) + /* Try and allocate at least one page */ + if (!nr_account) goto failed_irq; break; }
From: Christophe de Dinechin dinechin@redhat.com
commit 37462a920392cb86541650a6f4121155f11f1199 upstream.
With gcc version 12.0.1 20220401 (Red Hat 12.0.1-0), building with defconfig results in the following compilation error:
| CC mm/swapfile.o | mm/swapfile.c: In function `setup_swap_info': | mm/swapfile.c:2291:47: error: array subscript -1 is below array bounds | of `struct plist_node[]' [-Werror=array-bounds] | 2291 | p->avail_lists[i].prio = 1; | | ~~~~~~~~~~~~~~^~~ | In file included from mm/swapfile.c:16: | ./include/linux/swap.h:292:27: note: while referencing `avail_lists' | 292 | struct plist_node avail_lists[]; /* | | ^~~~~~~~~~~
This is due to the compiler detecting that the mask in node_states[__state] could theoretically be zero, which would lead to first_node() returning -1 through find_first_bit.
I believe that the warning/error is legitimate. I first tried adding a test to check that the node mask is not emtpy, since a similar test exists in the case where MAX_NUMNODES == 1.
However, adding the if statement causes other warnings to appear in for_each_cpu_node_but, because it introduces a dangling else ambiguity. And unfortunately, GCC is not smart enough to detect that the added test makes the case where (node) == -1 impossible, so it still complains with the same message.
This is why I settled on replacing that with a harmless, but relatively useless (node) >= 0 test. Based on the warning for the dangling else, I also decided to fix the case where MAX_NUMNODES == 1 by moving the condition inside the for loop. It will still only be tested once. This ensures that the meaning of an else following for_each_node_mask or derivatives would not silently have a different meaning depending on the configuration.
Link: https://lkml.kernel.org/r/20220414150855.2407137-3-dinechin@redhat.com Signed-off-by: Christophe de Dinechin christophe@dinechin.org Signed-off-by: Christophe de Dinechin dinechin@redhat.com Reviewed-by: Andrew Morton akpm@linux-foundation.org Cc: Ben Segall bsegall@google.com Cc: "Michael S. Tsirkin" mst@redhat.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Ingo Molnar mingo@redhat.com Cc: Mel Gorman mgorman@suse.de Cc: Dietmar Eggemann dietmar.eggemann@arm.com Cc: Vincent Guittot vincent.guittot@linaro.org Cc: Paolo Bonzini pbonzini@redhat.com Cc: Daniel Bristot de Oliveira bristot@redhat.com Cc: Jason Wang jasowang@redhat.com Cc: Zhen Lei thunder.leizhen@huawei.com Cc: Juri Lelli juri.lelli@redhat.com Cc: Peter Zijlstra peterz@infradead.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/nodemask.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
--- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h @@ -375,14 +375,13 @@ static inline void __nodes_fold(nodemask }
#if MAX_NUMNODES > 1 -#define for_each_node_mask(node, mask) \ - for ((node) = first_node(mask); \ - (node) < MAX_NUMNODES; \ - (node) = next_node((node), (mask))) +#define for_each_node_mask(node, mask) \ + for ((node) = first_node(mask); \ + (node >= 0) && (node) < MAX_NUMNODES; \ + (node) = next_node((node), (mask))) #else /* MAX_NUMNODES == 1 */ -#define for_each_node_mask(node, mask) \ - if (!nodes_empty(mask)) \ - for ((node) = 0; (node) < 1; (node)++) +#define for_each_node_mask(node, mask) \ + for ((node) = 0; (node) < 1 && !nodes_empty(mask); (node)++) #endif /* MAX_NUMNODES */
/*
From: Mike Kravetz mike.kravetz@oracle.com
commit 48381273f8734d28ef56a5bdf1966dd8530111bc upstream.
The routine huge_pmd_unshare() is passed a pointer to an address associated with an area which may be unshared. If unshare is successful this address is updated to 'optimize' callers iterating over huge page addresses. For the optimization to work correctly, address should be updated to the last huge page in the unmapped/unshared area. However, in the common case where the passed address is PUD_SIZE aligned, the address is incorrectly updated to the address of the preceding huge page. That wastes CPU cycles as the unmapped/unshared range is scanned twice.
Link: https://lkml.kernel.org/r/20220524205003.126184-1-mike.kravetz@oracle.com Fixes: 39dde65c9940 ("shared page table for hugetlb page") Signed-off-by: Mike Kravetz mike.kravetz@oracle.com Acked-by: Muchun Song songmuchun@bytedance.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/hugetlb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -6562,7 +6562,14 @@ int huge_pmd_unshare(struct mm_struct *m pud_clear(pud); put_page(virt_to_page(ptep)); mm_dec_nr_pmds(mm); - *addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE; + /* + * This update of passed address optimizes loops sequentially + * processing addresses in increments of huge page size (PMD_SIZE + * in this case). By clearing the pud, a PUD_SIZE area is unmapped. + * Update address to the 'last page' in the cleared area so that + * calling loop can move to first page past this area. + */ + *addr |= PUD_SIZE - PMD_SIZE; return 1; }
From: Miaohe Lin linmiaohe@huawei.com
commit a04e1928e2ead144dc2f369768bc0a0f3110af89 upstream.
We forget to call untrack_pfn() to pair with track_pfn_remap() when range is not allowed to hotplug. Fix it by jump err_kasan.
Link: https://lkml.kernel.org/r/20220531122643.25249-1-linmiaohe@huawei.com Fixes: bca3feaa0764 ("mm/memory_hotplug: prevalidate the address range being added with platform") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Reviewed-by: David Hildenbrand david@redhat.com Acked-by: Muchun Song songmuchun@bytedance.com Cc: Anshuman Khandual anshuman.khandual@arm.com Cc: Oscar Salvador osalvador@suse.de Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/memremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/memremap.c +++ b/mm/memremap.c @@ -214,7 +214,7 @@ static int pagemap_range(struct dev_page
if (!mhp_range_allowed(range->start, range_len(range), !is_private)) { error = -EINVAL; - goto err_pfn_remap; + goto err_kasan; }
mem_hotplug_begin();
From: Yi Yang yiyang13@huawei.com
commit b011946d039d66bbc7102137e98cc67e1356aa87 upstream.
The commit a69755b18774 ("xtensa simdisk: switch to proc_create_data()") split read operation into two parts, first retrieving the path when it's non-null and second retrieving the trailing '\n'. However when the path is non-null the first simple_read_from_buffer updates ppos, and the second simple_read_from_buffer returns 0 if ppos is greater than 1 (i.e. almost always). As a result reading from that proc file is almost always empty.
Fix it by making a temporary copy of the path with the trailing '\n' and using simple_read_from_buffer on that copy.
Cc: stable@vger.kernel.org Fixes: a69755b18774 ("xtensa simdisk: switch to proc_create_data()") Signed-off-by: Yi Yang yiyang13@huawei.com Signed-off-by: Max Filippov jcmvbkbc@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/xtensa/platforms/iss/simdisk.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
--- a/arch/xtensa/platforms/iss/simdisk.c +++ b/arch/xtensa/platforms/iss/simdisk.c @@ -211,12 +211,18 @@ static ssize_t proc_read_simdisk(struct struct simdisk *dev = pde_data(file_inode(file)); const char *s = dev->filename; if (s) { - ssize_t n = simple_read_from_buffer(buf, size, ppos, - s, strlen(s)); - if (n < 0) - return n; - buf += n; - size -= n; + ssize_t len = strlen(s); + char *temp = kmalloc(len + 2, GFP_KERNEL); + + if (!temp) + return -ENOMEM; + + len = scnprintf(temp, len + 2, "%s\n", s); + len = simple_read_from_buffer(buf, size, ppos, + temp, len); + + kfree(temp); + return len; } return simple_read_from_buffer(buf, size, ppos, "\n", 1); }
From: Alexander Wetzel alexander@wetzel-home.de
commit 746285cf81dc19502ab238249d75f5990bd2d231 upstream.
Using not existing queues can panic the kernel with rtl8180/rtl8185 cards. Ignore the skb priority for those cards, they only have one tx queue. Pierre Asselin (pa@panix.com) reported the kernel crash in the Gentoo forum:
https://forums.gentoo.org/viewtopic-t-1147832-postdays-0-postorder-asc-start...
He also confirmed that this patch fixes the issue. In summary this happened:
After updating wpa_supplicant from 2.9 to 2.10 the kernel crashed with a "divide error: 0000" when connecting to an AP. Control port tx now tries to use IEEE80211_AC_VO for the priority, which wpa_supplicants starts to use in 2.10.
Since only the rtl8187se part of the driver supports QoS, the priority of the skb is set to IEEE80211_AC_BE (2) by mac80211 for rtl8180/rtl8185 cards.
rtl8180 is then unconditionally reading out the priority and finally crashes on drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c line 544 without this patch: idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries
"ring->entries" is zero for rtl8180/rtl8185 cards, tx_ring[2] never got initialized.
Cc: stable@vger.kernel.org Reported-by: pa@panix.com Tested-by: pa@panix.com Signed-off-by: Alexander Wetzel alexander@wetzel-home.de Signed-off-by: Kalle Valo kvalo@kernel.org Link: https://lore.kernel.org/r/20220422145228.7567-1-alexander@wetzel-home.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c @@ -460,8 +460,10 @@ static void rtl8180_tx(struct ieee80211_ struct rtl8180_priv *priv = dev->priv; struct rtl8180_tx_ring *ring; struct rtl8180_tx_desc *entry; + unsigned int prio = 0; unsigned long flags; - unsigned int idx, prio, hw_prio; + unsigned int idx, hw_prio; + dma_addr_t mapping; u32 tx_flags; u8 rc_flags; @@ -470,7 +472,9 @@ static void rtl8180_tx(struct ieee80211_ /* do arithmetic and then convert to le16 */ u16 frame_duration = 0;
- prio = skb_get_queue_mapping(skb); + /* rtl8180/rtl8185 only has one useable tx queue */ + if (dev->queues > IEEE80211_AC_BK) + prio = skb_get_queue_mapping(skb); ring = &priv->tx_ring[prio];
mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
From: Mark Brown broonie@kernel.org
commit 4213ff556740bb45e2d9ff0f50d056c4e7dd0921 upstream.
The driver has a custom put function for "DSP Voice Wake Up" which does not generate event notifications on change, instead returning 0. Since we already exit early in the case that there is no change this can be fixed by unconditionally returning 1 at the end of the function.
Signed-off-by: Mark Brown broonie@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220428162444.3883147-1-broonie@kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/codecs/rt5514.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c @@ -419,7 +419,7 @@ static int rt5514_dsp_voice_wake_up_put( } }
- return 0; + return 1; }
static const struct snd_kcontrol_new rt5514_snd_controls[] = {
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 54a6f29522da3c914da30e50721dedf51046449a upstream.
If the previous list_for_each_entry_continue_rcu() don't exit early (no goto hit inside the loop), the iterator 'cvif' after the loop will be a bogus pointer to an invalid structure object containing the HEAD (&ar->vif_list). As a result, the use of 'cvif' after that will lead to a invalid memory access (i.e., 'cvif->id': the invalid pointer dereference when return back to/after the callsite in the carl9170_update_beacon()).
The original intention should have been to return the valid 'cvif' when found in list, NULL otherwise. So just return NULL when no entry found, to fix this bug.
Cc: stable@vger.kernel.org Fixes: 1f1d9654e183c ("carl9170: refactor carl9170_update_beacon") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Acked-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Kalle Valo quic_kvalo@quicinc.com Link: https://lore.kernel.org/r/20220328122820.1004-1-xiam0nd.tong@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/carl9170/tx.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1558,6 +1558,9 @@ static struct carl9170_vif_info *carl917 goto out; } } while (ar->beacon_enabled && i--); + + /* no entry found in list */ + return NULL; }
out:
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 2e6c86be0e57079d1fb6c7c7e5423db096d0548a upstream.
The two bugs are here: if (encoder) { if (bridge && bridge->timings)
The list iterator value 'encoder/bridge' will *always* be set and non-NULL by drm_for_each_encoder()/list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found.
To fix the bug, use a new variable '*_iter' as the list iterator, while use the old variable 'encoder/bridge' as a dedicated pointer to point to the found element.
Cc: stable@vger.kernel.org Fixes: 99e360442f223 ("drm/stm: Fix bus_flags handling") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Acked-by: Raphael Gallais-Pou raphael.gallais-pou@foss.st.com Signed-off-by: Philippe Cornu philippe.cornu@foss.st.com Link: https://patchwork.freedesktop.org/patch/msgid/20220327055355.3808-1-xiam0nd.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/stm/ltdc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -869,8 +869,8 @@ static void ltdc_crtc_mode_set_nofb(stru struct drm_device *ddev = crtc->dev; struct drm_connector_list_iter iter; struct drm_connector *connector = NULL; - struct drm_encoder *encoder = NULL; - struct drm_bridge *bridge = NULL; + struct drm_encoder *encoder = NULL, *en_iter; + struct drm_bridge *bridge = NULL, *br_iter; struct drm_display_mode *mode = &crtc->state->adjusted_mode; u32 hsync, vsync, accum_hbp, accum_vbp, accum_act_w, accum_act_h; u32 total_width, total_height; @@ -880,15 +880,19 @@ static void ltdc_crtc_mode_set_nofb(stru int ret;
/* get encoder from crtc */ - drm_for_each_encoder(encoder, ddev) - if (encoder->crtc == crtc) + drm_for_each_encoder(en_iter, ddev) + if (en_iter->crtc == crtc) { + encoder = en_iter; break; + }
if (encoder) { /* get bridge from encoder */ - list_for_each_entry(bridge, &encoder->bridge_chain, chain_node) - if (bridge->encoder == encoder) + list_for_each_entry(br_iter, &encoder->bridge_chain, chain_node) + if (br_iter->encoder == encoder) { + bridge = br_iter; break; + }
/* Get the connector from encoder */ drm_connector_list_iter_begin(ddev, &iter);
From: Coly Li colyli@suse.de
commit 622536443b6731ec82c563aae7807165adbe9178 upstream.
Commit 8e7102273f59 ("bcache: make bch_btree_check() to be multithreaded") makes bch_btree_check() to be much faster when checking all btree nodes during cache device registration. But it isn't in ideal shap yet, still can be improved.
This patch does the following thing to improve current parallel btree nodes check by multiple threads in bch_btree_check(), - Add read lock to root node while checking all the btree nodes with multiple threads. Although currently it is not mandatory but it is good to have a read lock in code logic. - Remove local variable 'char name[32]', and generate kernel thread name string directly when calling kthread_run(). - Allocate local variable "struct btree_check_state check_state" on the stack and avoid unnecessary dynamic memory allocation for it. - Reduce BCH_BTR_CHKTHREAD_MAX from 64 to 12 which is enough indeed. - Increase check_state->started to count created kernel thread after it succeeds to create. - When wait for all checking kernel threads to finish, use wait_event() to replace wait_event_interruptible().
With this change, the code is more clear, and some potential error conditions are avoided.
Fixes: 8e7102273f59 ("bcache: make bch_btree_check() to be multithreaded") Signed-off-by: Coly Li colyli@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220524102336.10684-2-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/btree.c | 58 ++++++++++++++++++++-------------------------- drivers/md/bcache/btree.h | 2 - 2 files changed, 27 insertions(+), 33 deletions(-)
--- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -2006,8 +2006,7 @@ int bch_btree_check(struct cache_set *c) int i; struct bkey *k = NULL; struct btree_iter iter; - struct btree_check_state *check_state; - char name[32]; + struct btree_check_state check_state;
/* check and mark root node keys */ for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) @@ -2018,63 +2017,58 @@ int bch_btree_check(struct cache_set *c) if (c->root->level == 0) return 0;
- check_state = kzalloc(sizeof(struct btree_check_state), GFP_KERNEL); - if (!check_state) - return -ENOMEM; - - check_state->c = c; - check_state->total_threads = bch_btree_chkthread_nr(); - check_state->key_idx = 0; - spin_lock_init(&check_state->idx_lock); - atomic_set(&check_state->started, 0); - atomic_set(&check_state->enough, 0); - init_waitqueue_head(&check_state->wait); + check_state.c = c; + check_state.total_threads = bch_btree_chkthread_nr(); + check_state.key_idx = 0; + spin_lock_init(&check_state.idx_lock); + atomic_set(&check_state.started, 0); + atomic_set(&check_state.enough, 0); + init_waitqueue_head(&check_state.wait);
+ rw_lock(0, c->root, c->root->level); /* * Run multiple threads to check btree nodes in parallel, - * if check_state->enough is non-zero, it means current + * if check_state.enough is non-zero, it means current * running check threads are enough, unncessary to create * more. */ - for (i = 0; i < check_state->total_threads; i++) { - /* fetch latest check_state->enough earlier */ + for (i = 0; i < check_state.total_threads; i++) { + /* fetch latest check_state.enough earlier */ smp_mb__before_atomic(); - if (atomic_read(&check_state->enough)) + if (atomic_read(&check_state.enough)) break;
- check_state->infos[i].result = 0; - check_state->infos[i].state = check_state; - snprintf(name, sizeof(name), "bch_btrchk[%u]", i); - atomic_inc(&check_state->started); + check_state.infos[i].result = 0; + check_state.infos[i].state = &check_state;
- check_state->infos[i].thread = + check_state.infos[i].thread = kthread_run(bch_btree_check_thread, - &check_state->infos[i], - name); - if (IS_ERR(check_state->infos[i].thread)) { + &check_state.infos[i], + "bch_btrchk[%d]", i); + if (IS_ERR(check_state.infos[i].thread)) { pr_err("fails to run thread bch_btrchk[%d]\n", i); for (--i; i >= 0; i--) - kthread_stop(check_state->infos[i].thread); + kthread_stop(check_state.infos[i].thread); ret = -ENOMEM; goto out; } + atomic_inc(&check_state.started); }
/* * Must wait for all threads to stop. */ - wait_event_interruptible(check_state->wait, - atomic_read(&check_state->started) == 0); + wait_event(check_state.wait, atomic_read(&check_state.started) == 0);
- for (i = 0; i < check_state->total_threads; i++) { - if (check_state->infos[i].result) { - ret = check_state->infos[i].result; + for (i = 0; i < check_state.total_threads; i++) { + if (check_state.infos[i].result) { + ret = check_state.infos[i].result; goto out; } }
out: - kfree(check_state); + rw_unlock(0, c->root); return ret; }
--- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h @@ -226,7 +226,7 @@ struct btree_check_info { int result; };
-#define BCH_BTR_CHKTHREAD_MAX 64 +#define BCH_BTR_CHKTHREAD_MAX 12 struct btree_check_state { struct cache_set *c; int total_threads;
From: Coly Li colyli@suse.de
commit 4dc34ae1b45fe26e772a44379f936c72623dd407 upstream.
Commit b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") makes bch_sectors_dirty_init() to be much faster when counting dirty sectors by iterating all dirty keys in the btree. But it isn't in ideal shape yet, still can be improved.
This patch does the following changes to improve current parallel dirty keys iteration on the btree, - Add read lock to root node when multiple threads iterating the btree, to prevent the root node gets split by I/Os from other registered bcache devices. - Remove local variable "char name[32]" and generate kernel thread name string directly when calling kthread_run(). - Allocate "struct bch_dirty_init_state state" directly on stack and avoid the unnecessary dynamic memory allocation for it. - Decrease BCH_DIRTY_INIT_THRD_MAX from 64 to 12 which is enough indeed. - Increase &state->started to count created kernel thread after it succeeds to create. - When wait for all dirty key counting threads to finish, use wait_event() to replace wait_event_interruptible().
With the above changes, the code is more clear, and some potential error conditions are avoided.
Fixes: b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") Signed-off-by: Coly Li colyli@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220524102336.10684-3-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/writeback.c | 60 ++++++++++++++++-------------------------- drivers/md/bcache/writeback.h | 2 - 2 files changed, 25 insertions(+), 37 deletions(-)
--- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -948,10 +948,10 @@ void bch_sectors_dirty_init(struct bcach struct btree_iter iter; struct sectors_dirty_init op; struct cache_set *c = d->c; - struct bch_dirty_init_state *state; - char name[32]; + struct bch_dirty_init_state state;
/* Just count root keys if no leaf node */ + rw_lock(0, c->root, c->root->level); if (c->root->level == 0) { bch_btree_op_init(&op.op, -1); op.inode = d->id; @@ -961,54 +961,42 @@ void bch_sectors_dirty_init(struct bcach for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) sectors_dirty_init_fn(&op.op, c->root, k); + rw_unlock(0, c->root); return; }
- state = kzalloc(sizeof(struct bch_dirty_init_state), GFP_KERNEL); - if (!state) { - pr_warn("sectors dirty init failed: cannot allocate memory\n"); - return; - } + state.c = c; + state.d = d; + state.total_threads = bch_btre_dirty_init_thread_nr(); + state.key_idx = 0; + spin_lock_init(&state.idx_lock); + atomic_set(&state.started, 0); + atomic_set(&state.enough, 0); + init_waitqueue_head(&state.wait);
- state->c = c; - state->d = d; - state->total_threads = bch_btre_dirty_init_thread_nr(); - state->key_idx = 0; - spin_lock_init(&state->idx_lock); - atomic_set(&state->started, 0); - atomic_set(&state->enough, 0); - init_waitqueue_head(&state->wait); - - for (i = 0; i < state->total_threads; i++) { - /* Fetch latest state->enough earlier */ + for (i = 0; i < state.total_threads; i++) { + /* Fetch latest state.enough earlier */ smp_mb__before_atomic(); - if (atomic_read(&state->enough)) + if (atomic_read(&state.enough)) break;
- state->infos[i].state = state; - atomic_inc(&state->started); - snprintf(name, sizeof(name), "bch_dirty_init[%d]", i); - - state->infos[i].thread = - kthread_run(bch_dirty_init_thread, - &state->infos[i], - name); - if (IS_ERR(state->infos[i].thread)) { + state.infos[i].state = &state; + state.infos[i].thread = + kthread_run(bch_dirty_init_thread, &state.infos[i], + "bch_dirtcnt[%d]", i); + if (IS_ERR(state.infos[i].thread)) { pr_err("fails to run thread bch_dirty_init[%d]\n", i); for (--i; i >= 0; i--) - kthread_stop(state->infos[i].thread); + kthread_stop(state.infos[i].thread); goto out; } + atomic_inc(&state.started); }
- /* - * Must wait for all threads to stop. - */ - wait_event_interruptible(state->wait, - atomic_read(&state->started) == 0); - out: - kfree(state); + /* Must wait for all threads to stop. */ + wait_event(state.wait, atomic_read(&state.started) == 0); + rw_unlock(0, c->root); }
void bch_cached_dev_writeback_init(struct cached_dev *dc) --- a/drivers/md/bcache/writeback.h +++ b/drivers/md/bcache/writeback.h @@ -20,7 +20,7 @@ #define BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID 57 #define BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH 64
-#define BCH_DIRTY_INIT_THRD_MAX 64 +#define BCH_DIRTY_INIT_THRD_MAX 12 /* * 14 (16384ths) is chosen here as something that each backing device * should be a reasonable fraction of the share, and not to blow up
From: Coly Li colyli@suse.de
commit 80db4e4707e78cb22287da7d058d7274bd4cb370 upstream.
After making bch_sectors_dirty_init() being multithreaded, the existing incremental dirty sector counting in bch_root_node_dirty_init() doesn't release btree occupation after iterating 500000 (INIT_KEYS_EACH_TIME) bkeys. Because a read lock is added on btree root node to prevent the btree to be split during the dirty sectors counting, other I/O requester has no chance to gain the write lock even restart bcache_btree().
That is to say, the incremental dirty sectors counting is incompatible to the multhreaded bch_sectors_dirty_init(). We have to choose one and drop another one.
In my testing, with 512 bytes random writes, I generate 1.2T dirty data and a btree with 400K nodes. With single thread and incremental dirty sectors counting, it takes 30+ minites to register the backing device. And with multithreaded dirty sectors counting, the backing device registration can be accomplished within 2 minutes.
The 30+ minutes V.S. 2- minutes difference makes me decide to keep multithreaded bch_sectors_dirty_init() and drop the incremental dirty sectors counting. This is what this patch does.
But INIT_KEYS_EACH_TIME is kept, in sectors_dirty_init_fn() the CPU will be released by cond_resched() after every INIT_KEYS_EACH_TIME keys iterated. This is to avoid the watchdog reports a bogus soft lockup warning.
Fixes: b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") Signed-off-by: Coly Li colyli@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220524102336.10684-4-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/writeback.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-)
--- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -805,13 +805,11 @@ static int bch_writeback_thread(void *ar
/* Init */ #define INIT_KEYS_EACH_TIME 500000 -#define INIT_KEYS_SLEEP_MS 100
struct sectors_dirty_init { struct btree_op op; unsigned int inode; size_t count; - struct bkey start; };
static int sectors_dirty_init_fn(struct btree_op *_op, struct btree *b, @@ -827,11 +825,8 @@ static int sectors_dirty_init_fn(struct KEY_START(k), KEY_SIZE(k));
op->count++; - if (atomic_read(&b->c->search_inflight) && - !(op->count % INIT_KEYS_EACH_TIME)) { - bkey_copy_key(&op->start, k); - return -EAGAIN; - } + if (!(op->count % INIT_KEYS_EACH_TIME)) + cond_resched();
return MAP_CONTINUE; } @@ -846,24 +841,16 @@ static int bch_root_node_dirty_init(stru bch_btree_op_init(&op.op, -1); op.inode = d->id; op.count = 0; - op.start = KEY(op.inode, 0, 0);
- do { - ret = bcache_btree(map_keys_recurse, - k, - c->root, - &op.op, - &op.start, - sectors_dirty_init_fn, - 0); - if (ret == -EAGAIN) - schedule_timeout_interruptible( - msecs_to_jiffies(INIT_KEYS_SLEEP_MS)); - else if (ret < 0) { - pr_warn("sectors dirty init failed, ret=%d!\n", ret); - break; - } - } while (ret == -EAGAIN); + ret = bcache_btree(map_keys_recurse, + k, + c->root, + &op.op, + &KEY(op.inode, 0, 0), + sectors_dirty_init_fn, + 0); + if (ret < 0) + pr_warn("sectors dirty init failed, ret=%d!\n", ret);
return ret; } @@ -907,7 +894,6 @@ static int bch_dirty_init_thread(void *a goto out; } skip_nr--; - cond_resched(); }
if (p) { @@ -917,7 +903,6 @@ static int bch_dirty_init_thread(void *a
p = NULL; prev_idx = cur_idx; - cond_resched(); }
out: @@ -956,11 +941,11 @@ void bch_sectors_dirty_init(struct bcach bch_btree_op_init(&op.op, -1); op.inode = d->id; op.count = 0; - op.start = KEY(op.inode, 0, 0);
for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) sectors_dirty_init_fn(&op.op, c->root, k); + rw_unlock(0, c->root); return; }
From: Coly Li colyli@suse.de
commit 32feee36c30ea06e38ccb8ae6e5c44c6eec790a6 upstream.
The journal no-space deadlock was reported time to time. Such deadlock can happen in the following situation.
When all journal buckets are fully filled by active jset with heavy write I/O load, the cache set registration (after a reboot) will load all active jsets and inserting them into the btree again (which is called journal replay). If a journaled bkey is inserted into a btree node and results btree node split, new journal request might be triggered. For example, the btree grows one more level after the node split, then the root node record in cache device super block will be upgrade by bch_journal_meta() from bch_btree_set_root(). But there is no space in journal buckets, the journal replay has to wait for new journal bucket to be reclaimed after at least one journal bucket replayed. This is one example that how the journal no-space deadlock happens.
The solution to avoid the deadlock is to reserve 1 journal bucket in run time, and only permit the reserved journal bucket to be used during cache set registration procedure for things like journal replay. Then the journal space will never be fully filled, there is no chance for journal no-space deadlock to happen anymore.
This patch adds a new member "bool do_reserve" in struct journal, it is inititalized to 0 (false) when struct journal is allocated, and set to 1 (true) by bch_journal_space_reserve() when all initialization done in run_cache_set(). In the run time when journal_reclaim() tries to allocate a new journal bucket, free_journal_buckets() is called to check whether there are enough free journal buckets to use. If there is only 1 free journal bucket and journal->do_reserve is 1 (true), the last bucket is reserved and free_journal_buckets() will return 0 to indicate no free journal bucket. Then journal_reclaim() will give up, and try next time to see whetheer there is free journal bucket to allocate. By this method, there is always 1 jouranl bucket reserved in run time.
During the cache set registration, journal->do_reserve is 0 (false), so the reserved journal bucket can be used to avoid the no-space deadlock.
Reported-by: Nikhil Kshirsagar nkshirsagar@gmail.com Signed-off-by: Coly Li colyli@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220524102336.10684-5-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/journal.c | 31 ++++++++++++++++++++++++++----- drivers/md/bcache/journal.h | 2 ++ drivers/md/bcache/super.c | 1 + 3 files changed, 29 insertions(+), 5 deletions(-)
--- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c @@ -405,6 +405,11 @@ err: return ret; }
+void bch_journal_space_reserve(struct journal *j) +{ + j->do_reserve = true; +} + /* Journalling */
static void btree_flush_write(struct cache_set *c) @@ -621,12 +626,30 @@ static void do_journal_discard(struct ca } }
+static unsigned int free_journal_buckets(struct cache_set *c) +{ + struct journal *j = &c->journal; + struct cache *ca = c->cache; + struct journal_device *ja = &c->cache->journal; + unsigned int n; + + /* In case njournal_buckets is not power of 2 */ + if (ja->cur_idx >= ja->discard_idx) + n = ca->sb.njournal_buckets + ja->discard_idx - ja->cur_idx; + else + n = ja->discard_idx - ja->cur_idx; + + if (n > (1 + j->do_reserve)) + return n - (1 + j->do_reserve); + + return 0; +} + static void journal_reclaim(struct cache_set *c) { struct bkey *k = &c->journal.key; struct cache *ca = c->cache; uint64_t last_seq; - unsigned int next; struct journal_device *ja = &ca->journal; atomic_t p __maybe_unused;
@@ -649,12 +672,10 @@ static void journal_reclaim(struct cache if (c->journal.blocks_free) goto out;
- next = (ja->cur_idx + 1) % ca->sb.njournal_buckets; - /* No space available on this device */ - if (next == ja->discard_idx) + if (!free_journal_buckets(c)) goto out;
- ja->cur_idx = next; + ja->cur_idx = (ja->cur_idx + 1) % ca->sb.njournal_buckets; k->ptr[0] = MAKE_PTR(0, bucket_to_sector(c, ca->sb.d[ja->cur_idx]), ca->sb.nr_this_dev); --- a/drivers/md/bcache/journal.h +++ b/drivers/md/bcache/journal.h @@ -105,6 +105,7 @@ struct journal { spinlock_t lock; spinlock_t flush_write_lock; bool btree_flushing; + bool do_reserve; /* used when waiting because the journal was full */ struct closure_waitlist wait; struct closure io; @@ -182,5 +183,6 @@ int bch_journal_replay(struct cache_set
void bch_journal_free(struct cache_set *c); int bch_journal_alloc(struct cache_set *c); +void bch_journal_space_reserve(struct journal *j);
#endif /* _BCACHE_JOURNAL_H */ --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -2128,6 +2128,7 @@ static int run_cache_set(struct cache_se
flash_devs_run(c);
+ bch_journal_space_reserve(&c->journal); set_bit(CACHE_SET_RUNNING, &c->flags); return 0; err:
From: Jiri Slaby jslaby@suse.cz
commit d9f3af4fbb1d955bbaf872d9e76502f6e3e803cb upstream.
When x_char is to be sent, the TX path overwrites whatever is in the circular buffer at offset 0 with x_char and sends it using pch_uart_hal_write(). I don't understand how this was supposed to work if xmit->buf[0] already contained some character. It must have been lost.
Remove this whole pop_tx_x() concept and do the work directly in the callers. (Without printing anything using dev_dbg().)
Cc: stable@vger.kernel.org Fixes: 3c6a483275f4 (Serial: EG20T: add PCH_UART driver) Signed-off-by: Jiri Slaby jslaby@suse.cz Link: https://lore.kernel.org/r/20220503080808.28332-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/pch_uart.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-)
--- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -624,22 +624,6 @@ static int push_rx(struct eg20t_port *pr return 0; }
-static int pop_tx_x(struct eg20t_port *priv, unsigned char *buf) -{ - int ret = 0; - struct uart_port *port = &priv->port; - - if (port->x_char) { - dev_dbg(priv->port.dev, "%s:X character send %02x (%lu)\n", - __func__, port->x_char, jiffies); - buf[0] = port->x_char; - port->x_char = 0; - ret = 1; - } - - return ret; -} - static int dma_push_rx(struct eg20t_port *priv, int size) { int room; @@ -889,9 +873,10 @@ static unsigned int handle_tx(struct eg2
fifo_size = max(priv->fifo_size, 1); tx_empty = 1; - if (pop_tx_x(priv, xmit->buf)) { - pch_uart_hal_write(priv, xmit->buf, 1); + if (port->x_char) { + pch_uart_hal_write(priv, &port->x_char, 1); port->icount.tx++; + port->x_char = 0; tx_empty = 0; fifo_size--; } @@ -946,9 +931,11 @@ static unsigned int dma_handle_tx(struct }
fifo_size = max(priv->fifo_size, 1); - if (pop_tx_x(priv, xmit->buf)) { - pch_uart_hal_write(priv, xmit->buf, 1); + + if (port->x_char) { + pch_uart_hal_write(priv, &port->x_char, 1); port->icount.tx++; + port->x_char = 0; fifo_size--; }
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit 8b917cbe38e9b0d002492477a9fc2bfee2412ce4 upstream.
The bug is here: if (!encoder) {
The list iterator value 'encoder' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found.
To fix the bug, use a new variable 'iter' as the list iterator, while use the original variable 'encoder' as a dedicated pointer to point to the found element.
Cc: stable@vger.kernel.org Fixes: ec9eab097a500 ("drm/tilcdc: Add drm bridge support for attaching drm bridge drivers") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Reviewed-by: Jyri Sarha jyri.sarha@iki.fi Tested-by: Jyri Sarha jyri.sarha@iki.fi Signed-off-by: Jyri Sarha jyri.sarha@iki.fi Link: https://patchwork.freedesktop.org/patch/msgid/20220327061516.5076-1-xiam0nd.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/tilcdc/tilcdc_external.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/tilcdc/tilcdc_external.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_external.c @@ -60,11 +60,13 @@ struct drm_connector *tilcdc_encoder_fin int tilcdc_add_component_encoder(struct drm_device *ddev) { struct tilcdc_drm_private *priv = ddev->dev_private; - struct drm_encoder *encoder; + struct drm_encoder *encoder = NULL, *iter;
- list_for_each_entry(encoder, &ddev->mode_config.encoder_list, head) - if (encoder->possible_crtcs & (1 << priv->crtc->index)) + list_for_each_entry(iter, &ddev->mode_config.encoder_list, head) + if (iter->possible_crtcs & (1 << priv->crtc->index)) { + encoder = iter; break; + }
if (!encoder) { dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__);
From: Xiaomeng Tong xiam0nd.tong@gmail.com
commit bdef417d84536715145f6dc9cc3275c46f26295a upstream.
The bug is here: return crtc;
The list iterator value 'crtc' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found.
To fix the bug, return 'crtc' when found, otherwise return NULL.
Cc: stable@vger.kernel.org fixes: 89c78134cc54d ("gma500: Add Poulsbo support") Signed-off-by: Xiaomeng Tong xiam0nd.tong@gmail.com Signed-off-by: Patrik Jakobsson patrik.r.jakobsson@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20220327052028.2013-1-xiam0nd.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/gma500/psb_intel_display.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -535,14 +535,15 @@ void psb_intel_crtc_init(struct drm_devi
struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) { - struct drm_crtc *crtc = NULL; + struct drm_crtc *crtc;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct gma_crtc *gma_crtc = to_gma_crtc(crtc); + if (gma_crtc->pipe == pipe) - break; + return crtc; } - return crtc; + return NULL; }
int gma_connector_clones(struct drm_device *dev, int type_mask)
From: Kathiravan T quic_kathirav@quicinc.com
commit f607dd767f5d6800ffbdce5b99ba81763b023781 upstream.
Sleep clock frequency should be 32768Hz. Lets fix it.
Cc: stable@vger.kernel.org Fixes: 41dac73e243d ("arm64: dts: Add ipq8074 SoC and HK01 board support") Link: https://lore.kernel.org/all/e2a447f8-6024-0369-f698-2027b6edcf9e@codeaurora.... Signed-off-by: Kathiravan T quic_kathirav@quicinc.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1644581655-11568-1-git-send-email-quic_kathirav@qu... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -13,7 +13,7 @@ clocks { sleep_clk: sleep_clk { compatible = "fixed-clock"; - clock-frequency = <32000>; + clock-frequency = <32768>; #clock-cells = <0>; };
From: Diogo Ivo diogo.ivo@tecnico.ulisboa.pt
commit 0017f2c856e21bb900be88469e15dac4f41f4065 upstream.
Commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") removed deassertion of reset lines when enabling peripheral clocks. This breaks the initialization of the DFLL driver which relied on this behaviour.
In order to be able to fix this, add the corresponding reset to the DT. Tested on Google Pixel C.
Cc: stable@vger.kernel.org Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") Signed-off-by: Diogo Ivo diogo.ivo@tecnico.ulisboa.pt Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/boot/dts/nvidia/tegra210.dtsi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1366,8 +1366,9 @@ <&tegra_car TEGRA210_CLK_DFLL_REF>, <&tegra_car TEGRA210_CLK_I2C5>; clock-names = "soc", "ref", "i2c"; - resets = <&tegra_car TEGRA210_RST_DFLL_DVCO>; - reset-names = "dvco"; + resets = <&tegra_car TEGRA210_RST_DFLL_DVCO>, + <&tegra_car 155>; + reset-names = "dvco", "dfll"; #clock-cells = <0>; clock-output-names = "dfllCPU_out"; status = "disabled";
From: Diogo Ivo diogo.ivo@tecnico.ulisboa.pt
commit 23a43cc437e747473d5f8f98b4fe189fb5c433b7 upstream.
Commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") removed deassertion of reset lines when enabling peripheral clocks. This breaks the initialization of the DFLL driver which relied on this behaviour.
Fix this problem by adding explicit deassert/assert requests to the driver. Tested on Google Pixel C.
Cc: stable@vger.kernel.org Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks") Signed-off-by: Diogo Ivo diogo.ivo@tecnico.ulisboa.pt Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/clk/tegra/clk-dfll.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
--- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -271,6 +271,7 @@ struct tegra_dfll { struct clk *ref_clk; struct clk *i2c_clk; struct clk *dfll_clk; + struct reset_control *dfll_rst; struct reset_control *dvco_rst; unsigned long ref_rate; unsigned long i2c_clk_rate; @@ -1464,6 +1465,7 @@ static int dfll_init(struct tegra_dfll * return -EINVAL; }
+ reset_control_deassert(td->dfll_rst); reset_control_deassert(td->dvco_rst);
ret = clk_prepare(td->ref_clk); @@ -1509,6 +1511,7 @@ di_err1: clk_unprepare(td->ref_clk);
reset_control_assert(td->dvco_rst); + reset_control_assert(td->dfll_rst);
return ret; } @@ -1530,6 +1533,7 @@ int tegra_dfll_suspend(struct device *de }
reset_control_assert(td->dvco_rst); + reset_control_assert(td->dfll_rst);
return 0; } @@ -1548,6 +1552,7 @@ int tegra_dfll_resume(struct device *dev { struct tegra_dfll *td = dev_get_drvdata(dev);
+ reset_control_deassert(td->dfll_rst); reset_control_deassert(td->dvco_rst);
pm_runtime_get_sync(td->dev); @@ -1951,6 +1956,12 @@ int tegra_dfll_register(struct platform_
td->soc = soc;
+ td->dfll_rst = devm_reset_control_get_optional(td->dev, "dfll"); + if (IS_ERR(td->dfll_rst)) { + dev_err(td->dev, "couldn't get dfll reset\n"); + return PTR_ERR(td->dfll_rst); + } + td->dvco_rst = devm_reset_control_get(td->dev, "dvco"); if (IS_ERR(td->dvco_rst)) { dev_err(td->dev, "couldn't get dvco reset\n"); @@ -2087,6 +2098,7 @@ struct tegra_dfll_soc_data *tegra_dfll_u clk_unprepare(td->i2c_clk);
reset_control_assert(td->dvco_rst); + reset_control_assert(td->dfll_rst);
return td->soc; }
From: Johan Hovold johan+linaro@kernel.org
commit f0a4bc38a12f5a0cc5ad68670d9480e91e6a94df upstream.
Make sure to release the pipe clock reference in case of a late probe error (e.g. probe deferral).
Fixes: e78f3d15e115 ("phy: qcom-qmp: new qmp phy driver for qcom-chipsets") Cc: stable@vger.kernel.org # 4.12 Cc: Vivek Gautam vivek.gautam@codeaurora.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20220427063243.32576-2-johan+linaro@kernel.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/phy/qualcomm/phy-qcom-qmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -5890,7 +5890,7 @@ int qcom_qmp_phy_create(struct device *d * all phys that don't need this. */ snprintf(prop_name, sizeof(prop_name), "pipe%d", id); - qphy->pipe_clk = of_clk_get_by_name(np, prop_name); + qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name); if (IS_ERR(qphy->pipe_clk)) { if (cfg->type == PHY_TYPE_PCIE || cfg->type == PHY_TYPE_USB3) {
From: Jonathan Bakker xc-racer2@live.ca
commit 096f58507374e1293a9e9cff8a1ccd5f37780a20 upstream.
Since commit 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors"), the panel has been blank due to an inverted CS GPIO. In order to correct this, drop the spi-cs-high from the panel SPI device.
Fixes: 766c6b63aa04 ("spi: fix client driver breakages when using GPIO descriptors") Cc: stable@vger.kernel.org Signed-off-by: Jonathan Bakker xc-racer2@live.ca Link: https://lore.kernel.org/r/CY4PR04MB05670C771062570E911AF3B4CB1C9@CY4PR04MB05... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/boot/dts/s5pv210-aries.dtsi | 1 - 1 file changed, 1 deletion(-)
--- a/arch/arm/boot/dts/s5pv210-aries.dtsi +++ b/arch/arm/boot/dts/s5pv210-aries.dtsi @@ -564,7 +564,6 @@ reset-gpios = <&mp05 5 GPIO_ACTIVE_LOW>; vdd3-supply = <&ldo7_reg>; vci-supply = <&ldo17_reg>; - spi-cs-high; spi-max-frequency = <1200000>;
pinctrl-names = "default";
From: Arnd Bergmann arnd@arndb.de
commit 2672a4bff6c03a20d5ae460a091f67ee782c3eff upstream.
From inspection I found a couple of GPIO lookups that are
listed with device "gpio-pxa", but actually have a number from a different gpio controller.
Try to rectify that here, with a guess of what the actual device name is.
Acked-by: Robert Jarzmik robert.jarzmik@free.fr Reviewed-by: Linus Walleij linus.walleij@linaro.org Cc: stable@vger.kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/mach-pxa/cm-x300.c | 8 ++++---- arch/arm/mach-pxa/magician.c | 2 +- arch/arm/mach-pxa/tosa.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-)
--- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -354,13 +354,13 @@ static struct platform_device cm_x300_sp static struct gpiod_lookup_table cm_x300_spi_gpiod_table = { .dev_id = "spi_gpio", .table = { - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_SCL, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_SCL - GPIO_LCD_BASE, "sck", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_DIN, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_DIN - GPIO_LCD_BASE, "mosi", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_DOUT, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_DOUT - GPIO_LCD_BASE, "miso", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_CS, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_CS - GPIO_LCD_BASE, "cs", GPIO_ACTIVE_HIGH), { }, }, --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -681,7 +681,7 @@ static struct platform_device bq24022 = static struct gpiod_lookup_table bq24022_gpiod_table = { .dev_id = "gpio-regulator", .table = { - GPIO_LOOKUP("gpio-pxa", EGPIO_MAGICIAN_BQ24022_ISET2, + GPIO_LOOKUP("htc-egpio-0", EGPIO_MAGICIAN_BQ24022_ISET2 - MAGICIAN_EGPIO_BASE, NULL, GPIO_ACTIVE_HIGH), GPIO_LOOKUP("gpio-pxa", GPIO30_MAGICIAN_BQ24022_nCHARGE_EN, "enable", GPIO_ACTIVE_LOW), --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -296,9 +296,9 @@ static struct gpiod_lookup_table tosa_mc .table = { GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_nSD_DETECT, "cd", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_SD_WP, + GPIO_LOOKUP("sharp-scoop.0", TOSA_GPIO_SD_WP - TOSA_SCOOP_GPIO_BASE, "wp", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_PWR_ON, + GPIO_LOOKUP("sharp-scoop.0", TOSA_GPIO_PWR_ON - TOSA_SCOOP_GPIO_BASE, "power", GPIO_ACTIVE_HIGH), { }, },
From: Luís Henriques lhenriques@suse.de
commit ea16567f11018e2f58e72b667b0c803ff92b8153 upstream.
The cephfs kernel client started to show the message:
ceph: mds0 session blocklisted
when mounting a filesystem. This is due to the fact that the session messages are being incorrectly decoded: the skip needs to take into account the 'len'.
While there, fixed some whitespaces too.
Cc: stable@vger.kernel.org Fixes: e1c9788cb397 ("ceph: don't rely on error_string to validate blocklisted session.") Signed-off-by: Luís Henriques lhenriques@suse.de Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ceph/mds_client.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
--- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -3375,13 +3375,17 @@ static void handle_session(struct ceph_m }
if (msg_version >= 5) { - u32 flags; - /* version >= 4, struct_v, struct_cv, len, metric_spec */ - ceph_decode_skip_n(&p, end, 2 + sizeof(u32) * 2, bad); + u32 flags, len; + + /* version >= 4 */ + ceph_decode_skip_16(&p, end, bad); /* struct_v, struct_cv */ + ceph_decode_32_safe(&p, end, len, bad); /* len */ + ceph_decode_skip_n(&p, end, len, bad); /* metric_spec */ + /* version >= 5, flags */ - ceph_decode_32_safe(&p, end, flags, bad); + ceph_decode_32_safe(&p, end, flags, bad); if (flags & CEPH_SESSION_BLOCKLISTED) { - pr_warn("mds%d session blocklisted\n", session->s_mds); + pr_warn("mds%d session blocklisted\n", session->s_mds); blocklisted = true; } }
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
commit c5c07c5958cf0c9af6e76813e6de15d42ee49822 upstream.
This is another instance of incorrect use of list iterator and checking it for NULL.
The list iterator value 'map' will *always* be set and non-NULL by list_for_each_entry(), so it is incorrect to assume that the iterator value will be NULL if the list is empty (in this case, the check 'if (!map) {' will always be false and never exit as expected).
To fix the bug, use a new variable 'iter' as the list iterator, while use the original variable 'map' as a dedicated pointer to point to the found element.
Without this patch, Kernel crashes with below trace:
Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000ffff7fb03750 ... Call trace: fastrpc_map_create+0x70/0x290 [fastrpc] fastrpc_req_mem_map+0xf0/0x2dc [fastrpc] fastrpc_device_ioctl+0x138/0xc60 [fastrpc] __arm64_sys_ioctl+0xa8/0xec invoke_syscall+0x48/0x114 el0_svc_common.constprop.0+0xd4/0xfc do_el0_svc+0x28/0x90 el0_svc+0x3c/0x130 el0t_64_sync_handler+0xa4/0x130 el0t_64_sync+0x18c/0x190 Code: 14000016 f94000a5 eb05029f 54000260 (b94018a6) ---[ end trace 0000000000000000 ]---
Fixes: 5c1b97c7d7b7 ("misc: fastrpc: add support for FASTRPC_IOCTL_MEM_MAP/UNMAP") Cc: stable@vger.kernel.org Reported-by: Jan Jablonsky jjablonsky@snapchat.com Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20220518152353.13058-1-srinivas.kandagatla@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/fastrpc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1747,17 +1747,18 @@ err_invoke: static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req) { struct fastrpc_invoke_args args[1] = { [0] = { 0 } }; - struct fastrpc_map *map = NULL, *m; + struct fastrpc_map *map = NULL, *iter, *m; struct fastrpc_mem_unmap_req_msg req_msg = { 0 }; int err = 0; u32 sc; struct device *dev = fl->sctx->dev;
spin_lock(&fl->lock); - list_for_each_entry_safe(map, m, &fl->maps, node) { - if ((req->fd < 0 || map->fd == req->fd) && (map->raddr == req->vaddr)) + list_for_each_entry_safe(iter, m, &fl->maps, node) { + if ((req->fd < 0 || iter->fd == req->fd) && (iter->raddr == req->vaddr)) { + map = iter; break; - map = NULL; + } }
spin_unlock(&fl->lock);
From: Steve French stfrench@microsoft.com
commit 0a55cf74ffb5d004b93647e4389096880ce37d6b upstream.
There is a race condition in smb2_compound_op:
after_close: num_rqst++;
if (cfile) { cifsFileInfo_put(cfile); // sends SMB2_CLOSE to the server cfile = NULL;
This is triggered by smb2_query_path_info operation that happens during revalidate_dentry. In smb2_query_path_info, get_readable_path is called to load the cfile, increasing the reference counter. If in the meantime, this reference becomes the very last, this call to cifsFileInfo_put(cfile) will trigger a SMB2_CLOSE request sent to the server just before sending this compound request – and so then the compound request fails either with EBADF/EIO depending on the timing at the server, because the handle is already closed.
In the first scenario, the race seems to be happening between smb2_query_path_info triggered by the rename operation, and between “cleanup” of asynchronous writes – while fsync(fd) likely waits for the asynchronous writes to complete, releasing the writeback structures can happen after the close(fd) call. So the EBADF/EIO errors will pop up if the timing is such that: 1) There are still outstanding references after close(fd) in the writeback structures 2) smb2_query_path_info successfully fetches the cfile, increasing the refcounter by 1 3) All writeback structures release the same cfile, reducing refcounter to 1 4) smb2_compound_op is called with that cfile
In the second scenario, the race seems to be similar – here open triggers the smb2_query_path_info operation, and if all other threads in the meantime decrease the refcounter to 1 similarly to the first scenario, again SMB2_CLOSE will be sent to the server just before issuing the compound request. This case is harder to reproduce.
See https://bugzilla.samba.org/show_bug.cgi?id=15051
Cc: stable@vger.kernel.org Fixes: 8de9e86c67ba ("cifs: create a helper to find a writeable handle by path name") Signed-off-by: Ondrej Hubsch ohubsch@purestorage.com Reviewed-by: Ronnie Sahlberg lsahlber@redhat.com Reviewed-by: Paulo Alcantara (SUSE) pc@cjr.nz Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/smb2inode.c | 2 -- 1 file changed, 2 deletions(-)
--- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -362,8 +362,6 @@ smb2_compound_op(const unsigned int xid, num_rqst++;
if (cfile) { - cifsFileInfo_put(cfile); - cfile = NULL; rc = compound_send_recv(xid, ses, server, flags, num_rqst - 2, &rqst[1], &resp_buftype[1],
From: Akira Yokosawa akiyks@gmail.com
commit 627f01eab93d8671d4e4afee9b148f9998d20e7c upstream.
One of the changes in Sphinx 5.0.0 [1] says [sic]:
5.0.0 final
- #10474: language does not accept None as it value. The default value of language becomes to 'en' now.
[1]: https://www.sphinx-doc.org/en/master/changes.html#release-5-0-0-released-may...
It results in a new warning from Sphinx 5.0.0 [sic]:
WARNING: Invalid configuration value found: 'language = None'. Update your configuration to a valid langauge code. Falling back to 'en' (English).
Silence the warning by using 'en'. It works with all the Sphinx versions required for building kernel documentation (1.7.9 or later).
Signed-off-by: Akira Yokosawa akiyks@gmail.com Link: https://lore.kernel.org/r/bd0c2ddc-2401-03cb-4526-79ca664e1cbe@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Jonathan Corbet corbet@lwn.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/conf.py +++ b/Documentation/conf.py @@ -161,7 +161,7 @@ finally: # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en'
# There are two options for replacing |today|: either, you set today to some # non-false value, then it is used:
From: Dinh Nguyen dinguyen@kernel.org
commit 3a21c3ac93aff7b4522b152399df8f6a041df56d upstream.
update documentation to correctly state the interrupt-cells to be 2.
Cc: stable@vger.kernel.org Fixes: 4fd9bbc6e071 ("drivers/gpio: Altera soft IP GPIO driver devicetree binding") Signed-off-by: Dinh Nguyen dinguyen@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/devicetree/bindings/gpio/gpio-altera.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/Documentation/devicetree/bindings/gpio/gpio-altera.txt +++ b/Documentation/devicetree/bindings/gpio/gpio-altera.txt @@ -9,8 +9,9 @@ Required properties: - The second cell is reserved and is currently unused. - gpio-controller : Marks the device node as a GPIO controller. - interrupt-controller: Mark the device node as an interrupt controller -- #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware. +- #interrupt-cells : Should be 2. The interrupt type is fixed in the hardware. - The first cell is the GPIO offset number within the GPIO controller. + - The second cell is the interrupt trigger type and level flags. - interrupts: Specify the interrupt. - altr,interrupt-type: Specifies the interrupt trigger type the GPIO hardware is synthesized. This field is required if the Altera GPIO controller @@ -38,6 +39,6 @@ gpio_altr: gpio@ff200000 { altr,interrupt-type = <IRQ_TYPE_EDGE_RISING>; #gpio-cells = <2>; gpio-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; interrupt-controller; };
From: Eugenio Pérez eperezma@redhat.com
commit 242436973831aa97e8ce19533c6c912ea8def31b upstream.
Code must be resilient to enable a queue many times.
At the moment the queue is resetting so it's definitely not the expected behavior.
v2: set vq->ready = 0 at disable.
Fixes: 2c53d0f64c06 ("vdpasim: vDPA device simulator") Cc: stable@vger.kernel.org Signed-off-by: Eugenio Pérez eperezma@redhat.com Message-Id: 20220519145919.772896-1-eperezma@redhat.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Reviewed-by: Stefano Garzarella sgarzare@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/vdpa/vdpa_sim/vdpa_sim.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c @@ -353,11 +353,14 @@ static void vdpasim_set_vq_ready(struct { struct vdpasim *vdpasim = vdpa_to_sim(vdpa); struct vdpasim_virtqueue *vq = &vdpasim->vqs[idx]; + bool old_ready;
spin_lock(&vdpasim->lock); + old_ready = vq->ready; vq->ready = ready; - if (vq->ready) + if (vq->ready && !old_ready) { vdpasim_queue_ready(vdpasim, idx); + } spin_unlock(&vdpasim->lock); }
From: Tejun Heo tj@kernel.org
commit 8a177a36da6c54c98b8685d4f914cb3637d53c0d upstream.
iolatency needs to track the number of inflight IOs per cgroup. As this tracking can be expensive, it is disabled when no cgroup has iolatency configured for the device. To ensure that the inflight counters stay balanced, iolatency_set_limit() freezes the request_queue while manipulating the enabled counter, which ensures that no IO is in flight and thus all counters are zero.
Unfortunately, iolatency_set_limit() isn't the only place where the enabled counter is manipulated. iolatency_pd_offline() can also dec the counter and trigger disabling. As this disabling happens without freezing the q, this can easily happen while some IOs are in flight and thus leak the counts.
This can be easily demonstrated by turning on iolatency on an one empty cgroup while IOs are in flight in other cgroups and then removing the cgroup. Note that iolatency shouldn't have been enabled elsewhere in the system to ensure that removing the cgroup disables iolatency for the whole device.
The following keeps flipping on and off iolatency on sda:
echo +io > /sys/fs/cgroup/cgroup.subtree_control while true; do mkdir -p /sys/fs/cgroup/test echo '8:0 target=100000' > /sys/fs/cgroup/test/io.latency sleep 1 rmdir /sys/fs/cgroup/test sleep 1 done
and there's concurrent fio generating direct rand reads:
fio --name test --filename=/dev/sda --direct=1 --rw=randread \ --runtime=600 --time_based --iodepth=256 --numjobs=4 --bs=4k
while monitoring with the following drgn script:
while True: for css in css_for_each_descendant_pre(prog['blkcg_root'].css.address_of_()): for pos in hlist_for_each(container_of(css, 'struct blkcg', 'css').blkg_list): blkg = container_of(pos, 'struct blkcg_gq', 'blkcg_node') pd = blkg.pd[prog['blkcg_policy_iolatency'].plid] if pd.value_() == 0: continue iolat = container_of(pd, 'struct iolatency_grp', 'pd') inflight = iolat.rq_wait.inflight.counter.value_() if inflight: print(f'inflight={inflight} {disk_name(blkg.q.disk).decode("utf-8")} ' f'{cgroup_path(css.cgroup).decode("utf-8")}') time.sleep(1)
The monitoring output looks like the following:
inflight=1 sda /user.slice inflight=1 sda /user.slice ... inflight=14 sda /user.slice inflight=13 sda /user.slice inflight=17 sda /user.slice inflight=15 sda /user.slice inflight=18 sda /user.slice inflight=17 sda /user.slice inflight=20 sda /user.slice inflight=19 sda /user.slice <- fio stopped, inflight stuck at 19 inflight=19 sda /user.slice inflight=19 sda /user.slice
If a cgroup with stuck inflight ends up getting throttled, the throttled IOs will never get issued as there's no completion event to wake it up leading to an indefinite hang.
This patch fixes the bug by unifying enable handling into a work item which is automatically kicked off from iolatency_set_min_lat_nsec() which is called from both iolatency_set_limit() and iolatency_pd_offline() paths. Punting to a work item is necessary as iolatency_pd_offline() is called under spinlocks while freezing a request_queue requires a sleepable context.
This also simplifies the code reducing LOC sans the comments and avoids the unnecessary freezes which were happening whenever a cgroup's latency target is newly set or cleared.
Signed-off-by: Tejun Heo tj@kernel.org Cc: Josef Bacik josef@toxicpanda.com Cc: Liu Bo bo.liu@linux.alibaba.com Fixes: 8c772a9bfc7c ("blk-iolatency: fix IO hang due to negative inflight counter") Cc: stable@vger.kernel.org # v5.0+ Link: https://lore.kernel.org/r/Yn9ScX6Nx2qIiQQi@slm.duckdns.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-iolatency.c | 122 ++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 58 deletions(-)
--- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -87,7 +87,17 @@ struct iolatency_grp; struct blk_iolatency { struct rq_qos rqos; struct timer_list timer; - atomic_t enabled; + + /* + * ->enabled is the master enable switch gating the throttling logic and + * inflight tracking. The number of cgroups which have iolat enabled is + * tracked in ->enable_cnt, and ->enable is flipped on/off accordingly + * from ->enable_work with the request_queue frozen. For details, See + * blkiolatency_enable_work_fn(). + */ + bool enabled; + atomic_t enable_cnt; + struct work_struct enable_work; };
static inline struct blk_iolatency *BLKIOLATENCY(struct rq_qos *rqos) @@ -95,11 +105,6 @@ static inline struct blk_iolatency *BLKI return container_of(rqos, struct blk_iolatency, rqos); }
-static inline bool blk_iolatency_enabled(struct blk_iolatency *blkiolat) -{ - return atomic_read(&blkiolat->enabled) > 0; -} - struct child_latency_info { spinlock_t lock;
@@ -464,7 +469,7 @@ static void blkcg_iolatency_throttle(str struct blkcg_gq *blkg = bio->bi_blkg; bool issue_as_root = bio_issue_as_root_blkg(bio);
- if (!blk_iolatency_enabled(blkiolat)) + if (!blkiolat->enabled) return;
while (blkg && blkg->parent) { @@ -594,7 +599,6 @@ static void blkcg_iolatency_done_bio(str u64 window_start; u64 now; bool issue_as_root = bio_issue_as_root_blkg(bio); - bool enabled = false; int inflight = 0;
blkg = bio->bi_blkg; @@ -605,8 +609,7 @@ static void blkcg_iolatency_done_bio(str if (!iolat) return;
- enabled = blk_iolatency_enabled(iolat->blkiolat); - if (!enabled) + if (!iolat->blkiolat->enabled) return;
now = ktime_to_ns(ktime_get()); @@ -645,6 +648,7 @@ static void blkcg_iolatency_exit(struct struct blk_iolatency *blkiolat = BLKIOLATENCY(rqos);
del_timer_sync(&blkiolat->timer); + flush_work(&blkiolat->enable_work); blkcg_deactivate_policy(rqos->q, &blkcg_policy_iolatency); kfree(blkiolat); } @@ -716,6 +720,44 @@ next: rcu_read_unlock(); }
+/** + * blkiolatency_enable_work_fn - Enable or disable iolatency on the device + * @work: enable_work of the blk_iolatency of interest + * + * iolatency needs to keep track of the number of in-flight IOs per cgroup. This + * is relatively expensive as it involves walking up the hierarchy twice for + * every IO. Thus, if iolatency is not enabled in any cgroup for the device, we + * want to disable the in-flight tracking. + * + * We have to make sure that the counting is balanced - we don't want to leak + * the in-flight counts by disabling accounting in the completion path while IOs + * are in flight. This is achieved by ensuring that no IO is in flight by + * freezing the queue while flipping ->enabled. As this requires a sleepable + * context, ->enabled flipping is punted to this work function. + */ +static void blkiolatency_enable_work_fn(struct work_struct *work) +{ + struct blk_iolatency *blkiolat = container_of(work, struct blk_iolatency, + enable_work); + bool enabled; + + /* + * There can only be one instance of this function running for @blkiolat + * and it's guaranteed to be executed at least once after the latest + * ->enabled_cnt modification. Acting on the latest ->enable_cnt is + * sufficient. + * + * Also, we know @blkiolat is safe to access as ->enable_work is flushed + * in blkcg_iolatency_exit(). + */ + enabled = atomic_read(&blkiolat->enable_cnt); + if (enabled != blkiolat->enabled) { + blk_mq_freeze_queue(blkiolat->rqos.q); + blkiolat->enabled = enabled; + blk_mq_unfreeze_queue(blkiolat->rqos.q); + } +} + int blk_iolatency_init(struct request_queue *q) { struct blk_iolatency *blkiolat; @@ -741,17 +783,15 @@ int blk_iolatency_init(struct request_qu }
timer_setup(&blkiolat->timer, blkiolatency_timer_fn, 0); + INIT_WORK(&blkiolat->enable_work, blkiolatency_enable_work_fn);
return 0; }
-/* - * return 1 for enabling iolatency, return -1 for disabling iolatency, otherwise - * return 0. - */ -static int iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) +static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val) { struct iolatency_grp *iolat = blkg_to_lat(blkg); + struct blk_iolatency *blkiolat = iolat->blkiolat; u64 oldval = iolat->min_lat_nsec;
iolat->min_lat_nsec = val; @@ -759,13 +799,15 @@ static int iolatency_set_min_lat_nsec(st iolat->cur_win_nsec = min_t(u64, iolat->cur_win_nsec, BLKIOLATENCY_MAX_WIN_SIZE);
- if (!oldval && val) - return 1; + if (!oldval && val) { + if (atomic_inc_return(&blkiolat->enable_cnt) == 1) + schedule_work(&blkiolat->enable_work); + } if (oldval && !val) { blkcg_clear_delay(blkg); - return -1; + if (atomic_dec_return(&blkiolat->enable_cnt) == 0) + schedule_work(&blkiolat->enable_work); } - return 0; }
static void iolatency_clear_scaling(struct blkcg_gq *blkg) @@ -797,7 +839,6 @@ static ssize_t iolatency_set_limit(struc u64 lat_val = 0; u64 oldval; int ret; - int enable = 0;
ret = blkg_conf_prep(blkcg, &blkcg_policy_iolatency, buf, &ctx); if (ret) @@ -832,41 +873,12 @@ static ssize_t iolatency_set_limit(struc blkg = ctx.blkg; oldval = iolat->min_lat_nsec;
- enable = iolatency_set_min_lat_nsec(blkg, lat_val); - if (enable) { - if (!blk_get_queue(blkg->q)) { - ret = -ENODEV; - goto out; - } - - blkg_get(blkg); - } - - if (oldval != iolat->min_lat_nsec) { + iolatency_set_min_lat_nsec(blkg, lat_val); + if (oldval != iolat->min_lat_nsec) iolatency_clear_scaling(blkg); - } - ret = 0; out: blkg_conf_finish(&ctx); - if (ret == 0 && enable) { - struct iolatency_grp *tmp = blkg_to_lat(blkg); - struct blk_iolatency *blkiolat = tmp->blkiolat; - - blk_mq_freeze_queue(blkg->q); - - if (enable == 1) - atomic_inc(&blkiolat->enabled); - else if (enable == -1) - atomic_dec(&blkiolat->enabled); - else - WARN_ON_ONCE(1); - - blk_mq_unfreeze_queue(blkg->q); - - blkg_put(blkg); - blk_put_queue(blkg->q); - } return ret ?: nbytes; }
@@ -1005,14 +1017,8 @@ static void iolatency_pd_offline(struct { struct iolatency_grp *iolat = pd_to_lat(pd); struct blkcg_gq *blkg = lat_to_blkg(iolat); - struct blk_iolatency *blkiolat = iolat->blkiolat; - int ret;
- ret = iolatency_set_min_lat_nsec(blkg, 0); - if (ret == 1) - atomic_inc(&blkiolat->enabled); - if (ret == -1) - atomic_dec(&blkiolat->enabled); + iolatency_set_min_lat_nsec(blkg, 0); iolatency_clear_scaling(blkg); }
From: Mao Jinlong quic_jinlmao@quicinc.com
commit 8c1d3f79d9ca48e406b78e90e94cf09a8c076bf2 upstream.
It is possibe that probe failure issue happens when the device and its child_device's probe happens at the same time. In coresight_make_links, has_conns_grp is true for parent, but has_conns_grp is false for child device as has_conns_grp is set to true in coresight_create_conns_sysfs_group. The probe of parent device will fail at this condition. Add has_conns_grp check for child device before make the links and make the process from device_register to connection_create be atomic to avoid this probe failure issue.
Cc: stable@vger.kernel.org Suggested-by: Suzuki K Poulose suzuki.poulose@arm.com Suggested-by: Mike Leach mike.leach@linaro.org Signed-off-by: Mao Jinlong quic_jinlmao@quicinc.com Link: https://lore.kernel.org/r/20220309142206.15632-1-quic_jinlmao@quicinc.com [ Added Cc stable ] Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/coresight/coresight-core.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-)
--- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -1379,7 +1379,7 @@ static int coresight_fixup_device_conns( continue; conn->child_dev = coresight_find_csdev_by_fwnode(conn->child_fwnode); - if (conn->child_dev) { + if (conn->child_dev && conn->child_dev->has_conns_grp) { ret = coresight_make_links(csdev, conn, conn->child_dev); if (ret) @@ -1571,6 +1571,7 @@ struct coresight_device *coresight_regis int nr_refcnts = 1; atomic_t *refcnts = NULL; struct coresight_device *csdev; + bool registered = false;
csdev = kzalloc(sizeof(*csdev), GFP_KERNEL); if (!csdev) { @@ -1591,7 +1592,8 @@ struct coresight_device *coresight_regis refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL); if (!refcnts) { ret = -ENOMEM; - goto err_free_csdev; + kfree(csdev); + goto err_out; }
csdev->refcnt = refcnts; @@ -1616,6 +1618,13 @@ struct coresight_device *coresight_regis csdev->dev.fwnode = fwnode_handle_get(dev_fwnode(desc->dev)); dev_set_name(&csdev->dev, "%s", desc->name);
+ /* + * Make sure the device registration and the connection fixup + * are synchronised, so that we don't see uninitialised devices + * on the coresight bus while trying to resolve the connections. + */ + mutex_lock(&coresight_mutex); + ret = device_register(&csdev->dev); if (ret) { put_device(&csdev->dev); @@ -1623,7 +1632,7 @@ struct coresight_device *coresight_regis * All resources are free'd explicitly via * coresight_device_release(), triggered from put_device(). */ - goto err_out; + goto out_unlock; }
if (csdev->type == CORESIGHT_DEV_TYPE_SINK || @@ -1638,11 +1647,11 @@ struct coresight_device *coresight_regis * from put_device(), which is in turn called from * function device_unregister(). */ - goto err_out; + goto out_unlock; } } - - mutex_lock(&coresight_mutex); + /* Device is now registered */ + registered = true;
ret = coresight_create_conns_sysfs_group(csdev); if (!ret) @@ -1652,16 +1661,18 @@ struct coresight_device *coresight_regis if (!ret && cti_assoc_ops && cti_assoc_ops->add) cti_assoc_ops->add(csdev);
+out_unlock: mutex_unlock(&coresight_mutex); - if (ret) { + /* Success */ + if (!ret) + return csdev; + + /* Unregister the device if needed */ + if (registered) { coresight_unregister(csdev); return ERR_PTR(ret); }
- return csdev; - -err_free_csdev: - kfree(csdev); err_out: /* Cleanup the connection information */ coresight_release_platform_data(NULL, desc->pdata);
From: Johan Hovold johan+linaro@kernel.org
commit 4d2900f20edfe541f75756a00deeb2ffe7c66bc1 upstream.
Make sure to release the lane reset controller in case of a late probe error (e.g. probe deferral).
Note that due to the reset controller being defined in devicetree in "lane" child nodes, devm_reset_control_get_exclusive() cannot be used directly.
Fixes: e78f3d15e115 ("phy: qcom-qmp: new qmp phy driver for qcom-chipsets") Cc: stable@vger.kernel.org # 4.12 Cc: Vivek Gautam vivek.gautam@codeaurora.org Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Signed-off-by: Johan Hovold johan+linaro@kernel.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20220427063243.32576-3-johan+linaro@kernel.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/phy/qualcomm/phy-qcom-qmp.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -5818,6 +5818,11 @@ static const struct phy_ops qcom_qmp_pci .owner = THIS_MODULE, };
+static void qcom_qmp_reset_control_put(void *data) +{ + reset_control_put(data); +} + static int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id, void __iomem *serdes, const struct qmp_phy_cfg *cfg) @@ -5912,6 +5917,10 @@ int qcom_qmp_phy_create(struct device *d dev_err(dev, "failed to get lane%d reset\n", id); return PTR_ERR(qphy->lane_rst); } + ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put, + qphy->lane_rst); + if (ret) + return ret; }
if (cfg->type == PHY_TYPE_UFS || cfg->type == PHY_TYPE_PCIE)
From: Alex Elder elder@linaro.org
commit 155c0c90bca918de6e4327275dfc1d97fd604115 upstream.
Currently the (possibly compound) page used for receive buffers are freed using __free_pages(). But according to this comment above the definition of that function, that's wrong: If you want to use the page's reference count to decide when to free the allocation, you should allocate a compound page, and use put_page() instead of __free_pages().
Convert the call to __free_pages() in ipa_endpoint_trans_release() to use put_page() instead.
Fixes: ed23f02680caa ("net: ipa: define per-endpoint receive buffer size") Signed-off-by: Alex Elder elder@linaro.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ipa/ipa_endpoint.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
--- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -1385,11 +1385,8 @@ void ipa_endpoint_trans_release(struct i } else { struct page *page = trans->data;
- if (page) { - u32 buffer_size = endpoint->data->rx.buffer_size; - - __free_pages(page, get_order(buffer_size)); - } + if (page) + put_page(page); } }
From: Alex Elder elder@linaro.org
commit 70132763d5d2e94cd185e3aa92ac6a3ba89068fa upstream.
Currently the (possibly compound) pages used for receive buffers are freed using __free_pages(). But according to this comment above the definition of that function, that's wrong: If you want to use the page's reference count to decide when to free the allocation, you should allocate a compound page, and use put_page() instead of __free_pages().
Convert the call to __free_pages() in ipa_endpoint_replenish_one() to use put_page() instead.
Fixes: 6a606b90153b8 ("net: ipa: allocate transaction in replenish loop") Signed-off-by: Alex Elder elder@linaro.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ipa/ipa_endpoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -1062,7 +1062,7 @@ static int ipa_endpoint_replenish_one(st
ret = gsi_trans_page_add(trans, page, len, offset); if (ret) - __free_pages(page, get_order(buffer_size)); + put_page(page); else trans->data = page; /* transaction owns page now */
From: Sean Young sean@mess.org
commit b1c8312c6bd70e2c41f96183936fdb6f4f07cc0e upstream.
Commit e5499dd7253c ("media: lirc: revert removal of unused feature flags") reintroduced unused feature flags in the lirc uapi header, but failed to reintroduce the necessary exceptions for the docs.
Fixes: e5499dd7253c ("media: lirc: revert removal of unused feature flags") Signed-off-by: Sean Young sean@mess.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/userspace-api/media/lirc.h.rst.exceptions | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/Documentation/userspace-api/media/lirc.h.rst.exceptions b/Documentation/userspace-api/media/lirc.h.rst.exceptions index 913d17b49831..1aeb7d7afe13 100644 --- a/Documentation/userspace-api/media/lirc.h.rst.exceptions +++ b/Documentation/userspace-api/media/lirc.h.rst.exceptions @@ -30,6 +30,8 @@ ignore define LIRC_CAN_REC
ignore define LIRC_CAN_SEND_MASK ignore define LIRC_CAN_REC_MASK +ignore define LIRC_CAN_SET_REC_FILTER +ignore define LIRC_CAN_NOTIFY_DECODE
# Obsolete ioctls
From: Waiman Long longman@redhat.com
commit 213adc63dfbcdff9a0c19ec1f2681fda9c05cf6d upstream.
Commit 54de76c01239 ("kselftest/cgroup: fix test_stress.sh to use OUTPUT dir") changes the test_core command path from . to $OUTPUT. However, variable OUTPUT may not be defined if the command is run interactively. Fix that by using ${OUTPUT:-.} to cover both cases.
Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/cgroup/test_stress.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/testing/selftests/cgroup/test_stress.sh +++ b/tools/testing/selftests/cgroup/test_stress.sh @@ -1,4 +1,4 @@ #!/bin/bash # SPDX-License-Identifier: GPL-2.0
-./with_stress.sh -s subsys -s fork ${OUTPUT}/test_core +./with_stress.sh -s subsys -s fork ${OUTPUT:-.}/test_core
From: Zhengjun Xing zhengjun.xing@linux.intel.com
commit e69a5c010246ca6a87c4e6f13d0a291954bdece8 upstream.
For the hybrid system, the "slots" event changes to "cpu_core/slots/", need extend API arch_evsel__must_be_in_group() to support hybrid systems.
In the origin code, for hybrid system event "cpu_core/slots/", the output of the API arch_evsel__must_be_in_group() is "false" (in fact,it should be "true"). Currently only one API evsel__remove_from_group() calls it. In evsel__remove_from_group(), it adds the second condition to check, so the output of evsel__remove_from_group() still is correct. That's the reason why there isn't an instant error. I'd like to fix the issue found in API arch_evsel__must_be_in_group() in case someone else using the function in the other place.
Fixes: d98079c05b5a ("perf evlist: Keep topdown counters in weak group") Signed-off-by: Zhengjun Xing zhengjun.xing@linux.intel.com Reviewed-by: Kan Liang kan.liang@linux.intel.com Acked-by: Ian Rogers irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Link: https://lore.kernel.org/r/20220601152544.1842447-1-zhengjun.xing@linux.intel... Cc: peterz@infradead.org Cc: adrian.hunter@intel.com Cc: alexander.shishkin@intel.com Cc: acme@kernel.org Cc: ak@linux.intel.com Cc: jolsa@redhat.com Cc: mingo@redhat.com Cc: linux-kernel@vger.kernel.org Cc: linux-perf-users@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/perf/arch/x86/util/evsel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/perf/arch/x86/util/evsel.c +++ b/tools/perf/arch/x86/util/evsel.c @@ -38,6 +38,6 @@ bool arch_evsel__must_be_in_group(const return false;
return evsel->name && - (!strcasecmp(evsel->name, "slots") || + (strcasestr(evsel->name, "slots") || strcasestr(evsel->name, "topdown")); }
From: "Jason A. Donenfeld" Jason@zx2c4.com
This reverts upstream commit f5bda35fba615ace70a656d4700423fa6c9bebee from stable. It's not essential and will take some time during 5.19 to work out properly.
Signed-off-by: Jason A. Donenfeld Jason@zx2c4.com --- drivers/char/random.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-)
--- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -78,8 +78,7 @@ static enum { CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ } crng_init __read_mostly = CRNG_EMPTY; -static DEFINE_STATIC_KEY_FALSE(crng_is_ready); -#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) +#define crng_ready() (likely(crng_init >= CRNG_READY)) /* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; @@ -109,11 +108,6 @@ bool rng_is_initialized(void) } EXPORT_SYMBOL(rng_is_initialized);
-static void __cold crng_set_ready(struct work_struct *work) -{ - static_branch_enable(&crng_is_ready); -} - /* Used by wait_for_random_bytes(), and considered an entropy collector, below. */ static void try_to_generate_entropy(void);
@@ -267,7 +261,7 @@ static void crng_reseed(void) ++next_gen; WRITE_ONCE(base_crng.generation, next_gen); WRITE_ONCE(base_crng.birth, jiffies); - if (!static_branch_likely(&crng_is_ready)) + if (!crng_ready()) crng_init = CRNG_READY; spin_unlock_irqrestore(&base_crng.lock, flags); memzero_explicit(key, sizeof(key)); @@ -710,7 +704,6 @@ static void extract_entropy(void *buf, s
static void __cold _credit_init_bits(size_t bits) { - static struct execute_work set_ready; unsigned int new, orig, add; unsigned long flags;
@@ -726,7 +719,6 @@ static void __cold _credit_init_bits(siz
if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */ - execute_in_process_context(crng_set_ready, &set_ready); process_random_ready_list(); wake_up_interruptible(&crng_init_wait); kill_fasync(&fasync, SIGIO, POLL_IN);
From: Dan Carpenter dan.carpenter@oracle.com
commit 4d0cc9e0e53e9946d7b8dc58279c62dfa7a2191b upstream.
These debugging tools let you call:
status = usb_control_msg_recv/send(udev, 0, REALTEK_USB_VENQT_CMD_REQ, REALTEK_USB_VENQT_READ/WRITE, value, REALTEK_USB_VENQT_CMD_IDX, io_buf, size, RTW_USB_CONTROL_MSG_TIMEOUT, GFP_KERNEL);
with a user controlled "value" in the 0-0xffff range. It's not a valid API.
Fixes: 2b42bd58b321 ("staging: r8188eu: introduce new os_dep dir for RTL8188eu driver") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/YoXS4OaD1oauPvmj@kili Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/r8188eu/os_dep/ioctl_linux.c | 86 --------------------------- 1 file changed, 2 insertions(+), 84 deletions(-)
--- a/drivers/staging/r8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/r8188eu/os_dep/ioctl_linux.c @@ -1888,88 +1888,6 @@ static int rtw_wx_get_nick(struct net_de return 0; }
-static int rtw_wx_read32(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct adapter *padapter; - struct iw_point *p; - u16 len; - u32 addr; - u32 data32; - u32 bytes; - u8 *ptmp; - int ret; - - padapter = (struct adapter *)rtw_netdev_priv(dev); - p = &wrqu->data; - len = p->length; - ptmp = memdup_user(p->pointer, len); - if (IS_ERR(ptmp)) - return PTR_ERR(ptmp); - - bytes = 0; - addr = 0; - sscanf(ptmp, "%d,%x", &bytes, &addr); - - switch (bytes) { - case 1: - data32 = rtw_read8(padapter, addr); - sprintf(extra, "0x%02X", data32); - break; - case 2: - data32 = rtw_read16(padapter, addr); - sprintf(extra, "0x%04X", data32); - break; - case 4: - data32 = rtw_read32(padapter, addr); - sprintf(extra, "0x%08X", data32); - break; - default: - ret = -EINVAL; - goto err_free_ptmp; - } - - kfree(ptmp); - return 0; - -err_free_ptmp: - kfree(ptmp); - return ret; -} - -static int rtw_wx_write32(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); - - u32 addr; - u32 data32; - u32 bytes; - - bytes = 0; - addr = 0; - data32 = 0; - sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32); - - switch (bytes) { - case 1: - rtw_write8(padapter, addr, (u8)data32); - break; - case 2: - rtw_write16(padapter, addr, (u16)data32); - break; - case 4: - rtw_write32(padapter, addr, data32); - break; - default: - return -EINVAL; - } - - return 0; -} - static int rtw_wx_read_rf(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) @@ -3897,8 +3815,8 @@ static const struct iw_priv_args rtw_pri };
static iw_handler rtw_private_handler[] = { -rtw_wx_write32, /* 0x00 */ -rtw_wx_read32, /* 0x01 */ + NULL, /* 0x00 */ + NULL, /* 0x01 */ NULL, /* 0x02 */ NULL, /* 0x03 */ /* for MM DTV platform */
From: Carlos Llamas cmllamas@google.com
commit 8cc5b032240ae5220b62c689c20459d3e1825b2d upstream.
The {pid,uid}_t fields of struct binder_transaction were recently replaced to use kernel types in commit 169adc2b6b3c ("android/binder.h: add linux/android/binder(fs).h to UAPI compile-test coverage").
However, using __kernel_uid_t here breaks backwards compatibility in architectures using 16-bits for this type, since glibc and some others still expect a 32-bit uid_t. Instead, let's use __kernel_uid32_t which avoids this compatibility problem.
Fixes: 169adc2b6b3c ("android/binder.h: add linux/android/binder(fs).h to UAPI compile-test coverage") Reported-by: Christopher Ferris cferris@google.com Signed-off-by: Carlos Llamas cmllamas@google.com Acked-by: Todd Kjos tkjos@google.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/android/binder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -289,7 +289,7 @@ struct binder_transaction_data { /* General information about the transaction. */ __u32 flags; __kernel_pid_t sender_pid; - __kernel_uid_t sender_euid; + __kernel_uid32_t sender_euid; binder_size_t data_size; /* number of bytes of data */ binder_size_t offsets_size; /* number of bytes of offsets */
From: Yixing Liu liuyixing1@huawei.com
commit db5dfbf5b201df65c1f5332c4d9d5e7c2f42396b upstream.
The bt number of cqc_timer of HIP09 increases compared with that of HIP08. Therefore, cqc_timer_bt_num and num_cqc_timer do not match. As a result, the driver may fail to allocate cqc_timer. So the driver needs to uniquely uses cqc_timer_bt_num to represent the bt number of cqc_timer.
Fixes: 0e40dc2f70cd ("RDMA/hns: Add timer allocation support for hip08") Link: https://lore.kernel.org/r/20220429093545.58070-1-liangwenpeng@huawei.com Signed-off-by: Yixing Liu liuyixing1@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/infiniband/hw/hns/hns_roce_device.h | 1 - drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +-- drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +- drivers/infiniband/hw/hns/hns_roce_main.c | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/infiniband/hw/hns/hns_roce_device.h +++ b/drivers/infiniband/hw/hns/hns_roce_device.h @@ -731,7 +731,6 @@ struct hns_roce_caps { u32 num_pi_qps; u32 reserved_qps; int num_qpc_timer; - int num_cqc_timer; u32 num_srqs; u32 max_wqes; u32 max_srq_wrs; --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1965,7 +1965,7 @@ static void set_default_caps(struct hns_ caps->num_mtpts = HNS_ROCE_V2_MAX_MTPT_NUM; caps->num_pds = HNS_ROCE_V2_MAX_PD_NUM; caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM; - caps->num_cqc_timer = HNS_ROCE_V2_MAX_CQC_TIMER_NUM; + caps->cqc_timer_bt_num = HNS_ROCE_V2_MAX_CQC_TIMER_BT_NUM;
caps->max_qp_init_rdma = HNS_ROCE_V2_MAX_QP_INIT_RDMA; caps->max_qp_dest_rdma = HNS_ROCE_V2_MAX_QP_DEST_RDMA; @@ -2261,7 +2261,6 @@ static int hns_roce_query_pf_caps(struct caps->max_rq_sg = roundup_pow_of_two(caps->max_rq_sg); caps->max_extend_sg = le32_to_cpu(resp_a->max_extend_sg); caps->num_qpc_timer = le16_to_cpu(resp_a->num_qpc_timer); - caps->num_cqc_timer = le16_to_cpu(resp_a->num_cqc_timer); caps->max_srq_sges = le16_to_cpu(resp_a->max_srq_sges); caps->max_srq_sges = roundup_pow_of_two(caps->max_srq_sges); caps->num_aeq_vectors = resp_a->num_aeq_vectors; --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -41,7 +41,7 @@ #define HNS_ROCE_V2_MAX_SRQ_WR 0x8000 #define HNS_ROCE_V2_MAX_SRQ_SGE 64 #define HNS_ROCE_V2_MAX_CQ_NUM 0x100000 -#define HNS_ROCE_V2_MAX_CQC_TIMER_NUM 0x100 +#define HNS_ROCE_V2_MAX_CQC_TIMER_BT_NUM 0x100 #define HNS_ROCE_V2_MAX_SRQ_NUM 0x100000 #define HNS_ROCE_V2_MAX_CQE_NUM 0x400000 #define HNS_ROCE_V2_MAX_RQ_SGE_NUM 64 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -737,7 +737,7 @@ static int hns_roce_init_hem(struct hns_ ret = hns_roce_init_hem_table(hr_dev, &hr_dev->cqc_timer_table, HEM_TYPE_CQC_TIMER, hr_dev->caps.cqc_timer_entry_sz, - hr_dev->caps.num_cqc_timer, 1); + hr_dev->caps.cqc_timer_bt_num, 1); if (ret) { dev_err(dev, "Failed to init CQC timer memory, aborting.\n");
From: Xiao Yang yangx.jy@fujitsu.com
commit 2f917af777011c88e977b9b9a5d00b280d3a59ce upstream.
Current rxe_requester() doesn't generate a completion when processing an unsupported/invalid opcode. If rxe driver doesn't support a new opcode (e.g. RDMA Atomic Write) and RDMA library supports it, an application using the new opcode can reproduce this issue. Fix the issue by calling "goto err;".
Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20220410113513.27537-1-yangx.jy@fujitsu.com Signed-off-by: Xiao Yang yangx.jy@fujitsu.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/infiniband/sw/rxe/rxe_req.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -661,7 +661,7 @@ next_wqe: opcode = next_opcode(qp, wqe, wqe->wr.opcode); if (unlikely(opcode < 0)) { wqe->status = IB_WC_LOC_QP_OP_ERR; - goto exit; + goto err; }
mask = rxe_opcode[opcode].mask;
From: Eric Biggers ebiggers@google.com
commit 5f41fdaea63ddf96d921ab36b2af4a90ccdb5744 upstream.
Make the test_dummy_encryption mount option require that the encrypt feature flag be already enabled on the filesystem, rather than automatically enabling it. Practically, this means that "-O encrypt" will need to be included in MKFS_OPTIONS when running xfstests with the test_dummy_encryption mount option. (ext4/053 also needs an update.)
Moreover, as long as the preconditions for test_dummy_encryption are being tightened anyway, take the opportunity to start rejecting it when !CONFIG_FS_ENCRYPTION rather than ignoring it.
The motivation for requiring the encrypt feature flag is that:
- Having the filesystem auto-enable feature flags is problematic, as it bypasses the usual sanity checks. The specific issue which came up recently is that in kernel versions where ext4 supports casefold but not encrypt+casefold (v5.1 through v5.10), the kernel will happily add the encrypt flag to a filesystem that has the casefold flag, making it unmountable -- but only for subsequent mounts, not the initial one. This confused the casefold support detection in xfstests, causing generic/556 to fail rather than be skipped.
- The xfstests-bld test runners (kvm-xfstests et al.) already use the required mkfs flag, so they will not be affected by this change. Only users of test_dummy_encryption alone will be affected. But, this option has always been for testing only, so it should be fine to require that the few users of this option update their test scripts.
- f2fs already requires it (for its equivalent feature flag).
Signed-off-by: Eric Biggers ebiggers@google.com Reviewed-by: Gabriel Krisman Bertazi krisman@collabora.com Link: https://lore.kernel.org/r/20220519204437.61645-1-ebiggers@kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/ext4.h | 6 ----- fs/ext4/super.c | 60 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 28 deletions(-)
--- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1440,12 +1440,6 @@ struct ext4_super_block {
#ifdef __KERNEL__
-#ifdef CONFIG_FS_ENCRYPTION -#define DUMMY_ENCRYPTION_ENABLED(sbi) ((sbi)->s_dummy_enc_policy.policy != NULL) -#else -#define DUMMY_ENCRYPTION_ENABLED(sbi) (0) -#endif - /* Number of quota types we support */ #define EXT4_MAXQUOTAS 3
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2428,11 +2428,12 @@ static int ext4_parse_param(struct fs_co ctx->spec |= EXT4_SPEC_DUMMY_ENCRYPTION; ctx->test_dummy_enc_arg = kmemdup_nul(param->string, param->size, GFP_KERNEL); + return 0; #else ext4_msg(NULL, KERN_WARNING, - "Test dummy encryption mount option ignored"); + "test_dummy_encryption option not supported"); + return -EINVAL; #endif - return 0; case Opt_dax: case Opt_dax_type: #ifdef CONFIG_FS_DAX @@ -2789,12 +2790,44 @@ err_jquota_specified: #endif }
+static int ext4_check_test_dummy_encryption(const struct fs_context *fc, + struct super_block *sb) +{ +#ifdef CONFIG_FS_ENCRYPTION + const struct ext4_fs_context *ctx = fc->fs_private; + const struct ext4_sb_info *sbi = EXT4_SB(sb); + + if (!(ctx->spec & EXT4_SPEC_DUMMY_ENCRYPTION)) + return 0; + + if (!ext4_has_feature_encrypt(sb)) { + ext4_msg(NULL, KERN_WARNING, + "test_dummy_encryption requires encrypt feature"); + return -EINVAL; + } + /* + * This mount option is just for testing, and it's not worthwhile to + * implement the extra complexity (e.g. RCU protection) that would be + * needed to allow it to be set or changed during remount. We do allow + * it to be specified during remount, but only if there is no change. + */ + if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE && + !sbi->s_dummy_enc_policy.policy) { + ext4_msg(NULL, KERN_WARNING, + "Can't set test_dummy_encryption on remount"); + return -EINVAL; + } +#endif /* CONFIG_FS_ENCRYPTION */ + return 0; +} + static int ext4_check_opt_consistency(struct fs_context *fc, struct super_block *sb) { struct ext4_fs_context *ctx = fc->fs_private; struct ext4_sb_info *sbi = fc->s_fs_info; int is_remount = fc->purpose == FS_CONTEXT_FOR_RECONFIGURE; + int err;
if ((ctx->opt_flags & MOPT_NO_EXT2) && IS_EXT2_SB(sb)) { ext4_msg(NULL, KERN_ERR, @@ -2824,20 +2857,9 @@ static int ext4_check_opt_consistency(st "for blocksize < PAGE_SIZE"); }
-#ifdef CONFIG_FS_ENCRYPTION - /* - * This mount option is just for testing, and it's not worthwhile to - * implement the extra complexity (e.g. RCU protection) that would be - * needed to allow it to be set or changed during remount. We do allow - * it to be specified during remount, but only if there is no change. - */ - if ((ctx->spec & EXT4_SPEC_DUMMY_ENCRYPTION) && - is_remount && !sbi->s_dummy_enc_policy.policy) { - ext4_msg(NULL, KERN_WARNING, - "Can't set test_dummy_encryption on remount"); - return -1; - } -#endif + err = ext4_check_test_dummy_encryption(fc, sb); + if (err) + return err;
if ((ctx->spec & EXT4_SPEC_DATAJ) && is_remount) { if (!sbi->s_journal) { @@ -5283,12 +5305,6 @@ no_journal: goto failed_mount_wq; }
- if (DUMMY_ENCRYPTION_ENABLED(sbi) && !sb_rdonly(sb) && - !ext4_has_feature_encrypt(sb)) { - ext4_set_feature_encrypt(sb); - ext4_commit_super(sb); - } - /* * Get the # of file system overhead blocks from the * superblock if present.
From: Christian Brauner brauner@kernel.org
commit 00675017e0aeba5305665c52ded4ddce6a4c0231 upstream.
Similar to the addition of lookup_one() add a version of lookup_one_unlocked() and lookup_one_positive_unlocked() that take idmapped mounts into account. This is required to port overlay to support idmapped base layers.
Cc: linux-fsdevel@vger.kernel.org Tested-by: Giuseppe Scrivano gscrivan@redhat.com Reviewed-by: Amir Goldstein amir73il@gmail.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/namei.c | 70 ++++++++++++++++++++++++++++++++++++++++++-------- include/linux/namei.h | 6 ++++ 2 files changed, 66 insertions(+), 10 deletions(-)
--- a/fs/namei.c +++ b/fs/namei.c @@ -2768,7 +2768,8 @@ struct dentry *lookup_one(struct user_na EXPORT_SYMBOL(lookup_one);
/** - * lookup_one_len_unlocked - filesystem helper to lookup single pathname component + * lookup_one_unlocked - filesystem helper to lookup single pathname component + * @mnt_userns: idmapping of the mount the lookup is performed from * @name: pathname component to lookup * @base: base directory to lookup from * @len: maximum length @len should be interpreted to @@ -2779,14 +2780,15 @@ EXPORT_SYMBOL(lookup_one); * Unlike lookup_one_len, it should be called without the parent * i_mutex held, and will take the i_mutex itself if necessary. */ -struct dentry *lookup_one_len_unlocked(const char *name, - struct dentry *base, int len) +struct dentry *lookup_one_unlocked(struct user_namespace *mnt_userns, + const char *name, struct dentry *base, + int len) { struct qstr this; int err; struct dentry *ret;
- err = lookup_one_common(&init_user_ns, name, base, len, &this); + err = lookup_one_common(mnt_userns, name, base, len, &this); if (err) return ERR_PTR(err);
@@ -2795,6 +2797,59 @@ struct dentry *lookup_one_len_unlocked(c ret = lookup_slow(&this, base, 0); return ret; } +EXPORT_SYMBOL(lookup_one_unlocked); + +/** + * lookup_one_positive_unlocked - filesystem helper to lookup single + * pathname component + * @mnt_userns: idmapping of the mount the lookup is performed from + * @name: pathname component to lookup + * @base: base directory to lookup from + * @len: maximum length @len should be interpreted to + * + * This helper will yield ERR_PTR(-ENOENT) on negatives. The helper returns + * known positive or ERR_PTR(). This is what most of the users want. + * + * Note that pinned negative with unlocked parent _can_ become positive at any + * time, so callers of lookup_one_unlocked() need to be very careful; pinned + * positives have >d_inode stable, so this one avoids such problems. + * + * Note that this routine is purely a helper for filesystem usage and should + * not be called by generic code. + * + * The helper should be called without i_mutex held. + */ +struct dentry *lookup_one_positive_unlocked(struct user_namespace *mnt_userns, + const char *name, + struct dentry *base, int len) +{ + struct dentry *ret = lookup_one_unlocked(mnt_userns, name, base, len); + + if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) { + dput(ret); + ret = ERR_PTR(-ENOENT); + } + return ret; +} +EXPORT_SYMBOL(lookup_one_positive_unlocked); + +/** + * lookup_one_len_unlocked - filesystem helper to lookup single pathname component + * @name: pathname component to lookup + * @base: base directory to lookup from + * @len: maximum length @len should be interpreted to + * + * Note that this routine is purely a helper for filesystem usage and should + * not be called by generic code. + * + * Unlike lookup_one_len, it should be called without the parent + * i_mutex held, and will take the i_mutex itself if necessary. + */ +struct dentry *lookup_one_len_unlocked(const char *name, + struct dentry *base, int len) +{ + return lookup_one_unlocked(&init_user_ns, name, base, len); +} EXPORT_SYMBOL(lookup_one_len_unlocked);
/* @@ -2808,12 +2863,7 @@ EXPORT_SYMBOL(lookup_one_len_unlocked); struct dentry *lookup_positive_unlocked(const char *name, struct dentry *base, int len) { - struct dentry *ret = lookup_one_len_unlocked(name, base, len); - if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) { - dput(ret); - ret = ERR_PTR(-ENOENT); - } - return ret; + return lookup_one_positive_unlocked(&init_user_ns, name, base, len); } EXPORT_SYMBOL(lookup_positive_unlocked);
--- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -69,6 +69,12 @@ extern struct dentry *lookup_one_len(con extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int); extern struct dentry *lookup_positive_unlocked(const char *, struct dentry *, int); struct dentry *lookup_one(struct user_namespace *, const char *, struct dentry *, int); +struct dentry *lookup_one_unlocked(struct user_namespace *mnt_userns, + const char *name, struct dentry *base, + int len); +struct dentry *lookup_one_positive_unlocked(struct user_namespace *mnt_userns, + const char *name, + struct dentry *base, int len);
extern int follow_down_one(struct path *); extern int follow_down(struct path *);
From: Christian Brauner brauner@kernel.org
commit 3a761d72fa62eec8913e45d29375344f61706541 upstream.
Make the two locations where exportfs helpers check permission to lookup a given inode idmapped mount aware by switching it to the lookup_one() helper. This is a bugfix for the open_by_handle_at() system call which doesn't take idmapped mounts into account currently. It's not tied to a specific commit so we'll just Cc stable.
In addition this is required to support idmapped base layers in overlay. The overlay filesystem uses exportfs to encode and decode file handles for its index=on mount option and when nfs_export=on.
Cc: stable@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Tested-by: Giuseppe Scrivano gscrivan@redhat.com Reviewed-by: Amir Goldstein amir73il@gmail.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Christian Brauner (Microsoft) brauner@kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/exportfs/expfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -145,7 +145,7 @@ static struct dentry *reconnect_one(stru if (err) goto out_err; dprintk("%s: found name: %s\n", __func__, nbuf); - tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf)); + tmp = lookup_one_unlocked(mnt_user_ns(mnt), nbuf, parent, strlen(nbuf)); if (IS_ERR(tmp)) { dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp)); err = PTR_ERR(tmp); @@ -525,7 +525,8 @@ exportfs_decode_fh_raw(struct vfsmount * }
inode_lock(target_dir->d_inode); - nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf)); + nresult = lookup_one(mnt_user_ns(mnt), nbuf, + target_dir, strlen(nbuf)); if (!IS_ERR(nresult)) { if (unlikely(nresult->d_inode != result->d_inode)) { dput(nresult);
From: Namjae Jeon linkinjeon@kernel.org
commit f26967b9f7a830e228bb13fb41bd516ddd9d789d upstream.
log_read_rst() returns ENOMEM error when there is not enough memory. In this case, if info is returned without initialization, it attempts to kfree the uninitialized info->r_page pointer. This patch moves the memset initialization code to before log_read_rst() is called.
Reported-by: Gerald Lee sundaywind2004@gmail.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ntfs3/fslog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -1185,8 +1185,6 @@ static int log_read_rst(struct ntfs_log if (!r_page) return -ENOMEM;
- memset(info, 0, sizeof(struct restart_info)); - /* Determine which restart area we are looking for. */ if (first) { vbo = 0; @@ -3791,10 +3789,11 @@ int log_replay(struct ntfs_inode *ni, bo if (!log) return -ENOMEM;
+ memset(&rst_info, 0, sizeof(struct restart_info)); + log->ni = ni; log->l_size = l_size; log->one_page_buf = kmalloc(page_size, GFP_NOFS); - if (!log->one_page_buf) { err = -ENOMEM; goto out; @@ -3842,6 +3841,7 @@ int log_replay(struct ntfs_inode *ni, bo if (rst_info.vbo) goto check_restart_area;
+ memset(&rst_info2, 0, sizeof(struct restart_info)); err = log_read_rst(log, l_size, false, &rst_info2);
/* Determine which restart area to use. */
From: Xiao Ni xni@redhat.com
commit 0f2571ad7a30ff6b33cde142439f9378669f8b4f upstream.
In normal stop process, it does like this: do_md_stop | __md_stop (pers->free(); mddev->private=NULL) | md_free (free mddev) __md_stop sets mddev->private to NULL after pers->free. The raid device will be stopped and mddev memory is free. But in reshape, it doesn't free the mddev and mddev will still be used in new raid.
In reshape, it first sets mddev->private to new_pers and then runs old_pers->free(). Now raid0 sets mddev->private to NULL in raid0_free. The new raid can't work anymore. It will panic when dereference mddev->private because of NULL pointer dereference.
It can panic like this: [63010.814972] kernel BUG at drivers/md/raid10.c:928! [63010.819778] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [63010.825011] CPU: 3 PID: 44437 Comm: md0_resync Kdump: loaded Not tainted 5.14.0-86.el9.x86_64 #1 [63010.833789] Hardware name: Dell Inc. PowerEdge R6415/07YXFK, BIOS 1.15.0 09/11/2020 [63010.841440] RIP: 0010:raise_barrier+0x161/0x170 [raid10] [63010.865508] RSP: 0018:ffffc312408bbc10 EFLAGS: 00010246 [63010.870734] RAX: 0000000000000000 RBX: ffffa00bf7d39800 RCX: 0000000000000000 [63010.877866] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffa00bf7d39800 [63010.884999] RBP: 0000000000000000 R08: fffffa4945e74400 R09: 0000000000000000 [63010.892132] R10: ffffa00eed02f798 R11: 0000000000000000 R12: ffffa00bbc435200 [63010.899266] R13: ffffa00bf7d39800 R14: 0000000000000400 R15: 0000000000000003 [63010.906399] FS: 0000000000000000(0000) GS:ffffa00eed000000(0000) knlGS:0000000000000000 [63010.914485] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [63010.920229] CR2: 00007f5cfbe99828 CR3: 0000000105efe000 CR4: 00000000003506e0 [63010.927363] Call Trace: [63010.929822] ? bio_reset+0xe/0x40 [63010.933144] ? raid10_alloc_init_r10buf+0x60/0xa0 [raid10] [63010.938629] raid10_sync_request+0x756/0x1610 [raid10] [63010.943770] md_do_sync.cold+0x3e4/0x94c [63010.947698] md_thread+0xab/0x160 [63010.951024] ? md_write_inc+0x50/0x50 [63010.954688] kthread+0x149/0x170 [63010.957923] ? set_kthread_struct+0x40/0x40 [63010.962107] ret_from_fork+0x22/0x30
Removing the code that sets mddev->private to NULL in raid0 can fix problem.
Fixes: 0c031fd37f69 (md: Move alloc/free acct bioset in to personality) Reported-by: Fine Fan ffan@redhat.com Signed-off-by: Xiao Ni xni@redhat.com Signed-off-by: Song Liu song@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid0.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -361,7 +361,6 @@ static void free_conf(struct mddev *mdde kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - mddev->private = NULL; }
static void raid0_free(struct mddev *mddev, void *priv)
From: Xiao Ni xni@redhat.com
commit 42b805af102471f53e3c7867b8c2b502ea4eef7e upstream.
Now io_acct_set is alloc and free in personality. Remove the codes that free io_acct_set in md_free and md_stop.
Fixes: 0c031fd37f69 (md: Move alloc/free acct bioset in to personality) Signed-off-by: Xiao Ni xni@redhat.com Signed-off-by: Song Liu song@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/md.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5598,8 +5598,6 @@ static void md_free(struct kobject *ko)
bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - if (mddev->level != 1 && mddev->level != 10) - bioset_exit(&mddev->io_acct_set); kfree(mddev); }
@@ -6286,8 +6284,6 @@ void md_stop(struct mddev *mddev) __md_stop(mddev); bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); - if (mddev->level != 1 && mddev->level != 10) - bioset_exit(&mddev->io_acct_set); }
EXPORT_SYMBOL_GPL(md_stop);
From: Jia-Ju Bai baijiaju1990@gmail.com
commit 40f567bbb3b0639d2ec7d1c6ad4b1b018f80cf19 upstream.
The function kzalloc() in detached_dev_do_request() can fail, so its return value should be checked.
Fixes: bc082a55d25c ("bcache: fix inaccurate io state for detached bcache devices") Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Signed-off-by: Coly Li colyli@suse.de Link: https://lore.kernel.org/r/20220527152818.27545-4-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/request.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -1105,6 +1105,12 @@ static void detached_dev_do_request(stru * which would call closure_get(&dc->disk.cl) */ ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO); + if (!ddip) { + bio->bi_status = BLK_STS_RESOURCE; + bio->bi_end_io(bio); + return; + } + ddip->d = d; /* Count on the bcache device */ ddip->orig_bdev = orig_bdev;
From: Ziyang Xuan william.xuanziyang@huawei.com
commit 196a888ca6571deb344468e1d7138e3273206335 upstream.
Create a new macsec device but not get reference to real_dev. That can not ensure that real_dev is freed after macsec. That will trigger the UAF bug for real_dev as following:
================================================================== BUG: KASAN: use-after-free in macsec_get_iflink+0x5f/0x70 drivers/net/macsec.c:3662 Call Trace: ... macsec_get_iflink+0x5f/0x70 drivers/net/macsec.c:3662 dev_get_iflink+0x73/0xe0 net/core/dev.c:637 default_operstate net/core/link_watch.c:42 [inline] rfc2863_policy+0x233/0x2d0 net/core/link_watch.c:54 linkwatch_do_dev+0x2a/0x150 net/core/link_watch.c:161
Allocated by task 22209: ... alloc_netdev_mqs+0x98/0x1100 net/core/dev.c:10549 rtnl_create_link+0x9d7/0xc00 net/core/rtnetlink.c:3235 veth_newlink+0x20e/0xa90 drivers/net/veth.c:1748
Freed by task 8: ... kfree+0xd6/0x4d0 mm/slub.c:4552 kvfree+0x42/0x50 mm/util.c:615 device_release+0x9f/0x240 drivers/base/core.c:2229 kobject_cleanup lib/kobject.c:673 [inline] kobject_release lib/kobject.c:704 [inline] kref_put include/linux/kref.h:65 [inline] kobject_put+0x1c8/0x540 lib/kobject.c:721 netdev_run_todo+0x72e/0x10b0 net/core/dev.c:10327
After commit faab39f63c1f ("net: allow out-of-order netdev unregistration") and commit e5f80fcf869a ("ipv6: give an IPv6 dev to blackhole_netdev"), we can add dev_hold_track() in macsec_dev_init() and dev_put_track() in macsec_free_netdev() to fix the problem.
Fixes: 2bce1ebed17d ("macsec: fix refcnt leak in module exit routine") Reported-by: syzbot+d0e94b65ac259c29ce7a@syzkaller.appspotmail.com Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Link: https://lore.kernel.org/r/20220531074500.1272846-1-william.xuanziyang@huawei... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/macsec.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -99,6 +99,7 @@ struct pcpu_secy_stats { * struct macsec_dev - private data * @secy: SecY config * @real_dev: pointer to underlying netdevice + * @dev_tracker: refcount tracker for @real_dev reference * @stats: MACsec device stats * @secys: linked list of SecY's on the underlying device * @gro_cells: pointer to the Generic Receive Offload cell @@ -107,6 +108,7 @@ struct pcpu_secy_stats { struct macsec_dev { struct macsec_secy secy; struct net_device *real_dev; + netdevice_tracker dev_tracker; struct pcpu_secy_stats __percpu *stats; struct list_head secys; struct gro_cells gro_cells; @@ -3459,6 +3461,9 @@ static int macsec_dev_init(struct net_de if (is_zero_ether_addr(dev->broadcast)) memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
+ /* Get macsec's reference to real_dev */ + dev_hold_track(real_dev, &macsec->dev_tracker, GFP_KERNEL); + return 0; }
@@ -3704,6 +3709,8 @@ static void macsec_free_netdev(struct ne free_percpu(macsec->stats); free_percpu(macsec->secy.tx_sc.stats);
+ /* Get rid of the macsec's reference to real_dev */ + dev_put_track(macsec->real_dev, &macsec->dev_tracker); }
static void macsec_setup(struct net_device *dev)
From: Tony Lindgren tony@atomide.com
commit 925ea0fa5277c1e6bb9e51955ef34eea9736c3d7 upstream.
The module param debug for n_gsm uses KERN_INFO level, but the hexdump now uses KERN_DEBUG level. This started after commit 091cb0994edd ("lib/hexdump: make print_hex_dump_bytes() a nop on !DEBUG builds"). We now use dynamic_hex_dump() unless DEBUG is set.
This causes no packets to be seen with modprobe n_gsm debug=0x1f unlike earlier. Let's fix this by adding gsm_hex_dump_bytes() that calls print_hex_dump() with KERN_INFO to match what n_gsm is doing with the other debug related output.
Fixes: 091cb0994edd ("lib/hexdump: make print_hex_dump_bytes() a nop on !DEBUG builds") Cc: Stephen Boyd swboyd@chromium.org Signed-off-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20220512131506.1216-1-tony@atomide.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/n_gsm.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)
--- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -444,6 +444,25 @@ static u8 gsm_encode_modem(const struct return modembits; }
+static void gsm_hex_dump_bytes(const char *fname, const u8 *data, + unsigned long len) +{ + char *prefix; + + if (!fname) { + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, data, len, + true); + return; + } + + prefix = kasprintf(GFP_KERNEL, "%s: ", fname); + if (!prefix) + return; + print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_OFFSET, 16, 1, data, len, + true); + kfree(prefix); +} + /** * gsm_print_packet - display a frame for debug * @hdr: header to print before decode @@ -508,7 +527,7 @@ static void gsm_print_packet(const char else pr_cont("(F)");
- print_hex_dump_bytes("", DUMP_PREFIX_NONE, data, dlen); + gsm_hex_dump_bytes(NULL, data, dlen); }
@@ -698,9 +717,7 @@ static void gsm_data_kick(struct gsm_mux }
if (debug & 4) - print_hex_dump_bytes("gsm_data_kick: ", - DUMP_PREFIX_OFFSET, - gsm->txframe, len); + gsm_hex_dump_bytes(__func__, gsm->txframe, len); if (gsmld_output(gsm, gsm->txframe, len) <= 0) break; /* FIXME: Can eliminate one SOF in many more cases */ @@ -2448,8 +2465,7 @@ static int gsmld_output(struct gsm_mux * return -ENOSPC; } if (debug & 4) - print_hex_dump_bytes("gsmld_output: ", DUMP_PREFIX_OFFSET, - data, len); + gsm_hex_dump_bytes(__func__, data, len); return gsm->tty->ops->write(gsm->tty, data, len); }
@@ -2525,8 +2541,7 @@ static void gsmld_receive_buf(struct tty char flags = TTY_NORMAL;
if (debug & 4) - print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET, - cp, count); + gsm_hex_dump_bytes(__func__, cp, count);
for (; count; count--, cp++) { if (fp)
On Tue, Jun 7, 2022 at 1:32 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
Hi Greg,
Compiled and booted on my test system Lenovo P50s: Intel Core i7 No emergency and critical messages in the dmesg
./perf bench sched all # Running sched/messaging benchmark... # 20 sender and receiver processes per group # 10 groups == 400 processes run
Total time: 0.447 [sec]
# Running sched/pipe benchmark... # Executed 1000000 pipe operations between two processes
Total time: 10.055 [sec]
10.055368 usecs/op 99449 ops/sec
Tested-by: Zan Aziz zanaziz313@gmail.com
Thanks -Zan
On 6/7/22 10:51 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On 6/7/22 9:51 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Tested-by: Ron Economos re@w6rz.net
Hey Greg,
Ran tests and boot tested on my system, no regressions found
Tested-by: Fenil Jain fkjainco@gmail.com
On Wed, 8 Jun 2022 at 00:16, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 5.18.3-rc1 * git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc * git branch: linux-5.18.y * git commit: 09bf95a7c28a7069eb8bb958d434a575a0c63454 * git describe: v5.18.2-880-g09bf95a7c28a * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.18.y/build/v5.18....
## Test Regressions (compared to v5.18.2) No test regressions found.
## Metric Regressions (compared to v5.18.2) No metric regressions found.
## Test Fixes (compared to v5.18.2) No test fixes found.
## Metric Fixes (compared to v5.18.2) No metric fixes found.
## Test result summary total: 136450, pass: 124786, fail: 519, skip: 10295, xfail: 850
## Build Summary * arm: 17 total, 14 passed, 3 failed * arm64: 20 total, 18 passed, 2 failed * i386: 17 total, 12 passed, 5 failed * mips: 4 total, 1 passed, 3 failed * parisc: 2 total, 2 passed, 0 failed * powerpc: 5 total, 2 passed, 3 failed * riscv: 5 total, 5 passed, 0 failed * s390: 5 total, 2 passed, 3 failed * sh: 2 total, 0 passed, 2 failed * sparc: 2 total, 2 passed, 0 failed * x86_64: 20 total, 17 passed, 3 failed
## Test suites summary * fwts * igt-gpu-tools * kselftest-android * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers-dma-buf * kselftest-efivarfs * kselftest-filesystems * kselftest-filesystems-binderfs * kselftest-firmware * kselftest-fpu * kselftest-gpio * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-lib * kselftest-membarrier * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-rseq * kselftest-rtc * kselftest-seccomp * kselftest-sigaltstack * kselftest-size * kselftest-splice * kselftest-static_keys * kselftest-sync * kselftest-sysctl * kselftest-tc-testing * kselftest-timens * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user * kselftest-vm * kselftest-zram * kunit * kunit/15 * kunit/261 * kunit/3 * kunit/427 * kunit/90 * kvm-unit-tests * libgpiod * libhugetlbfs * log-parser-boot * log-parser-test * ltp-cap_bounds * ltp-cap_bounds-tests * ltp-commands * ltp-commands-tests * ltp-containers * ltp-containers-tests * ltp-controllers-tests * ltp-cpuhotplug-tests * ltp-crypto * ltp-crypto-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests * ltp-fcntl-locktests-tests * ltp-filecaps * ltp-filecaps-tests * ltp-fs * ltp-fs-tests * ltp-fs_bind * ltp-fs_bind-tests * ltp-fs_perms_simple * ltp-fs_perms_simple-tests * ltp-fsx * ltp-fsx-tests * ltp-hugetlb * ltp-hugetlb-tests * ltp-io * ltp-io-tests * ltp-ipc * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl * ltp-nptl-tests * ltp-open-posix-tests * ltp-pty * ltp-pty-tests * ltp-sched-tests * ltp-securebits * ltp-securebits-tests * ltp-syscalls-tests * ltp-tracing-tests * network-basic-tests * packetdrill * perf * rcutorture * ssuite * v4l2-compliance * vdso
-- Linaro LKFT https://lkft.linaro.org
On Tue, 7 Jun 2022 18:51:58 +0200, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
5.18.3-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Tested-by: Fox Chen foxhlchen@gmail.com
On Tue, Jun 07, 2022 at 06:51:58PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
thanks,
greg k-h
Tested rc1 against the Fedora build system (aarch64, armv7, ppc64le, s390x, x86_64), and boot tested x86_64. No regressions noted.
Tested-by: Justin M. Forbes jforbes@fedoraproject.org
On Tue, Jun 07, 2022 at 06:51:58PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +0000. Anything received after that time might be too late.
Build results: total: 154 pass: 154 fail: 0 Qemu test results: total: 489 pass: 489 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
On Tue, Jun 07, 2022 at 06:51:58PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully cross-compiled for arm (multi_v7_defconfig, GCC 12.1.0, armv7 with neon fpu) and arm64 (bcm2711_defconfig, GCC 12.1.0).
Tested-by: Bagas Sanjaya bagasdotme@gmail.com
On 07. 06. 22, 18:51, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.18.3 release. There are 879 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 09 Jun 2022 16:48:02 +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.18.3-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.18.y and the diffstat can be found below.
openSUSE configs¹⁾ all green.
Tested-by: Jiri Slaby jirislaby@kernel.org
¹⁾ armv6hl armv7hl arm64 i386 ppc64 ppc64le riscv64 s390x x86_64
linux-stable-mirror@lists.linaro.org