This is the start of the stable review cycle for the 5.15.5 release. There are 279 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 Fri, 26 Nov 2021 11:56:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.5-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.15.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 5.15.5-rc1
Randy Dunlap rdunlap@infradead.org x86/Kconfig: Fix an unused variable error in dell-smm-hwmon
Eric Dumazet edumazet@google.com net: add and use skb_unclone_keeptruesize() helper
Josef Bacik josef@toxicpanda.com btrfs: update device path inode time instead of bd_inode
Josef Bacik josef@toxicpanda.com fs: export an inode_update_time helper
Leon Romanovsky leon@kernel.org ice: Delete always true check of PF pointer
Brett Creeley brett.creeley@intel.com ice: Fix VF true promiscuous mode
Uwe Kleine-König u.kleine-koenig@pengutronix.de usb: max-3421: Use driver data instead of maintaining a list of bound devices
Kuninori Morimoto kuninori.morimoto.gx@renesas.com ASoC: rsnd: fixup DMAEngine API
Takashi Iwai tiwai@suse.de ASoC: DAPM: Cover regression by kctl change notification fix
Ondrej Mosnacek omosnace@redhat.com selinux: fix NULL-pointer dereference when hashtab allocation fails
Dmitrii Banshchikov me@ubique.spb.ru bpf: Forbid bpf_ktime_get_coarse_ns and bpf_timer_* in tracing progs
Leon Romanovsky leon@kernel.org RDMA/netlink: Add __maybe_unused to static inline in C file
Nadav Amit namit@vmware.com hugetlbfs: flush TLBs correctly after huge_pmd_unshare
Eric W. Biederman ebiederm@xmission.com signal: Replace force_fatal_sig with force_exit_sig when in doubt
Eric W. Biederman ebiederm@xmission.com signal: Don't always set SA_IMMUTABLE for forced signals
Eric W. Biederman ebiederm@xmission.com signal: Replace force_sigsegv(SIGSEGV) with force_fatal_sig(SIGSEGV)
Eric W. Biederman ebiederm@xmission.com signal/x86: In emulate_vsyscall force a signal instead of calling do_exit
Eric W. Biederman ebiederm@xmission.com signal/vm86_32: Properly send SIGSEGV when the vm86 state cannot be saved.
Eric W. Biederman ebiederm@xmission.com signal/sparc32: In setup_rt_frame and setup_fram use force_fatal_sig
Eric W. Biederman ebiederm@xmission.com signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer fails
Eric W. Biederman ebiederm@xmission.com signal/s390: Use force_sigsegv in default_trap_handler
Eric W. Biederman ebiederm@xmission.com signal/powerpc: On swapcontext failure force SIGSEGV
Eric W. Biederman ebiederm@xmission.com exit/syscall_user_dispatch: Send ordinary signals on failure
Eric W. Biederman ebiederm@xmission.com signal: Implement force_fatal_sig
Evan Quan evan.quan@amd.com drm/amd/pm: avoid duplicate powergate/ungate setting
hongao hongao@uniontech.com drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga and dvi connectors
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915: Fix type1 DVI DP dual mode adapter heuristic for modern platforms
Imre Deak imre.deak@intel.com drm/i915/dp: Ensure max link params are always valid
Imre Deak imre.deak@intel.com drm/i915/dp: Ensure sink rate values are always valid
Jeremy Cline jcline@redhat.com drm/nouveau: clean up all clients on device removal
Jeremy Cline jcline@redhat.com drm/nouveau: use drm_dev_unplug() during device removal
Jeremy Cline jcline@redhat.com drm/nouveau: Add a dedicated mutex for the clients list
Anand K Mistry amistry@google.com drm/prime: Fix use after free in mmap with drm_gem_ttm_mmap
Johan Hovold johan@kernel.org drm/udl: fix control-message timeout
Matthew Brost matthew.brost@intel.com drm/i915/guc: Unwind context requests in reverse order
Matthew Brost matthew.brost@intel.com drm/i915/guc: Don't drop ce->guc_active.lock when unwinding context
Matthew Brost matthew.brost@intel.com drm/i915/guc: Workaround reset G2H is received after schedule done G2H
Matthew Brost matthew.brost@intel.com drm/i915/guc: Don't enable scheduling on a banned context, guc_id invalid, not registered
Matthew Brost matthew.brost@intel.com drm/i915/guc: Fix outstanding G2H accounting
Roman Li Roman.Li@amd.com drm/amd/display: Limit max DSC target bpp for specific monitors
Alvin Lee Alvin.Lee2@amd.com drm/amd/display: Update swizzle mode enums
Felix Fietkau nbd@nbd.name mac80211: drop check for DONT_REORDER in __ieee80211_select_queue
Johannes Berg johannes.berg@intel.com mac80211: fix radiotap header generation
Nguyen Dinh Phi phind.uet@gmail.com cfg80211: call cfg80211_stop_ap when switch from P2P_GO type
Sven Schnelle svens@stackframe.org parisc/sticon: fix reverse colors
Thomas Gleixner tglx@linutronix.de net: stmmac: Fix signed/unsigned wreckage
Christian Brauner christian.brauner@ubuntu.com fs: handle circular mappings correctly
Nikolay Borisov nborisov@suse.com btrfs: fix memory ordering between normal and ordered work functions
Boqun Feng boqun.feng@gmail.com Drivers: hv: balloon: Use VMBUS_RING_SIZE() wrapper for dm_ring_size
Meng Li meng.li@windriver.com net: stmmac: socfpga: add runtime suspend/resume callback for stratix10 platform
Michael Walle michael@walle.cc spi: fix use-after-free of the add_lock mutex
Jan Kara jack@suse.cz udf: Fix crash after seekdir
Nicholas Piggin npiggin@gmail.com printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
Thomas Zimmermann tzimmermann@suse.de drm/cma-helper: Release non-coherent memory with dma_free_noncoherent()
Maxim Levitsky mlevitsk@redhat.com KVM: nVMX: don't use vcpu->arch.efer when checking host state on nested state load
Sean Christopherson seanjc@google.com KVM: SEV: Disallow COPY_ENC_CONTEXT_FROM if target has created vCPUs
Javier Martinez Canillas javierm@redhat.com fbdev: Prevent probing generic drivers if a FB is already registered
Alistair Delva adelva@google.com block: Check ADMIN before NICE for IOPRIO_CLASS_RT
Alexander Egorenkov egorenar@linux.ibm.com s390/dump: fix copying to user-space of swapped kdump oldmem
Baoquan He bhe@redhat.com s390/kexec: fix memory leak of ipl report buffer
Sven Schnelle svens@linux.ibm.com s390/vdso: filter out -mstack-guard and -mstack-size
Vasily Gorbik gor@linux.ibm.com s390/boot: simplify and fix kernel memory layout setup
Vasily Gorbik gor@linux.ibm.com s390/setup: avoid reserving memory above identity mapping
Sergio Paracuellos sergio.paracuellos@gmail.com pinctrl: ralink: include 'ralink_regs.h' in 'pinctrl-mt7620.c'
Ewan D. Milne emilne@redhat.com scsi: qla2xxx: Fix mailbox direction flags in qla2xxx_get_adapter_id()
Damien Le Moal damien.lemoal@opensource.wdc.com ata: libata: add missing ata_identify_page_supported() calls
Damien Le Moal damien.lemoal@opensource.wdc.com ata: libata: improve ata_read_log_page() error message
Helge Deller deller@gmx.de Revert "parisc: Reduce sigreturn trampoline to 3 instructions"
Vandita Kulkarni vandita.kulkarni@intel.com Revert "drm/i915/tgl/dsi: Gate the ddi clocks after pll mapping"
Christophe Leroy christophe.leroy@csgroup.eu powerpc/8xx: Fix pinned TLBs with CONFIG_STRICT_KERNEL_RWX
Cédric Le Goater clg@kaod.org powerpc/xive: Change IRQ domain to a tree domain
Christophe Leroy christophe.leroy@csgroup.eu powerpc/signal32: Fix sigset_t copy
David Woodhouse dwmw@amazon.co.uk KVM: x86/xen: Fix get_attr of KVM_XEN_ATTR_TYPE_SHARED_INFO
Maxim Levitsky mlevitsk@redhat.com KVM: x86/mmu: include EFER.LMA in extended mmu role
黄乐 huangle1@jd.com KVM: x86: Fix uninitialized eoi_exit_bitmap usage in vcpu_load_eoi_exitmap()
Tom Lendacky thomas.lendacky@amd.com KVM: x86: Assume a 64-bit hypercall for guests with protected state
Sean Christopherson seanjc@google.com x86/hyperv: Fix NULL deref in set_hv_tscchange_cb() if Hyper-V setup fails
Reinette Chatre reinette.chatre@intel.com x86/sgx: Fix free page accounting
Borislav Petkov bp@suse.de x86/boot: Pull up cmdline preparation and early param parsing
SeongJae Park sj@kernel.org mm/damon/dbgfs: fix missed use of damon_dbgfs_lock
SeongJae Park sj@kernel.org mm/damon/dbgfs: use '__GFP_NOWARN' for user-specified size buffer allocation
Ard Biesheuvel ardb@kernel.org kmap_local: don't assume kmap PTEs are linear arrays in memory
Mina Almasry almasrymina@google.com hugetlb, userfaultfd: fix reservation restore on userfaultfd error
Rustam Kovhaev rkovhaev@gmail.com mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag
Alexander Mikhalitsyn alexander.mikhalitsyn@virtuozzo.com shm: extend forced shm destroy to support objects from several IPC nses
Alexander Mikhalitsyn alexander.mikhalitsyn@virtuozzo.com ipc: WARN if trying to remove ipc object which is absent
Tadeusz Struk tadeusz.struk@linaro.org tipc: check for null after calling kmemdup
Nathan Chancellor nathan@kernel.org hexagon: clean up timer-regs.h
Nathan Chancellor nathan@kernel.org hexagon: export raw I/O routines for modules
Geert Uytterhoeven geert@linux-m68k.org pstore/blk: Use "%lu" to format unsigned long
Kees Cook keescook@chromium.org Revert "mark pstore-blk as broken"
Nicolas Dichtel nicolas.dichtel@6wind.com tun: fix bonding active backup with arp monitoring
Arnd Bergmann arnd@arndb.de dmaengine: remove debugfs #ifdef
Yu Kuai yukuai3@huawei.com blk-cgroup: fix missing put device in error path from blkg_conf_pref()
Heiko Carstens hca@linux.ibm.com s390/kexec: fix return code handling
Alexander Antonov alexander.antonov@linux.intel.com perf/x86/intel/uncore: Fix IIO event constraints for Snowridge
Alexander Antonov alexander.antonov@linux.intel.com perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server
Alexander Antonov alexander.antonov@linux.intel.com perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server
Bjorn Andersson bjorn.andersson@linaro.org pinctrl: qcom: sm8350: Correct UFS and SDC offsets
Bjorn Andersson bjorn.andersson@linaro.org pinctrl: qcom: sdm845: Enable dual edge errata
Nicholas Piggin npiggin@gmail.com powerpc/pseries: Fix numa FORM2 parsing fallback code
Nicholas Piggin npiggin@gmail.com powerpc/pseries: rename numa_dist_table to form2_distances
Masahiro Yamada masahiroy@kernel.org powerpc: clean vdso32 and vdso64 directories
Michael Ellerman mpe@ellerman.id.au KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr()
Andreas Schwab schwab@suse.de riscv: fix building external modules
Arnaldo Carvalho de Melo acme@redhat.com tools build: Fix removal of feature-sync-compare-and-swap feature detection
Sohaib Mohamed sohaib.amhmd@gmail.com perf bench: Fix two memory leaks detected with ASan
Dan Carpenter dan.carpenter@oracle.com ptp: ocp: Fix a couple NULL vs IS_ERR() checks
Jesse Brandeburg jesse.brandeburg@intel.com e100: fix device suspend/resume
Lin Ma linma@zju.edu.cn NFC: add NCI_UNREG flag to eliminate the race
Lin Ma linma@zju.edu.cn NFC: reorder the logic in nfc_{un,}register_device
Lin Ma linma@zju.edu.cn NFC: reorganize the functions in nci_request
Grzegorz Szczurek grzegorzx.szczurek@intel.com i40e: Fix display error code in dmesg
Jedrzej Jagielski jedrzej.jagielski@intel.com i40e: Fix creation of first queue by omitting it if is not power of two
Karen Sornek karen.sornek@intel.com i40e: Fix warning message and call stack during rmmod i40e driver
Jack Wang jinpu.wang@ionos.com RDMA/mlx4: Do not fail the registration on port stats
Eryk Rybak eryk.roch.rybak@intel.com i40e: Fix ping is lost after configuring ADq on VF
Eryk Rybak eryk.roch.rybak@intel.com i40e: Fix changing previously set num_queue_pairs for PFs
Michal Maloszewski michal.maloszewski@intel.com i40e: Fix NULL ptr dereference on VSI filter sync
Eryk Rybak eryk.roch.rybak@intel.com i40e: Fix correct max_pkt_size on VF RX queue
Jonathan Davies jonathan.davies@nutanix.com net: virtio_net_hdr_to_skb: count transport header in UFO
Pavel Skripkin paskripkin@gmail.com net: dpaa2-eth: fix use-after-free in dpaa2_eth_remove
Xin Long lucien.xin@gmail.com net: sched: act_mirred: drop dst for the direction from egress to ingress
Marcin Wojtas mw@semihalf.com net: mvmdio: fix compilation warning
Adrian Hunter adrian.hunter@intel.com scsi: ufs: core: Fix another task management completion race
Adrian Hunter adrian.hunter@intel.com scsi: ufs: core: Fix task management completion timeout race
Mike Christie michael.christie@oracle.com scsi: core: sysfs: Fix hang when device state is set via sysfs
Bart Van Assche bvanassche@acm.org scsi: ufs: core: Improve SCSI abort handling
Raed Salem raeds@nvidia.com net/mlx5: E-Switch, return error if encap isn't supported
Maher Sanalla msanalla@nvidia.com net/mlx5: Lag, update tracker when state change event received
Roi Dayan roid@nvidia.com net/mlx5e: CT, Fix multiple allocations and memleak of mod acts
Mark Bloch mbloch@nvidia.com net/mlx5: E-Switch, rebuild lag only when needed
Neta Ostrovsky netao@nvidia.com net/mlx5: Update error handler for UCTX and UMEM
Valentine Fatiev valentinef@nvidia.com net/mlx5e: nullify cq->dbg pointer in mlx5_debug_cq_remove()
Paul Blakey paulb@nvidia.com net/mlx5: E-Switch, Fix resetting of encap mode when entering switchdev
Vlad Buslov vladbu@nvidia.com net/mlx5e: Wait for concurrent flow deletion during neigh/fib events
Tariq Toukan tariqt@nvidia.com net/mlx5e: kTLS, Fix crash in RX resync flow
Leon Romanovsky leon@kernel.org RDMA/core: Set send and receive CQ before forwarding to the driver
Colin Ian King colin.i.king@googlemail.com btrfs: make 1-bit bit-fields of scrub_page unsigned int
Cong Wang cong.wang@bytedance.com udp: Validate checksum in udp_read_sock()
Alex Williamson alex.williamson@redhat.com platform/x86: think-lmi: Abort probe on analyze failure
Christophe JAILLET christophe.jaillet@wanadoo.fr platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()'
Randy Dunlap rdunlap@infradead.org gpio: rockchip: needs GENERIC_IRQ_CHIP to fix build errors
Randy Dunlap rdunlap@infradead.org mips: lantiq: add support for clk_get_parent()
Randy Dunlap rdunlap@infradead.org mips: bcm63xx: add support for clk_get_parent()
Colin Ian King colin.i.king@googlemail.com MIPS: generic/yamon-dt: fix uninitialized variable error
Daniel Borkmann daniel@iogearbox.net bpf: Fix toctou on read-only map's constant scalar tracking
Akeem G Abodunrin akeem.g.abodunrin@intel.com iavf: Restore VLAN filters after link down
Grzegorz Szczurek grzegorzx.szczurek@intel.com iavf: Fix for setting queues to 0
Surabhi Boob surabhi.boob@intel.com iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset
Mitch Williams mitch.a.williams@intel.com iavf: validate pointers
Jacob Keller jacob.e.keller@intel.com iavf: prevent accidental free of filter structure
Piotr Marczak piotr.marczak@intel.com iavf: Fix failure to exit out from last all-multicast mode
Nicholas Nunley nicholas.d.nunley@intel.com iavf: don't clear a lock we don't hold
Nicholas Nunley nicholas.d.nunley@intel.com iavf: free q_vectors before queues in iavf_disable_vf
Nicholas Nunley nicholas.d.nunley@intel.com iavf: check for null in iavf_fix_features
Mateusz Palczewski mateusz.palczewski@intel.com iavf: Fix return of set the new channel count
Chuck Lever chuck.lever@oracle.com NFSD: Fix exposure in nfsd4_decode_bitmap()
Wen Gu guwen@linux.alibaba.com net/smc: Make sure the link_id is unique
Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp sock: fix /proc/net/sockstat underflow in sk_clone_lock()
Xin Long lucien.xin@gmail.com tipc: only accept encrypted MSG_CRYPTO msgs
Sriharsha Basavapatna sriharsha.basavapatna@broadcom.com bnxt_en: reject indirect blk offload when hw-tc-offload is off
Pavel Skripkin paskripkin@gmail.com net: bnx2x: fix variable dereferenced before check
Li Zhijian lizhijian@cn.fujitsu.com selftests: gpio: fix gpio compiling error
Alex Elder elder@linaro.org net: ipa: disable HOLB drop when updating timer
Alex Elder elder@linaro.org net: ipa: HOLB register sometimes must be written twice
Johannes Berg johannes.berg@intel.com mac80211: fix monitor_sdata RCU/locking assertions
Johannes Berg johannes.berg@intel.com nl80211: fix radio statistics in survey dump
Steven Rostedt (VMware) rostedt@goodmis.org tracing: Add length protection to histogram string copies
Arjun Roy arjunroy@google.com tcp: Fix uninitialized access in skb frags array for Rx 0cp.
Konrad Dybcio konrad.dybcio@somainline.org net/ipa: ipa_resource: Fix wrong for loop range
Jakub Kicinski kuba@kernel.org selftests: net: switch to socat in the GSO GRE test
Kumar Kartikeya Dwivedi memxor@gmail.com samples/bpf: Fix incorrect use of strlen in xdp_redirect_cpu
Alexander Lobakin alexandr.lobakin@intel.com samples/bpf: Fix summary per-sec stats in xdp_sample_user
Alexei Starovoitov ast@kernel.org bpf: Fix inner map state pruning regression.
Hans Verkuil hverkuil-cisco@xs4all.nl drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame
James Clark james.clark@arm.com perf tests: Remove bash construct from record+zstd_comp_decomp.sh
Sohaib Mohamed sohaib.amhmd@gmail.com perf bench futex: Fix memory leak of perf_cpu_map__new()
Ian Rogers irogers@google.com perf bpf: Avoid memory leak from perf_env__insert_btf()
Masami Hiramatsu mhiramat@kernel.org tracing/histogram: Do not copy the fixed-size char array field over the field size
Laibin Qiu qiulaibin@huawei.com blkcg: Remove extra blkcg_bio_issue_init
Like Xu likexu@tencent.com perf/x86/vlbr: Add c->flags to vlbr event constraints
Mathias Krause minipli@grsecurity.net sched/fair: Prevent dead task groups from regaining cfs_rq's
Vincent Donnefort vincent.donnefort@arm.com sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain()
Randy Dunlap rdunlap@infradead.org MIPS: boot/compressed/: add __bswapdi2() to target for ZSTD decompression
Randy Dunlap rdunlap@infradead.org mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set
Quentin Perret qperret@google.com KVM: arm64: Fix host stage-2 finalization
Dmitry Baryshkov dmitry.baryshkov@linaro.org clk: qcom: gcc-msm8996: Drop (again) gcc_aggre1_pnoc_ahb_clk
Joel Stanley joel@jms.id.au clk/ast2600: Fix soc revision for AHB
Paul Cercueil paul@crapouillou.net clk: ingenic: Fix bugs with divided dividers
Chao Yu chao@kernel.org f2fs: fix incorrect return value in f2fs_sanity_check_ckpt()
Hyeong-Jun Kim hj514.kim@samsung.com f2fs: compress: disallow disabling compress on non-empty compressed file
Randy Dunlap rdunlap@infradead.org sh: define __BIG_ENDIAN for math-emu
Randy Dunlap rdunlap@infradead.org sh: math-emu: drop unused functions
Randy Dunlap rdunlap@infradead.org sh: fix kconfig unmet dependency warning for FRAME_POINTER
Chao Yu chao@kernel.org f2fs: fix wrong condition to trigger background checkpoint correctly
Keoseong Park keosung.park@samsung.com f2fs: fix to use WHINT_MODE
Gao Xiang hsiangkao@linux.alibaba.com f2fs: fix up f2fs_lookup tracepoints
Lu Wei luwei32@huawei.com maple: fix wrong return value of maple_bus_init().
Nick Desaulniers ndesaulniers@google.com sh: check return code of request_irq
Christophe Leroy christophe.leroy@csgroup.eu powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST
Michael Ellerman mpe@ellerman.id.au powerpc/dcr: Use cmplwi instead of 3-argument cmpli
Sven Peter sven@svenpeter.dev iommu/dart: Initialize DART_STREAMS_ENABLE
Claudiu Beznea claudiu.beznea@microchip.com clk: at91: sama7g5: remove prescaler part of master clock
Chengfeng Ye cyeaa@connect.ust.hk ALSA: usb-audio: fix null pointer dereference on pointer cs_desc
Chengfeng Ye cyeaa@connect.ust.hk ALSA: gus: fix null pointer dereference on pointer block
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: Fix node name of rpm-msg-ram device nodes
David Heidelberg david@ixit.cz ARM: dts: qcom: fix memory and mdio nodes naming for RB3011
Anatolij Gustschin agust@denx.de powerpc/5200: dts: fix memory node unit name
Dmitry Osipenko digetx@gmail.com memory: tegra20-emc: Add runtime dependency on devfreq governor module
James Smart jsmart2021@gmail.com scsi: lpfc: Allow fabric node recovery if recovery is in progress before devloss
James Smart jsmart2021@gmail.com scsi: lpfc: Fix link down processing to address NULL pointer dereference
James Smart jsmart2021@gmail.com scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine
wangyugui wangyugui@e16-tech.com RDMA/core: Use kvzalloc when allocating the struct ib_port
Teng Qi starmiku1207184332@gmail.com iio: imu: st_lsm6dsx: Avoid potential array overflow in st_lsm6dsx_set_odr()
Mike Christie michael.christie@oracle.com scsi: target: Fix alua_tg_pt_gps_count tracking
Mike Christie michael.christie@oracle.com scsi: target: Fix ordered tag handling
Ye Bin yebin10@huawei.com scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs()
Ye Bin yebin10@huawei.com scsi: scsi_debug: Fix out-of-bound read in resp_readcap16()
Bart Van Assche bvanassche@acm.org MIPS: sni: Fix the build
Guanghui Feng guanghuifeng@linux.alibaba.com tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc
Tvrtko Ursulin tvrtko.ursulin@intel.com iommu/vt-d: Do not falsely log intel_iommu is unsupported kernel option
Randy Dunlap rdunlap@infradead.org ALSA: ISA: not for M68K
Li Yang leoyang.li@nxp.com ARM: dts: ls1021a-tsn: use generic "jedec,spi-nor" compatible for flash
Li Yang leoyang.li@nxp.com ARM: dts: ls1021a: move thermal-zones node out of soc/
Derek Fang derek.fang@realtek.com ASoC: rt5682: fix a little pop while playback
Yang Yingliang yangyingliang@huawei.com usb: host: ohci-tmio: check return value after calling platform_get_resource()
Roger Quadros rogerq@kernel.org ARM: dts: omap: fix gpmc,mux-add-data type
William Overton willovertonuk@gmail.com ALSA: usb-audio: Add support for the Pioneer DJM 750MK2 Mixer/Soundcard
José Expósito jose.exposito89@gmail.com HID: multitouch: disable sticky fingers for UPERFECT Y
Dmitry Osipenko digetx@gmail.com cpuidle: tegra: Check whether PMC is ready
Luis Chamberlain mcgrof@kernel.org firmware_loader: fix pre-allocated buf built-in firmware use
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: Intel: sof_sdw: add missing quirk for Dell SKU 0A45
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: Intel: soc-acpi: add missing quirk for TGL SDCA single amp
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ALSA: intel-dsp-config: add quirk for APL/GLK/TGL devices based on ES8336 codec
Frieder Schrempf frieder.schrempf@kontron.de arm64: dts: imx8mm-kontron: Fix reset delays for ethernet PHY
Mahesh Rajashekhara mahesh.rajashekhara@microchip.com scsi: smartpqi: Add controller handshake during kdump
Guo Zhi qtxuning1999@sjtu.edu.cn scsi: advansys: Fix kernel pointer leak
Hans de Goede hdegoede@redhat.com ASoC: nau8824: Add DMI quirk mechanism for active-high jack-detect
Hans de Goede hdegoede@redhat.com ASoC: rt5651: Use IRQF_NO_AUTOEN when requesting the IRQ
Hans de Goede hdegoede@redhat.com ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ
Stefan Riedmueller s.riedmueller@phytec.de clk: imx: imx6ul: Move csi_sel mux to correct base register
Geraldo Nascimento geraldogabriel@gmail.com ALSA: usb-audio: disable implicit feedback sync for Behringer UFX1204 and UFX1604
Damien Le Moal damien.lemoal@wdc.com scsi: core: Fix scsi_mode_sense() buffer length handling
Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com ASoC: SOF: Intel: hda-dai: fix potential locking issue
Bob Pearson rpearsonhpe@gmail.com RDMA/rxe: Separate HW and SW l/rkeys
Kuldeep Singh kuldeep.singh@nxp.com arm64: dts: ls1012a: Add serial alias for ls1012a-rdb
Michael Walle michael@walle.cc arm64: dts: freescale: fix arm,sp805 compatible string
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: msm8916: Add unit name for /soc node
Shawn Guo shawn.guo@linaro.org arm64: dts: qcom: sdm845: Fix qcom,controlled-remotely property
Shawn Guo shawn.guo@linaro.org arm64: dts: qcom: ipq8074: Fix qcom,controlled-remotely property
Shawn Guo shawn.guo@linaro.org arm64: dts: qcom: ipq6018: Fix qcom,controlled-remotely property
AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org arm64: dts: qcom: msm8998: Fix CPU/L2 idle state latency and residency
Christian Lamparter chunkeey@gmail.com ARM: BCM53016: Specify switch ports for Meraki MR32
Hans de Goede hdegoede@redhat.com staging: rtl8723bs: remove a third possible deadlock
Hans de Goede hdegoede@redhat.com staging: rtl8723bs: remove a second possible deadlock
Fabio Aiuto fabioaiuto83@gmail.com staging: rtl8723bs: remove possible deadlock when disconnect (v2)
Linus Walleij linus.walleij@linaro.org ARM: dts: ux500: Skomer regulator fixes
Sven Peter sven@svenpeter.dev usb: typec: tipd: Remove WARN_ON in tps6598x_block_read
Yang Yingliang yangyingliang@huawei.com usb: musb: tusb6010: check return value after calling platform_get_resource()
Tony Lindgren tony@atomide.com bus: ti-sysc: Use context lost quirk for otg
Tony Lindgren tony@atomide.com bus: ti-sysc: Add quirk handling for reinit on context lost
Selvin Xavier selvin.xavier@broadcom.com RDMA/bnxt_re: Check if the vlan is valid before reporting
Michael Walle michael@walle.cc arm64: dts: hisilicon: fix arm,sp805 compatible string
Matthias Brugger mbrugger@suse.com arm64: dts: rockchip: Disable CDN DP on Pinebook Pro
Bixuan Cui cuibixuan@huawei.com ASoC: mediatek: mt8195: Add missing of_node_put()
James Smart jsmart2021@gmail.com scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq()
Ajish Koshy Ajish.Koshy@microchip.com scsi: pm80xx: Fix memory leak during rmmod
Rafał Miłecki rafal@milecki.pl arm64: dts: broadcom: bcm4908: Move reboot syscon out of bus
Matthew Hagan mnhagan88@gmail.com ARM: dts: NSP: Fix mpcore, mmc node names
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: Fix MDIO mux binding
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: Fix nodes names
Jérôme Pouiller jerome.pouiller@silabs.com staging: wfx: ensure IRQ is ready before enabling it
Maxime Ripard maxime@cerno.tech arm64: dts: allwinner: a100: Fix thermal zone node name
Maxime Ripard maxime@cerno.tech arm64: dts: allwinner: h5: Fix GPU thermal zone node name
Maxime Ripard maxime@cerno.tech ARM: dts: sunxi: Fix OPPs node name
Samuel Holland samuel@sholland.org clk: sunxi-ng: Unregister clocks/resets when unbinding
Michal Simek michal.simek@xilinx.com arm64: zynqmp: Fix serial compatible string
Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com arm64: zynqmp: Do not duplicate flash partition label property
-------------
Diffstat:
Makefile | 4 +- arch/arc/kernel/process.c | 2 +- arch/arm/Kconfig | 1 + arch/arm/boot/dts/bcm-nsp.dtsi | 4 +- arch/arm/boot/dts/bcm47094-linksys-panamera.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 22 +++ arch/arm/boot/dts/bcm5301x.dtsi | 10 +- arch/arm/boot/dts/ls1021a-tsn.dts | 2 +- arch/arm/boot/dts/ls1021a.dtsi | 66 +++---- arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi | 2 +- arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi | 2 +- arch/arm/boot/dts/qcom-ipq8064-rb3011.dts | 6 +- arch/arm/boot/dts/ste-ux500-samsung-skomer.dts | 8 +- arch/arm/boot/dts/sun8i-a33.dtsi | 4 +- arch/arm/boot/dts/sun8i-a83t.dtsi | 4 +- arch/arm/boot/dts/sun8i-h3.dtsi | 4 +- arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 6 +- .../boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi | 2 +- .../boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi | 2 +- arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 2 +- .../boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi | 2 +- arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi | 12 +- arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 1 + arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 16 +- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 16 +- .../boot/dts/freescale/imx8mm-kontron-n801x-s.dts | 4 +- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 +- arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 2 +- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8916.dtsi | 4 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8998.dtsi | 22 ++- arch/arm64/boot/dts/qcom/qcs404.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm6125.dtsi | 2 +- .../boot/dts/rockchip/rk3399-pinebook-pro.dts | 4 - .../boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts | 4 +- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 +- arch/arm64/kvm/hyp/nvhe/setup.c | 14 +- arch/hexagon/include/asm/timer-regs.h | 26 --- arch/hexagon/include/asm/timex.h | 3 +- arch/hexagon/kernel/time.c | 12 +- arch/hexagon/lib/io.c | 4 + arch/m68k/kernel/traps.c | 2 +- arch/mips/Kconfig | 3 + arch/mips/bcm63xx/clk.c | 6 + arch/mips/boot/compressed/Makefile | 6 + arch/mips/generic/yamon-dt.c | 2 +- arch/mips/lantiq/clk.c | 6 + arch/mips/sni/time.c | 4 +- arch/parisc/include/asm/rt_sigframe.h | 2 +- arch/parisc/kernel/signal.c | 13 +- arch/parisc/kernel/signal32.h | 2 +- arch/powerpc/boot/dts/charon.dts | 2 +- arch/powerpc/boot/dts/digsy_mtc.dts | 2 +- arch/powerpc/boot/dts/lite5200.dts | 2 +- arch/powerpc/boot/dts/lite5200b.dts | 2 +- arch/powerpc/boot/dts/media5200.dts | 2 +- arch/powerpc/boot/dts/mpc5200b.dtsi | 2 +- arch/powerpc/boot/dts/o2d.dts | 2 +- arch/powerpc/boot/dts/o2d.dtsi | 2 +- arch/powerpc/boot/dts/o2dnt2.dts | 2 +- arch/powerpc/boot/dts/o3dnt.dts | 2 +- arch/powerpc/boot/dts/pcm032.dts | 2 +- arch/powerpc/boot/dts/tqm5200.dts | 2 +- arch/powerpc/kernel/Makefile | 3 + arch/powerpc/kernel/head_8xx.S | 13 +- arch/powerpc/kernel/signal.h | 10 +- arch/powerpc/kernel/signal_32.c | 6 +- arch/powerpc/kernel/signal_64.c | 9 +- arch/powerpc/kernel/watchdog.c | 6 + arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 +- arch/powerpc/mm/numa.c | 44 +++-- arch/powerpc/sysdev/dcr-low.S | 2 +- arch/powerpc/sysdev/xive/Kconfig | 1 - arch/powerpc/sysdev/xive/common.c | 3 +- arch/riscv/Makefile | 2 + arch/s390/Kconfig | 2 +- arch/s390/Makefile | 10 +- arch/s390/boot/startup.c | 88 ++++------ arch/s390/include/asm/kexec.h | 6 + arch/s390/kernel/crash_dump.c | 4 +- arch/s390/kernel/ipl.c | 3 +- arch/s390/kernel/machine_kexec_file.c | 18 +- arch/s390/kernel/setup.c | 10 +- arch/s390/kernel/traps.c | 2 +- arch/s390/kernel/vdso64/Makefile | 5 +- arch/sh/Kconfig.debug | 1 + arch/sh/include/asm/sfp-machine.h | 8 + arch/sh/kernel/cpu/sh4a/smp-shx3.c | 5 +- arch/sh/math-emu/math.c | 103 ----------- arch/sparc/kernel/signal_32.c | 4 +- arch/sparc/kernel/windows.c | 6 +- arch/um/kernel/trap.c | 2 +- arch/x86/Kconfig | 3 +- arch/x86/entry/vsyscall/vsyscall_64.c | 3 +- arch/x86/events/intel/core.c | 4 +- arch/x86/events/intel/uncore_snbep.c | 12 ++ arch/x86/hyperv/hv_init.c | 3 + arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kernel/cpu/sgx/main.c | 12 +- arch/x86/kernel/setup.c | 66 ++++--- arch/x86/kernel/vm86_32.c | 4 +- arch/x86/kvm/hyperv.c | 4 +- arch/x86/kvm/mmu/mmu.c | 1 + arch/x86/kvm/svm/sev.c | 7 +- arch/x86/kvm/vmx/nested.c | 22 ++- arch/x86/kvm/x86.c | 10 +- arch/x86/kvm/x86.h | 12 ++ arch/x86/kvm/xen.c | 4 +- block/blk-cgroup.c | 9 +- block/blk-core.c | 4 +- block/ioprio.c | 9 +- drivers/ata/libata-core.c | 11 +- drivers/base/firmware_loader/main.c | 13 +- drivers/bus/ti-sysc.c | 110 +++++++++++- drivers/clk/at91/sama7g5.c | 11 +- drivers/clk/clk-ast2600.c | 12 +- drivers/clk/imx/clk-imx6ul.c | 2 +- drivers/clk/ingenic/cgu.c | 6 +- drivers/clk/qcom/gcc-msm8996.c | 15 -- drivers/clk/sunxi-ng/ccu-sun4i-a10.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-a100.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 4 +- drivers/clk/sunxi-ng/ccu-sun5i.c | 2 +- drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-r.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 2 +- drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c | 3 +- drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c | 3 +- drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 2 +- drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c | 2 +- drivers/clk/sunxi-ng/ccu_common.c | 89 ++++++++-- drivers/clk/sunxi-ng/ccu_common.h | 6 +- drivers/cpuidle/cpuidle-tegra.c | 3 + drivers/dma/xilinx/xilinx_dpdma.c | 15 +- drivers/gpio/Kconfig | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 + .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 35 ++++ .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 +- .../drm/amd/display/dc/dml/display_mode_enums.h | 4 +- drivers/gpu/drm/amd/include/amd_shared.h | 3 +- drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 10 ++ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 8 + drivers/gpu/drm/drm_gem_cma_helper.c | 9 +- drivers/gpu/drm/drm_prime.c | 6 +- drivers/gpu/drm/i915/display/icl_dsi.c | 10 +- drivers/gpu/drm/i915/display/intel_bios.c | 85 ++++++--- drivers/gpu/drm/i915/display/intel_dp.c | 29 +++- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 154 ++++++++++------- drivers/gpu/drm/nouveau/nouveau_drm.c | 42 ++++- drivers/gpu/drm/nouveau/nouveau_drv.h | 5 + .../gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c | 1 - drivers/gpu/drm/udl/udl_connector.c | 2 +- drivers/hid/hid-ids.h | 3 + drivers/hid/hid-multitouch.c | 13 ++ drivers/hv/hv_balloon.c | 2 +- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 6 +- drivers/infiniband/core/sysfs.c | 4 +- drivers/infiniband/core/verbs.c | 3 + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 +- drivers/infiniband/hw/mlx4/main.c | 18 +- drivers/infiniband/sw/rxe/rxe_loc.h | 1 + drivers/infiniband/sw/rxe/rxe_mr.c | 69 ++++++-- drivers/infiniband/sw/rxe/rxe_mw.c | 30 ++-- drivers/infiniband/sw/rxe/rxe_req.c | 14 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 18 +- drivers/iommu/apple-dart.c | 5 + drivers/iommu/intel/iommu.c | 6 +- drivers/memory/tegra/tegra20-emc.c | 1 + .../net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | 4 +- drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 2 +- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 +- drivers/net/ethernet/intel/e100.c | 18 +- drivers/net/ethernet/intel/i40e/i40e.h | 2 + drivers/net/ethernet/intel/i40e/i40e_main.c | 160 +++++++++++------ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 121 +++++-------- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 30 +++- drivers/net/ethernet/intel/iavf/iavf_main.c | 55 ++++-- drivers/net/ethernet/intel/ice/ice.h | 5 +- drivers/net/ethernet/intel/ice/ice_main.c | 3 - drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 78 ++++----- drivers/net/ethernet/marvell/mvmdio.c | 2 + drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/cq.c | 5 +- drivers/net/ethernet/mellanox/mlx5/core/debugfs.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c | 26 ++- drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h | 2 + .../net/ethernet/mellanox/mlx5/core/en/tc_priv.h | 1 + .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 8 +- .../ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c | 23 ++- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 10 +- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 21 ++- .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 9 +- drivers/net/ethernet/mellanox/mlx5/core/lag.c | 28 ++- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 24 ++- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 23 ++- drivers/net/ipa/ipa_endpoint.c | 5 + drivers/net/ipa/ipa_resource.c | 2 +- drivers/net/tun.c | 5 + drivers/pinctrl/qcom/pinctrl-sdm845.c | 1 + drivers/pinctrl/qcom/pinctrl-sm8350.c | 8 +- drivers/pinctrl/ralink/pinctrl-mt7620.c | 1 + drivers/platform/x86/hp_accel.c | 2 + drivers/platform/x86/think-lmi.c | 13 +- drivers/platform/x86/think-lmi.h | 1 - drivers/ptp/ptp_ocp.c | 9 +- drivers/scsi/advansys.c | 4 +- drivers/scsi/lpfc/lpfc_crtn.h | 2 + drivers/scsi/lpfc/lpfc_disc.h | 12 +- drivers/scsi/lpfc/lpfc_els.c | 7 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 112 +++++++++++- drivers/scsi/lpfc/lpfc_init.c | 12 +- drivers/scsi/lpfc/lpfc_scsi.c | 10 +- drivers/scsi/lpfc/lpfc_sli.c | 15 +- drivers/scsi/pm8001/pm8001_init.c | 11 ++ drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/qla2xxx/qla_mbx.c | 6 +- drivers/scsi/scsi_debug.c | 11 +- drivers/scsi/scsi_lib.c | 25 +-- drivers/scsi/scsi_sysfs.c | 30 ++-- drivers/scsi/smartpqi/smartpqi_init.c | 41 ++++- drivers/scsi/smartpqi/smartpqi_sis.c | 51 ++++++ drivers/scsi/smartpqi/smartpqi_sis.h | 1 + drivers/scsi/ufs/ufshcd.c | 9 +- drivers/sh/maple/maple.c | 5 +- drivers/spi/spi.c | 12 +- drivers/staging/rtl8723bs/core/rtw_mlme.c | 12 +- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 11 +- drivers/staging/rtl8723bs/core/rtw_recv.c | 10 +- drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 33 ++-- drivers/staging/rtl8723bs/core/rtw_xmit.c | 16 +- drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c | 2 - drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 - drivers/staging/wfx/bus_sdio.c | 17 +- drivers/target/target_core_alua.c | 1 - drivers/target/target_core_device.c | 2 + drivers/target/target_core_internal.h | 1 + drivers/target/target_core_transport.c | 76 ++++++--- drivers/tty/tty_buffer.c | 3 + drivers/usb/host/max3421-hcd.c | 25 +-- drivers/usb/host/ohci-tmio.c | 2 +- drivers/usb/musb/tusb6010.c | 5 + drivers/usb/typec/tipd/core.c | 2 +- drivers/video/console/sticon.c | 12 +- drivers/video/fbdev/efifb.c | 11 ++ drivers/video/fbdev/simplefb.c | 11 ++ fs/attr.c | 4 +- fs/btrfs/async-thread.c | 14 ++ fs/btrfs/scrub.c | 4 +- fs/btrfs/volumes.c | 21 ++- fs/exec.c | 2 +- fs/f2fs/f2fs.h | 3 +- fs/f2fs/segment.c | 2 +- fs/f2fs/super.c | 4 +- fs/inode.c | 7 +- fs/nfsd/nfs4xdr.c | 7 +- fs/pstore/Kconfig | 1 - fs/pstore/blk.c | 2 +- fs/udf/dir.c | 32 +++- fs/udf/namei.c | 3 + fs/udf/super.c | 2 + include/linux/bpf.h | 3 +- include/linux/dmaengine.h | 2 - include/linux/fs.h | 2 + include/linux/ipc_namespace.h | 15 ++ include/linux/mlx5/eswitch.h | 4 +- include/linux/platform_data/ti-sysc.h | 1 + include/linux/printk.h | 4 + include/linux/sched/signal.h | 2 + include/linux/sched/task.h | 2 +- include/linux/skbuff.h | 16 ++ include/linux/trace_events.h | 2 +- include/linux/virtio_net.h | 7 +- include/net/nfc/nci_core.h | 1 + include/rdma/rdma_netlink.h | 2 +- include/target/target_core_base.h | 6 +- include/trace/events/f2fs.h | 12 +- ipc/shm.c | 189 ++++++++++++++++----- ipc/util.c | 6 +- kernel/bpf/cgroup.c | 2 + kernel/bpf/helpers.c | 2 - kernel/bpf/syscall.c | 57 ++++--- kernel/bpf/verifier.c | 27 ++- kernel/entry/syscall_user_dispatch.c | 12 +- kernel/printk/printk.c | 5 + kernel/sched/autogroup.c | 2 +- kernel/sched/core.c | 47 ++++- kernel/sched/fair.c | 4 +- kernel/sched/rt.c | 12 +- kernel/sched/sched.h | 3 +- kernel/signal.c | 60 +++++-- kernel/trace/bpf_trace.c | 2 - kernel/trace/trace_events_hist.c | 14 +- lib/nmi_backtrace.c | 6 + mm/Kconfig | 3 + mm/damon/dbgfs.c | 15 +- mm/highmem.c | 32 ++-- mm/hugetlb.c | 30 +++- mm/slab.h | 2 +- net/core/filter.c | 6 + net/core/skbuff.c | 14 +- net/core/sock.c | 6 +- net/ipv4/bpf_tcp_ca.c | 2 + net/ipv4/tcp.c | 3 + net/ipv4/tcp_output.c | 6 +- net/ipv4/udp.c | 11 ++ net/mac80211/cfg.c | 12 +- net/mac80211/iface.c | 4 +- net/mac80211/rx.c | 2 +- net/mac80211/util.c | 7 +- net/mac80211/wme.c | 3 +- net/nfc/core.c | 32 ++-- net/nfc/nci/core.c | 30 +++- net/sched/act_mirred.c | 11 +- net/smc/smc_core.c | 3 +- net/tipc/crypto.c | 4 + net/tipc/link.c | 7 +- net/wireless/nl80211.c | 34 ++-- net/wireless/nl80211.h | 6 +- net/wireless/util.c | 1 + samples/bpf/xdp_redirect_cpu_user.c | 5 +- samples/bpf/xdp_sample_user.c | 28 +-- security/selinux/ss/hashtab.c | 17 +- sound/core/Makefile | 2 + sound/hda/intel-dsp-config.c | 22 ++- sound/isa/Kconfig | 2 +- sound/isa/gus/gus_dma.c | 2 + sound/pci/Kconfig | 1 + sound/soc/codecs/es8316.c | 7 +- sound/soc/codecs/nau8824.c | 40 +++++ sound/soc/codecs/rt5651.c | 7 +- sound/soc/codecs/rt5682.c | 56 +++++- sound/soc/codecs/rt5682.h | 20 +++ sound/soc/intel/boards/sof_sdw.c | 10 ++ sound/soc/intel/common/soc-acpi-intel-tgl-match.c | 41 +++++ .../mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c | 6 +- sound/soc/sh/rcar/dma.c | 2 +- sound/soc/soc-dapm.c | 29 +++- sound/soc/sof/intel/hda-dai.c | 7 +- sound/usb/clock.c | 4 + sound/usb/implicit.c | 2 - sound/usb/mixer_quirks.c | 34 ++++ sound/usb/quirks-table.h | 58 +++++++ tools/build/feature/test-all.c | 1 - tools/perf/bench/futex-lock-pi.c | 1 + tools/perf/bench/futex-requeue.c | 1 + tools/perf/bench/futex-wake-parallel.c | 1 + tools/perf/bench/futex-wake.c | 1 + tools/perf/bench/sched-messaging.c | 4 + tools/perf/tests/shell/record+zstd_comp_decomp.sh | 2 +- tools/perf/util/bpf-event.c | 6 +- tools/perf/util/env.c | 5 +- tools/perf/util/env.h | 2 +- tools/testing/selftests/gpio/Makefile | 1 + tools/testing/selftests/net/gre_gso.sh | 16 +- 371 files changed, 3095 insertions(+), 1545 deletions(-)
From: Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com
[ Upstream commit 167721a5909f867f8c18c8e78ea58e705ad9bbd4 ]
In kernel 5.4, support has been added for reading MTD devices via the nvmem API. For this the mtd devices are registered as read-only NVMEM providers under sysfs with the same name as the flash partition label property.
So if flash partition label property of multiple flash devices are identical then the second mtd device fails to get registered as a NVMEM provider.
This patch fixes the issue by having different label property for different flashes.
Signed-off-by: Amit Kumar Mahapatra amit.kumar-mahapatra@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com Link: https://lore.kernel.org/r/6c4b9b9232b93d9e316a63c086540fd5bf6b8687.162368425... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts index 4a86efa32d687..f7124e15f0ff6 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts @@ -131,7 +131,7 @@ reg = <0>;
partition@0 { - label = "data"; + label = "spi0-data"; reg = <0x0 0x100000>; }; }; @@ -149,7 +149,7 @@ reg = <0>;
partition@0 { - label = "data"; + label = "spi1-data"; reg = <0x0 0x84000>; }; };
From: Michal Simek michal.simek@xilinx.com
[ Upstream commit 812fa2f0e9d33564bd0131a69750e0d165f4c82a ]
Based on commit 65a2c14d4f00 ("dt-bindings: serial: convert Cadence UART bindings to YAML") compatible string should look like differently that's why fix it to be aligned with dt binding.
Signed-off-by: Michal Simek michal.simek@xilinx.com Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Link: https://lore.kernel.org/r/89b36e0a6187cc6b05b27a035efdf79173bd4486.162824030... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 28dccb891a535..8278876ad33fa 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -792,7 +792,7 @@ };
uart0: serial@ff000000 { - compatible = "cdns,uart-r1p12", "xlnx,xuartps"; + compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 21 4>; @@ -802,7 +802,7 @@ };
uart1: serial@ff010000 { - compatible = "cdns,uart-r1p12", "xlnx,xuartps"; + compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 22 4>;
From: Samuel Holland samuel@sholland.org
[ Upstream commit 9bec2b9c6134052994115d2d3374e96f2ccb9b9d ]
Currently, unbinding a CCU driver unmaps the device's MMIO region, while leaving its clocks/resets and their providers registered. This can cause a page fault later when some clock operation tries to perform MMIO. Fix this by separating the CCU initialization from the memory allocation, and then using a devres callback to unregister the clocks and resets.
This also fixes a memory leak of the `struct ccu_reset`, and uses the correct owner (the specific platform driver) for the clocks and resets.
Early OF clock providers are never unregistered, and limited error handling is possible, so they are mostly unchanged. The error reporting is made more consistent by moving the message inside of_sunxi_ccu_probe.
Signed-off-by: Samuel Holland samuel@sholland.org Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://lore.kernel.org/r/20210901050526.45673-2-samuel@sholland.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/sunxi-ng/ccu-sun4i-a10.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-a100.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 2 +- drivers/clk/sunxi-ng/ccu-sun50i-h616.c | 4 +- drivers/clk/sunxi-ng/ccu-sun5i.c | 2 +- drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-r.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 2 +- drivers/clk/sunxi-ng/ccu-sun8i-v3s.c | 2 +- drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c | 3 +- drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c | 3 +- drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 2 +- drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c | 2 +- drivers/clk/sunxi-ng/ccu_common.c | 89 ++++++++++++++++++++---- drivers/clk/sunxi-ng/ccu_common.h | 6 +- 23 files changed, 100 insertions(+), 41 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c index f32366d9336e7..bd9a8782fec3d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c +++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c @@ -1464,7 +1464,7 @@ static void __init sun4i_ccu_init(struct device_node *node, val &= ~GENMASK(7, 6); writel(val | (2 << 6), reg + SUN4I_AHB_REG);
- sunxi_ccu_probe(node, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); }
static void __init sun4i_a10_ccu_setup(struct device_node *node) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c index a56142b909938..6f2a589705561 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100-r.c @@ -196,7 +196,7 @@ static int sun50i_a100_r_ccu_probe(struct platform_device *pdev) if (IS_ERR(reg)) return PTR_ERR(reg);
- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc); + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_r_ccu_desc); }
static const struct of_device_id sun50i_a100_r_ccu_ids[] = { diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c index 81b48c73d389f..913bb08e6dee8 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a100.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a100.c @@ -1247,7 +1247,7 @@ static int sun50i_a100_ccu_probe(struct platform_device *pdev) writel(val, reg + sun50i_a100_usb2_clk_regs[i]); }
- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_ccu_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_ccu_desc); if (ret) return ret;
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 149cfde817cba..54f25c624f020 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -955,7 +955,7 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc); if (ret) return ret;
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c index f8909a7ed5539..f30d7eb5424d8 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c @@ -232,7 +232,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, return; }
- sunxi_ccu_probe(node, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); }
static void __init sun50i_h6_r_ccu_setup(struct device_node *node) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index bff446b782907..c0800da2fa3d7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -1240,7 +1240,7 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev) val |= BIT(24); writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc); }
static const struct of_device_id sun50i_h6_ccu_ids[] = { diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c index 225307305880e..22eb18079a154 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h616.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h616.c @@ -1141,9 +1141,7 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node) val |= BIT(24); writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
- i = sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); - if (i) - pr_err("%pOF: probing clocks fails: %d\n", node, i); + of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc); }
CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu", diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c index b78e9b507c1c6..1f4bc0e773a7e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun5i.c +++ b/drivers/clk/sunxi-ng/ccu-sun5i.c @@ -1012,7 +1012,7 @@ static void __init sun5i_ccu_init(struct device_node *node, val &= ~GENMASK(7, 6); writel(val | (2 << 6), reg + SUN5I_AHB_REG);
- sunxi_ccu_probe(node, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); }
static void __init sun5i_a10s_ccu_setup(struct device_node *node) diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c index 9b40d53266a3f..3df5c0b415804 100644 --- a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c +++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c @@ -1257,7 +1257,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node) val |= 0x3 << 12; writel(val, reg + SUN6I_A31_AHB1_REG);
- sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc); + of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, &sun6i_a31_cpu_nb); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c index 103aa504f6c8a..577bb235d6584 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c @@ -745,7 +745,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node) val &= ~BIT(16); writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
- sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); + of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc); } CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu", sun8i_a23_ccu_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c index 91838cd110377..8f65cd03f5acc 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c @@ -805,7 +805,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node) val &= ~BIT(16); writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
- sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc); + of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
/* Gate then ungate PLL CPU after any rate changes */ ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c index 2b434521c5ccf..c2ddcd2ddab4e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c @@ -906,7 +906,7 @@ static int sun8i_a83t_ccu_probe(struct platform_device *pdev) sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG); sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG);
- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc); + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a83t_ccu_desc); }
static const struct of_device_id sun8i_a83t_ccu_ids[] = { diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index 524f33275bc73..4b94b6041b271 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -342,7 +342,7 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev) goto err_disable_mod_clk; }
- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc); if (ret) goto err_assert_reset;
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 7e629a4493afd..d2fc2903787d8 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -1154,7 +1154,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node, val &= ~GENMASK(19, 16); writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
- sunxi_ccu_probe(node, reg, desc); + of_sunxi_ccu_probe(node, reg, desc);
/* Gate then ungate PLL CPU after any rate changes */ ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c index 4c8c491b87c27..9e754d1f754a1 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c @@ -265,7 +265,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node, return; }
- sunxi_ccu_probe(node, reg, desc); + of_sunxi_ccu_probe(node, reg, desc); }
static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index 84153418453f4..002e0c3a04dbe 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c @@ -1346,7 +1346,7 @@ static int sun8i_r40_ccu_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap);
- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_r40_ccu_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_r40_ccu_desc); if (ret) return ret;
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index f49724a22540e..ce150f83ab54e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -822,7 +822,7 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node, val &= ~GENMASK(19, 16); writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
- sunxi_ccu_probe(node, reg, ccu_desc); + of_sunxi_ccu_probe(node, reg, ccu_desc); }
static void __init sun8i_v3s_ccu_setup(struct device_node *node) diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c index 6616e8114f623..261e64416f26a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-de.c @@ -246,8 +246,7 @@ static int sun9i_a80_de_clk_probe(struct platform_device *pdev) goto err_disable_clk; }
- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, - &sun9i_a80_de_clk_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_de_clk_desc); if (ret) goto err_assert_reset;
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c index 4b4a507d04edf..596243b3e0fa3 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c @@ -117,8 +117,7 @@ static int sun9i_a80_usb_clk_probe(struct platform_device *pdev) return ret; }
- ret = sunxi_ccu_probe(pdev->dev.of_node, reg, - &sun9i_a80_usb_clk_desc); + ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_usb_clk_desc); if (ret) goto err_disable_clk;
diff --git a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c index ef29582676f6e..97aaed0e68500 100644 --- a/drivers/clk/sunxi-ng/ccu-sun9i-a80.c +++ b/drivers/clk/sunxi-ng/ccu-sun9i-a80.c @@ -1231,7 +1231,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev) sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C0CPUX_REG); sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C1CPUX_REG);
- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc); + return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_ccu_desc); }
static const struct of_device_id sun9i_a80_ccu_ids[] = { diff --git a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c index 7ecc3a5a5b5e1..61ad7ee91c114 100644 --- a/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c +++ b/drivers/clk/sunxi-ng/ccu-suniv-f1c100s.c @@ -538,7 +538,7 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node) val &= ~GENMASK(19, 16); writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
- sunxi_ccu_probe(node, reg, &suniv_ccu_desc); + of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
/* Gate then ungate PLL CPU after any rate changes */ ccu_pll_notifier_register(&suniv_pll_cpu_nb); diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 2e20e650b6c01..88cb569e58358 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -7,6 +7,7 @@
#include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/device.h> #include <linux/iopoll.h> #include <linux/slab.h>
@@ -14,6 +15,11 @@ #include "ccu_gate.h" #include "ccu_reset.h"
+struct sunxi_ccu { + const struct sunxi_ccu_desc *desc; + struct ccu_reset reset; +}; + static DEFINE_SPINLOCK(ccu_lock);
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock) @@ -79,12 +85,15 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb) &pll_nb->clk_nb); }
-int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, - const struct sunxi_ccu_desc *desc) +static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, + struct device_node *node, void __iomem *reg, + const struct sunxi_ccu_desc *desc) { struct ccu_reset *reset; int i, ret;
+ ccu->desc = desc; + for (i = 0; i < desc->num_ccu_clks; i++) { struct ccu_common *cclk = desc->ccu_clks[i];
@@ -103,7 +112,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, continue;
name = hw->init->name; - ret = of_clk_hw_register(node, hw); + if (dev) + ret = clk_hw_register(dev, hw); + else + ret = of_clk_hw_register(node, hw); if (ret) { pr_err("Couldn't register clock %d - %s\n", i, name); goto err_clk_unreg; @@ -115,15 +127,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, if (ret) goto err_clk_unreg;
- reset = kzalloc(sizeof(*reset), GFP_KERNEL); - if (!reset) { - ret = -ENOMEM; - goto err_alloc_reset; - } - + reset = &ccu->reset; reset->rcdev.of_node = node; reset->rcdev.ops = &ccu_reset_ops; - reset->rcdev.owner = THIS_MODULE; + reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE; reset->rcdev.nr_resets = desc->num_resets; reset->base = reg; reset->lock = &ccu_lock; @@ -131,13 +138,11 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
ret = reset_controller_register(&reset->rcdev); if (ret) - goto err_of_clk_unreg; + goto err_del_provider;
return 0;
-err_of_clk_unreg: - kfree(reset); -err_alloc_reset: +err_del_provider: of_clk_del_provider(node); err_clk_unreg: while (--i >= 0) { @@ -149,3 +154,59 @@ err_clk_unreg: } return ret; } + +static void devm_sunxi_ccu_release(struct device *dev, void *res) +{ + struct sunxi_ccu *ccu = res; + const struct sunxi_ccu_desc *desc = ccu->desc; + int i; + + reset_controller_unregister(&ccu->reset.rcdev); + of_clk_del_provider(dev->of_node); + + for (i = 0; i < desc->hw_clks->num; i++) { + struct clk_hw *hw = desc->hw_clks->hws[i]; + + if (!hw) + continue; + clk_hw_unregister(hw); + } +} + +int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, + const struct sunxi_ccu_desc *desc) +{ + struct sunxi_ccu *ccu; + int ret; + + ccu = devres_alloc(devm_sunxi_ccu_release, sizeof(*ccu), GFP_KERNEL); + if (!ccu) + return -ENOMEM; + + ret = sunxi_ccu_probe(ccu, dev, dev->of_node, reg, desc); + if (ret) { + devres_free(ccu); + return ret; + } + + devres_add(dev, ccu); + + return 0; +} + +void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, + const struct sunxi_ccu_desc *desc) +{ + struct sunxi_ccu *ccu; + int ret; + + ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); + if (!ccu) + return; + + ret = sunxi_ccu_probe(ccu, NULL, node, reg, desc); + if (ret) { + pr_err("%pOF: probing clocks failed: %d\n", node, ret); + kfree(ccu); + } +} diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h index 04e7a12200a21..98a1834b58bb4 100644 --- a/drivers/clk/sunxi-ng/ccu_common.h +++ b/drivers/clk/sunxi-ng/ccu_common.h @@ -63,7 +63,9 @@ struct ccu_pll_nb {
int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb);
-int sunxi_ccu_probe(struct device_node *node, void __iomem *reg, - const struct sunxi_ccu_desc *desc); +int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg, + const struct sunxi_ccu_desc *desc); +void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, + const struct sunxi_ccu_desc *desc);
#endif /* _COMMON_H_ */
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit ffbe853a3f5a37fa0a511265b21abf097ffdbe45 ]
The operating-points-v2 nodes are named inconsistently, but mostly either opp_table0 or gpu-opp-table. However, the underscore is an invalid character for a node name and the thermal zone binding explicitly requires that zones are called opp-table-*. Let's fix it.
Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Jernej Skrabec jernej.skrabec@gmail.com Link: https://lore.kernel.org/r/20210901091852.479202-43-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/sun8i-a33.dtsi | 4 ++-- arch/arm/boot/dts/sun8i-a83t.dtsi | 4 ++-- arch/arm/boot/dts/sun8i-h3.dtsi | 4 ++-- arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi | 2 +- arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi | 2 +- arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index 2beddbb3c5183..b3d1bdfb5118e 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -46,7 +46,7 @@ #include <dt-bindings/thermal/thermal.h>
/ { - cpu0_opp_table: opp_table0 { + cpu0_opp_table: opp-table-cpu { compatible = "operating-points-v2"; opp-shared;
@@ -164,7 +164,7 @@ io-channels = <&ths>; };
- mali_opp_table: gpu-opp-table { + mali_opp_table: opp-table-gpu { compatible = "operating-points-v2";
opp-144000000 { diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi index ac97eac91349b..82fdb04122caa 100644 --- a/arch/arm/boot/dts/sun8i-a83t.dtsi +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -200,7 +200,7 @@ status = "disabled"; };
- cpu0_opp_table: opp_table0 { + cpu0_opp_table: opp-table-cluster0 { compatible = "operating-points-v2"; opp-shared;
@@ -253,7 +253,7 @@ }; };
- cpu1_opp_table: opp_table1 { + cpu1_opp_table: opp-table-cluster1 { compatible = "operating-points-v2"; opp-shared;
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi index 4e89701df91f8..ae4f933abb895 100644 --- a/arch/arm/boot/dts/sun8i-h3.dtsi +++ b/arch/arm/boot/dts/sun8i-h3.dtsi @@ -44,7 +44,7 @@ #include <dt-bindings/thermal/thermal.h>
/ { - cpu0_opp_table: opp_table0 { + cpu0_opp_table: opp-table-cpu { compatible = "operating-points-v2"; opp-shared;
@@ -112,7 +112,7 @@ }; };
- gpu_opp_table: gpu-opp-table { + gpu_opp_table: opp-table-gpu { compatible = "operating-points-v2";
opp-120000000 { diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi index 578c37490d901..e39db51eb4489 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi @@ -4,7 +4,7 @@ */
/ { - cpu0_opp_table: opp_table0 { + cpu0_opp_table: opp-table-cpu { compatible = "operating-points-v2"; opp-shared;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi index b2657201957eb..1afad8b437d72 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-cpu-opp.dtsi @@ -2,7 +2,7 @@ // Copyright (C) 2020 Chen-Yu Tsai wens@csie.org
/ { - cpu_opp_table: cpu-opp-table { + cpu_opp_table: opp-table-cpu { compatible = "operating-points-v2"; opp-shared;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi index 8c6e8536b69fa..0baf0f8e4d272 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi @@ -3,7 +3,7 @@ // Copyright (C) 2020 Clément Péron peron.clem@gmail.com
/ { - cpu_opp_table: cpu-opp-table { + cpu_opp_table: opp-table-cpu { compatible = "allwinner,sun50i-h6-operating-points"; nvmem-cells = <&cpu_speed_grade>; opp-shared;
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 94a0f2b0e4e0953d8adf319c44244ef7a57de32c ]
The GPU thermal zone is named gpu_thermal. However, the underscore is an invalid character for a node name and the thermal zone binding explicitly requires that zones are called *-thermal. Let's fix it.
Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Jernej Skrabec jernej.skrabec@gmail.com Link: https://lore.kernel.org/r/20210901091852.479202-48-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi index 578a63dedf466..9988e87ea7b3d 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -217,7 +217,7 @@ }; };
- gpu_thermal { + gpu-thermal { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 1>;
From: Maxime Ripard maxime@cerno.tech
[ Upstream commit 5c34c4e46e601554bfa370b23c8ae3c3c734e9f7 ]
The thermal zones one the A100 are called $device-thermal-zone.
However, the thermal zone binding explicitly requires that zones are called *-thermal. Let's fix it.
Signed-off-by: Maxime Ripard maxime@cerno.tech Acked-by: Jernej Skrabec jernej.skrabec@gmail.com Link: https://lore.kernel.org/r/20210901091852.479202-50-maxime@cerno.tech Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi index cc321c04f1219..f6d7d7f7fdabe 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a100.dtsi @@ -343,19 +343,19 @@ };
thermal-zones { - cpu-thermal-zone { + cpu-thermal { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 0>; };
- ddr-thermal-zone { + ddr-thermal { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 2>; };
- gpu-thermal-zone { + gpu-thermal { polling-delay-passive = <0>; polling-delay = <0>; thermal-sensors = <&ths 1>;
From: Jérôme Pouiller jerome.pouiller@silabs.com
[ Upstream commit 5e57c668dc097c6c27c973504706edec53f79281 ]
Since commit 5561770f80b1 ("staging: wfx: repair external IRQ for SDIO"), wfx_sdio_irq_subscribe() enforce the device to use IRQs. However, there is currently a race in this code. An IRQ may happen before the IRQ has been registered.
The problem has observed during debug session when the device crashes before the IRQ set up:
[ 1.546] wfx-sdio mmc0:0001:1: started firmware 3.12.2 "WF200_ASIC_WFM_(Jenkins)_FW3.12.2" (API: 3.7, keyset: C0, caps: 0x00000002) [ 2.559] wfx-sdio mmc0:0001:1: time out while polling control register [ 3.565] wfx-sdio mmc0:0001:1: chip is abnormally long to answer [ 6.563] wfx-sdio mmc0:0001:1: chip did not answer [ 6.568] wfx-sdio mmc0:0001:1: hardware request CONFIGURATION (0x09) on vif 2 returned error -110 [ 6.577] wfx-sdio mmc0:0001:1: PDS bytes 0 to 12: chip didn't reply (corrupted file?) [ 6.585] Unable to handle kernel NULL pointer dereference at virtual address 00000000 [ 6.592] pgd = c0004000 [ 6.595] [00000000] *pgd=00000000 [ 6.598] Internal error: Oops - BUG: 17 [#1] THUMB2 [ 6.603] Modules linked in: [ 6.606] CPU: 0 PID: 23 Comm: kworker/u2:1 Not tainted 3.18.19 #78 [ 6.612] Workqueue: kmmcd mmc_rescan [ 6.616] task: c176d100 ti: c0e50000 task.ti: c0e50000 [ 6.621] PC is at wake_up_process+0xa/0x14 [ 6.625] LR is at sdio_irq+0x61/0x250 [ 6.629] pc : [<c001e8ae>] lr : [<c00ec5bd>] psr: 600001b3 [ 6.629] sp : c0e51bd8 ip : c0e51cc8 fp : 00000001 [ 6.640] r10: 00000003 r9 : 00000000 r8 : c0003c34 [ 6.644] r7 : c0e51bd8 r6 : c0003c30 r5 : 00000001 r4 : c0e78c00 [ 6.651] r3 : 00000000 r2 : 00000000 r1 : 00000003 r0 : 00000000 [ 6.657] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA Thumb Segment kernel [ 6.664] Control: 50c53c7d Table: 11fd8059 DAC: 00000015 [ 6.670] Process kworker/u2:1 (pid: 23, stack limit = 0xc0e501b0) [ 6.676] Stack: (0xc0e51bd8 to 0xc0e52000) [...] [ 6.949] [<c001e8ae>] (wake_up_process) from [<c00ec5bd>] (sdio_irq+0x61/0x250) [ 6.956] [<c00ec5bd>] (sdio_irq) from [<c0025099>] (handle_irq_event_percpu+0x17/0x92) [ 6.964] [<c0025099>] (handle_irq_event_percpu) from [<c002512f>] (handle_irq_event+0x1b/0x24) [ 6.973] [<c002512f>] (handle_irq_event) from [<c0026577>] (handle_level_irq+0x5d/0x76) [ 6.981] [<c0026577>] (handle_level_irq) from [<c0024cc3>] (generic_handle_irq+0x13/0x1c) [ 6.989] [<c0024cc3>] (generic_handle_irq) from [<c0024dd9>] (__handle_domain_irq+0x31/0x48) [ 6.997] [<c0024dd9>] (__handle_domain_irq) from [<c0008359>] (ov_handle_irq+0x31/0xe0) [ 7.005] [<c0008359>] (ov_handle_irq) from [<c000af5b>] (__irq_svc+0x3b/0x5c) [ 7.013] Exception stack(0xc0e51c68 to 0xc0e51cb0) [...] [ 7.038] [<c000af5b>] (__irq_svc) from [<c01775aa>] (wait_for_common+0x9e/0xc4) [ 7.045] [<c01775aa>] (wait_for_common) from [<c00e1dc3>] (mmc_wait_for_req+0x4b/0xdc) [ 7.053] [<c00e1dc3>] (mmc_wait_for_req) from [<c00e1e83>] (mmc_wait_for_cmd+0x2f/0x34) [ 7.061] [<c00e1e83>] (mmc_wait_for_cmd) from [<c00e7b2b>] (mmc_io_rw_direct_host+0x71/0xac) [ 7.070] [<c00e7b2b>] (mmc_io_rw_direct_host) from [<c00e8f79>] (sdio_claim_irq+0x6b/0x116) [ 7.078] [<c00e8f79>] (sdio_claim_irq) from [<c00d8415>] (wfx_sdio_irq_subscribe+0x19/0x94) [ 7.086] [<c00d8415>] (wfx_sdio_irq_subscribe) from [<c00d5229>] (wfx_probe+0x189/0x2ac) [ 7.095] [<c00d5229>] (wfx_probe) from [<c00d83bf>] (wfx_sdio_probe+0x8f/0xcc) [ 7.102] [<c00d83bf>] (wfx_sdio_probe) from [<c00e7fbb>] (sdio_bus_probe+0x5f/0xa8) [ 7.109] [<c00e7fbb>] (sdio_bus_probe) from [<c00be229>] (driver_probe_device+0x59/0x134) [ 7.118] [<c00be229>] (driver_probe_device) from [<c00bd4d7>] (bus_for_each_drv+0x3f/0x4a) [ 7.126] [<c00bd4d7>] (bus_for_each_drv) from [<c00be1a5>] (device_attach+0x3b/0x52) [ 7.134] [<c00be1a5>] (device_attach) from [<c00bdc2b>] (bus_probe_device+0x17/0x4c) [ 7.141] [<c00bdc2b>] (bus_probe_device) from [<c00bcd69>] (device_add+0x2c5/0x334) [ 7.149] [<c00bcd69>] (device_add) from [<c00e80bf>] (sdio_add_func+0x23/0x44) [ 7.156] [<c00e80bf>] (sdio_add_func) from [<c00e79eb>] (mmc_attach_sdio+0x187/0x1ec) [ 7.164] [<c00e79eb>] (mmc_attach_sdio) from [<c00e31bd>] (mmc_rescan+0x18d/0x1fc) [ 7.172] [<c00e31bd>] (mmc_rescan) from [<c001a14f>] (process_one_work+0xd7/0x170) [ 7.179] [<c001a14f>] (process_one_work) from [<c001a59b>] (worker_thread+0x103/0x1bc) [ 7.187] [<c001a59b>] (worker_thread) from [<c001c731>] (kthread+0x7d/0x90) [ 7.194] [<c001c731>] (kthread) from [<c0008ce1>] (ret_from_fork+0x11/0x30) [ 7.201] Code: 2103 b580 2200 af00 (681b) 46bd [ 7.206] ---[ end trace 3ab50aced42eedb4 ]---
Signed-off-by: Jérôme Pouiller jerome.pouiller@silabs.com Link: https://lore.kernel.org/r/20210913130203.1903622-33-Jerome.Pouiller@silabs.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/wfx/bus_sdio.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/staging/wfx/bus_sdio.c b/drivers/staging/wfx/bus_sdio.c index e06d7e1ebe9c3..61b8cc05f2935 100644 --- a/drivers/staging/wfx/bus_sdio.c +++ b/drivers/staging/wfx/bus_sdio.c @@ -120,19 +120,22 @@ static int wfx_sdio_irq_subscribe(void *priv) return ret; }
+ flags = irq_get_trigger_type(bus->of_irq); + if (!flags) + flags = IRQF_TRIGGER_HIGH; + flags |= IRQF_ONESHOT; + ret = devm_request_threaded_irq(&bus->func->dev, bus->of_irq, NULL, + wfx_sdio_irq_handler_ext, flags, + "wfx", bus); + if (ret) + return ret; sdio_claim_host(bus->func); cccr = sdio_f0_readb(bus->func, SDIO_CCCR_IENx, NULL); cccr |= BIT(0); cccr |= BIT(bus->func->num); sdio_f0_writeb(bus->func, cccr, SDIO_CCCR_IENx, NULL); sdio_release_host(bus->func); - flags = irq_get_trigger_type(bus->of_irq); - if (!flags) - flags = IRQF_TRIGGER_HIGH; - flags |= IRQF_ONESHOT; - return devm_request_threaded_irq(&bus->func->dev, bus->of_irq, NULL, - wfx_sdio_irq_handler_ext, flags, - "wfx", bus); + return 0; }
static int wfx_sdio_irq_unsubscribe(void *priv)
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit 9dba049b6d32e95c0dd2a0d607f593ea288ac140 ]
This fixes following errors for all BCM5301X dts files: chipcommonA@18000000: $nodename:0: 'chipcommonA@18000000' does not match '^([a-z][a-z0-9\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$' mpcore@19000000: $nodename:0: 'mpcore@19000000' does not match '^([a-z][a-z0-9\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$' mdio-bus-mux@18003000: $nodename:0: 'mdio-bus-mux@18003000' does not match '^mdio-mux[\-@]?' dmu@1800c000: $nodename:0: 'dmu@1800c000' does not match '^([a-z][a-z0-9\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
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/bcm47094-linksys-panamera.dts | 2 +- arch/arm/boot/dts/bcm5301x.dtsi | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts index 05d4f2931772b..9bef6b9bfa8d9 100644 --- a/arch/arm/boot/dts/bcm47094-linksys-panamera.dts +++ b/arch/arm/boot/dts/bcm47094-linksys-panamera.dts @@ -129,7 +129,7 @@ }; };
- mdio-bus-mux@18003000 { + mdio-mux@18003000 {
/* BIT(9) = 1 => external mdio */ mdio@200 { diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index f92089290ccd5..f9d3a53065ef7 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -19,7 +19,7 @@ #size-cells = <1>; interrupt-parent = <&gic>;
- chipcommonA@18000000 { + chipcommon-a-bus@18000000 { compatible = "simple-bus"; ranges = <0x00000000 0x18000000 0x00001000>; #address-cells = <1>; @@ -44,7 +44,7 @@ }; };
- mpcore@19000000 { + mpcore-bus@19000000 { compatible = "simple-bus"; ranges = <0x00000000 0x19000000 0x00023000>; #address-cells = <1>; @@ -369,7 +369,7 @@ #address-cells = <1>; };
- mdio-bus-mux@18003000 { + mdio-mux@18003000 { compatible = "mdio-mux-mmioreg"; mdio-parent-bus = <&mdio>; #address-cells = <1>; @@ -415,7 +415,7 @@ status = "disabled"; };
- dmu@1800c000 { + dmu-bus@1800c000 { compatible = "simple-bus"; ranges = <0 0x1800c000 0x1000>; #address-cells = <1>;
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit 6ee0b56f7530e0ebb496fe15d0b54c5f3a1b5e17 ]
This fixes following error for all BCM5301X dts files: mdio-bus-mux@18003000: compatible: ['mdio-mux-mmioreg'] is too short
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 f9d3a53065ef7..d4f355015e3ca 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -370,7 +370,7 @@ };
mdio-mux@18003000 { - compatible = "mdio-mux-mmioreg"; + compatible = "mdio-mux-mmioreg", "mdio-mux"; mdio-parent-bus = <&mdio>; #address-cells = <1>; #size-cells = <0>;
From: Matthew Hagan mnhagan88@gmail.com
[ Upstream commit 15a563d008ef9d04df525f0c476cd7d7127bb883 ]
Running dtbs_check yielded the issues with bcm-nsp.dtsi.
Firstly this patch fixes the following message by appending "-bus" to the mpcore node name: mpcore@19000000: $nodename:0: 'mpcore@19000000' does not match '^([a-z][a-z0-9\-]+-bus|bus|soc|axi|ahb|apb)(@[0-9a-f]+)?$'
Secondly mmc node name. The label name can remain as is. sdhci@21000: $nodename:0: 'sdhci@21000' does not match '^mmc(@.*)?$'
Signed-off-by: Matthew Hagan mnhagan88@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm-nsp.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index 748df7955ae67..e96ddb2e26e2c 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -77,7 +77,7 @@ interrupt-affinity = <&cpu0>, <&cpu1>; };
- mpcore@19000000 { + mpcore-bus@19000000 { compatible = "simple-bus"; ranges = <0x00000000 0x19000000 0x00023000>; #address-cells = <1>; @@ -219,7 +219,7 @@ status = "disabled"; };
- sdio: sdhci@21000 { + sdio: mmc@21000 { compatible = "brcm,sdhci-iproc-cygnus"; reg = <0x21000 0x100>; interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit 6cf9f70255b90b540b9cbde062f18fea29024a75 ]
This fixes following error for every bcm4908 DTS file: bus@ff800000: reboot: {'type': 'object'} is not allowed for {'compatible': ['syscon-reboot'], 'regmap': [[15]], 'offset': [[52]], 'mask': [[1]]}
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/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi index f6b93bbb49228..5118816b1ed76 100644 --- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi @@ -326,12 +326,12 @@ #reset-cells = <1>; }; }; + };
- reboot { - compatible = "syscon-reboot"; - regmap = <&timer>; - offset = <0x34>; - mask = <1>; - }; + reboot { + compatible = "syscon-reboot"; + regmap = <&timer>; + offset = <0x34>; + mask = <1>; }; };
From: Ajish Koshy Ajish.Koshy@microchip.com
[ Upstream commit 51e6ed83bb4ade7c360551fa4ae55c4eacea354b ]
Driver failed to release all memory allocated. This would lead to memory leak during driver removal.
Properly free memory when the module is removed.
Link: https://lore.kernel.org/r/20210906170404.5682-5-Ajish.Koshy@microchip.com Acked-by: Jack Wang jinpu.wang@ionos.com Signed-off-by: Ajish Koshy Ajish.Koshy@microchip.com Signed-off-by: Viswas G Viswas.G@microchip.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pm8001/pm8001_init.c | 11 +++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 1 + 2 files changed, 12 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 47db7e0beae6f..729d8252028e8 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -1198,6 +1198,7 @@ pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha, struct Scsi_Host *shost, goto err_out;
/* Memory region for ccb_info*/ + pm8001_ha->ccb_count = ccb_count; pm8001_ha->ccb_info = kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL); if (!pm8001_ha->ccb_info) { @@ -1259,6 +1260,16 @@ static void pm8001_pci_remove(struct pci_dev *pdev) tasklet_kill(&pm8001_ha->tasklet[j]); #endif scsi_host_put(pm8001_ha->shost); + + for (i = 0; i < pm8001_ha->ccb_count; i++) { + dma_free_coherent(&pm8001_ha->pdev->dev, + sizeof(struct pm8001_prd) * PM8001_MAX_DMA_SG, + pm8001_ha->ccb_info[i].buf_prd, + pm8001_ha->ccb_info[i].ccb_dma_handle); + } + kfree(pm8001_ha->ccb_info); + kfree(pm8001_ha->devices); + pm8001_free(pm8001_ha); kfree(sha->sas_phy); kfree(sha->sas_port); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index e18f2b60371db..f40a41f450d9b 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -517,6 +517,7 @@ struct pm8001_hba_info { u32 iomb_size; /* SPC and SPCV IOMB size */ struct pm8001_device *devices; struct pm8001_ccb_info *ccb_info; + u32 ccb_count; #ifdef PM8001_USE_MSIX int number_of_intr;/*will be used in remove()*/ char intr_drvname[PM8001_MAX_MSIX_VEC]
From: James Smart jsmart2021@gmail.com
[ Upstream commit 99154581b05c8fb22607afb7c3d66c1bace6aa5d ]
When parsing the txq list in lpfc_drain_txq(), the driver attempts to pass the requests to the adapter. If such an attempt fails, a local "fail_msg" string is set and a log message output. The job is then added to a completions list for cancellation.
Processing of any further jobs from the txq list continues, but since "fail_msg" remains set, jobs are added to the completions list regardless of whether a wqe was passed to the adapter. If successfully added to txcmplq, jobs are added to both lists resulting in list corruption.
Fix by clearing the fail_msg string after adding a job to the completions list. This stops the subsequent jobs from being added to the completions list unless they had an appropriate failure.
Link: https://lore.kernel.org/r/20210910233159.115896-2-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 | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 2fc671c8a638c..8e689f06afc92 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -21162,6 +21162,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) fail_msg, piocbq->iotag, piocbq->sli4_xritag); list_add_tail(&piocbq->list, &completions); + fail_msg = NULL; } spin_unlock_irqrestore(&pring->ring_lock, iflags); }
From: Bixuan Cui cuibixuan@huawei.com
[ Upstream commit b2fc2c92d2fd34d93268f677e514936f50dd6b5c ]
The platform_node is returned by of_parse_phandle() should have of_node_put() before return.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Bixuan Cui cuibixuan@huawei.com Link: https://lore.kernel.org/r/20210911081246.33867-1-cuibixuan@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c index de09f67c04502..a3fa8efc8f81c 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -1040,8 +1040,10 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) }
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) + if (!priv) { + of_node_put(platform_node); return -ENOMEM; + }
snd_soc_card_set_drvdata(card, priv);
@@ -1049,6 +1051,8 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) if (ret) dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", __func__, ret); + + of_node_put(platform_node); return ret; }
From: Matthias Brugger mbrugger@suse.com
[ Upstream commit 2513fa5c25d42f55ca5f0f0ab247af7c9fbfa3b1 ]
The CDN DP needs a PHY and a extcon to work correctly. But no extcon is provided by the device-tree, which leads to an error: cdn-dp fec00000.dp: [drm:cdn_dp_probe [rockchipdrm]] *ERROR* missing extcon or phy cdn-dp: probe of fec00000.dp failed with error -22
Disable the CDN DP to make graphic work on the Pinebook Pro.
Reported-by: Guillaume Gardet guillaume.gardet@arm.com Signed-off-by: Matthias Brugger mbrugger@suse.com Link: https://lore.kernel.org/r/20210715164101.11486-1-matthias.bgg@kernel.org Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts index 2b5f001ff4a61..9e5d07f5712e6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts @@ -385,10 +385,6 @@ }; };
-&cdn_dp { - status = "okay"; -}; - &cpu_b0 { cpu-supply = <&vdd_cpu_b>; };
From: Michael Walle michael@walle.cc
[ Upstream commit 894d4f1f77d0e88f1f81af2e1e37333c1c41b631 ]
According to Documentation/devicetree/bindings/watchdog/arm,sp805.yaml the compatible is: compatible = "arm,sp805", "arm,primecell";
The current compatible string doesn't exist at all. Fix it.
Signed-off-by: Michael Walle michael@walle.cc Signed-off-by: Wei Xu xuwei5@hisilicon.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 ++-- arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi index 2d5c1a348716a..6eabec2602e23 100644 --- a/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -1087,7 +1087,7 @@ };
watchdog0: watchdog@e8a06000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xe8a06000 0x0 0x1000>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; clocks = <&crg_ctrl HI3660_OSC32K>, @@ -1096,7 +1096,7 @@ };
watchdog1: watchdog@e8a07000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xe8a07000 0x0 0x1000>; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; clocks = <&crg_ctrl HI3660_OSC32K>, diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi index dde9371dc5451..e4860b8a638ec 100644 --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -840,7 +840,7 @@ };
watchdog0: watchdog@f8005000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xf8005000 0x0 0x1000>; interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ao_ctrl HI6220_WDT0_PCLK>,
From: Selvin Xavier selvin.xavier@broadcom.com
[ Upstream commit 6bda39149d4b8920fdb8744090653aca3daa792d ]
When VF is configured with default vlan, HW strips the vlan from the packet and driver receives it in Rx completion. VLAN needs to be reported for UD work completion only if the vlan is configured on the host. Add a check for valid vlan in the UD receive path.
Link: https://lore.kernel.org/r/1631709163-2287-12-git-send-email-selvin.xavier@br... Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 408dfbcc47b5e..b7ec3a3926785 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -3354,8 +3354,11 @@ static void bnxt_re_process_res_ud_wc(struct bnxt_re_qp *qp, struct ib_wc *wc, struct bnxt_qplib_cqe *cqe) { + struct bnxt_re_dev *rdev; + u16 vlan_id = 0; u8 nw_type;
+ rdev = qp->rdev; wc->opcode = IB_WC_RECV; wc->status = __rc_to_ib_wc_status(cqe->status);
@@ -3367,9 +3370,12 @@ static void bnxt_re_process_res_ud_wc(struct bnxt_re_qp *qp, memcpy(wc->smac, cqe->smac, ETH_ALEN); wc->wc_flags |= IB_WC_WITH_SMAC; if (cqe->flags & CQ_RES_UD_FLAGS_META_FORMAT_VLAN) { - wc->vlan_id = (cqe->cfa_meta & 0xFFF); - if (wc->vlan_id < 0x1000) - wc->wc_flags |= IB_WC_WITH_VLAN; + vlan_id = (cqe->cfa_meta & 0xFFF); + } + /* Mark only if vlan_id is non zero */ + if (vlan_id && bnxt_re_check_if_vlan_valid(rdev, vlan_id)) { + wc->vlan_id = vlan_id; + wc->wc_flags |= IB_WC_WITH_VLAN; } nw_type = (cqe->flags & CQ_RES_UD_FLAGS_ROCE_IP_VER_MASK) >> CQ_RES_UD_FLAGS_ROCE_IP_VER_SFT;
From: Tony Lindgren tony@atomide.com
[ Upstream commit 9d881361206ebcf6285c2ec2ef275aff80875347 ]
Some interconnect target modules such as otg and gpmc on am335x need a re-init after resume. As we also have PM runtime cases where the context may be lost, let's handle these all with cpu_pm.
For the am335x resume path, we already have cpu_pm_resume() call cpu_pm_cluster_exit().
Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/ti-sysc.c | 108 ++++++++++++++++++++++++-- include/linux/platform_data/ti-sysc.h | 1 + 2 files changed, 103 insertions(+), 6 deletions(-)
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index f47c7e20cc271..7c645754a82b1 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -6,6 +6,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <linux/clkdev.h> +#include <linux/cpu_pm.h> #include <linux/delay.h> #include <linux/list.h> #include <linux/module.h> @@ -52,11 +53,18 @@ struct sysc_address { struct list_head node; };
+struct sysc_module { + struct sysc *ddata; + struct list_head node; +}; + struct sysc_soc_info { unsigned long general_purpose:1; enum sysc_soc soc; - struct mutex list_lock; /* disabled modules list lock */ + struct mutex list_lock; /* disabled and restored modules list lock */ struct list_head disabled_modules; + struct list_head restored_modules; + struct notifier_block nb; };
enum sysc_clocks { @@ -2442,6 +2450,79 @@ static struct dev_pm_domain sysc_child_pm_domain = { } };
+/* Caller needs to take list_lock if ever used outside of cpu_pm */ +static void sysc_reinit_modules(struct sysc_soc_info *soc) +{ + struct sysc_module *module; + struct list_head *pos; + struct sysc *ddata; + int error = 0; + + list_for_each(pos, &sysc_soc->restored_modules) { + module = list_entry(pos, struct sysc_module, node); + ddata = module->ddata; + error = sysc_reinit_module(ddata, ddata->enabled); + } +} + +/** + * sysc_context_notifier - optionally reset and restore module after idle + * @nb: notifier block + * @cmd: unused + * @v: unused + * + * Some interconnect target modules need to be restored, or reset and restored + * on CPU_PM CPU_PM_CLUSTER_EXIT notifier. This is needed at least for am335x + * OTG and GPMC target modules even if the modules are unused. + */ +static int sysc_context_notifier(struct notifier_block *nb, unsigned long cmd, + void *v) +{ + struct sysc_soc_info *soc; + + soc = container_of(nb, struct sysc_soc_info, nb); + + switch (cmd) { + case CPU_CLUSTER_PM_ENTER: + break; + case CPU_CLUSTER_PM_ENTER_FAILED: /* No need to restore context */ + break; + case CPU_CLUSTER_PM_EXIT: + sysc_reinit_modules(soc); + break; + } + + return NOTIFY_OK; +} + +/** + * sysc_add_restored - optionally add reset and restore quirk hanlling + * @ddata: device data + */ +static void sysc_add_restored(struct sysc *ddata) +{ + struct sysc_module *restored_module; + + restored_module = kzalloc(sizeof(*restored_module), GFP_KERNEL); + if (!restored_module) + return; + + restored_module->ddata = ddata; + + mutex_lock(&sysc_soc->list_lock); + + list_add(&restored_module->node, &sysc_soc->restored_modules); + + if (sysc_soc->nb.notifier_call) + goto out_unlock; + + sysc_soc->nb.notifier_call = sysc_context_notifier; + cpu_pm_register_notifier(&sysc_soc->nb); + +out_unlock: + mutex_unlock(&sysc_soc->list_lock); +} + /** * sysc_legacy_idle_quirk - handle children in omap_device compatible way * @ddata: device driver data @@ -2941,12 +3022,14 @@ static int sysc_add_disabled(unsigned long base) }
/* - * One time init to detect the booted SoC and disable unavailable features. + * One time init to detect the booted SoC, disable unavailable features + * and initialize list for optional cpu_pm notifier. + * * Note that we initialize static data shared across all ti-sysc instances * so ddata is only used for SoC type. This can be called from module_init * once we no longer need to rely on platform data. */ -static int sysc_init_soc(struct sysc *ddata) +static int sysc_init_static_data(struct sysc *ddata) { const struct soc_device_attribute *match; struct ti_sysc_platform_data *pdata; @@ -2962,6 +3045,7 @@ static int sysc_init_soc(struct sysc *ddata)
mutex_init(&sysc_soc->list_lock); INIT_LIST_HEAD(&sysc_soc->disabled_modules); + INIT_LIST_HEAD(&sysc_soc->restored_modules); sysc_soc->general_purpose = true;
pdata = dev_get_platdata(ddata->dev); @@ -3026,15 +3110,24 @@ static int sysc_init_soc(struct sysc *ddata) return 0; }
-static void sysc_cleanup_soc(void) +static void sysc_cleanup_static_data(void) { + struct sysc_module *restored_module; struct sysc_address *disabled_module; struct list_head *pos, *tmp;
if (!sysc_soc) return;
+ if (sysc_soc->nb.notifier_call) + cpu_pm_unregister_notifier(&sysc_soc->nb); + mutex_lock(&sysc_soc->list_lock); + list_for_each_safe(pos, tmp, &sysc_soc->restored_modules) { + restored_module = list_entry(pos, struct sysc_module, node); + list_del(pos); + kfree(restored_module); + } list_for_each_safe(pos, tmp, &sysc_soc->disabled_modules) { disabled_module = list_entry(pos, struct sysc_address, node); list_del(pos); @@ -3102,7 +3195,7 @@ static int sysc_probe(struct platform_device *pdev) ddata->dev = &pdev->dev; platform_set_drvdata(pdev, ddata);
- error = sysc_init_soc(ddata); + error = sysc_init_static_data(ddata); if (error) return error;
@@ -3200,6 +3293,9 @@ static int sysc_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); }
+ if (ddata->cfg.quirks & SYSC_QUIRK_REINIT_ON_CTX_LOST) + sysc_add_restored(ddata); + return 0;
err: @@ -3281,7 +3377,7 @@ static void __exit sysc_exit(void) { bus_unregister_notifier(&platform_bus_type, &sysc_nb); platform_driver_unregister(&sysc_driver); - sysc_cleanup_soc(); + sysc_cleanup_static_data(); } module_exit(sysc_exit);
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h index 9837fb011f2fb..989aa30c598dc 100644 --- a/include/linux/platform_data/ti-sysc.h +++ b/include/linux/platform_data/ti-sysc.h @@ -50,6 +50,7 @@ struct sysc_regbits { s8 emufree_shift; };
+#define SYSC_QUIRK_REINIT_ON_CTX_LOST BIT(28) #define SYSC_QUIRK_REINIT_ON_RESUME BIT(27) #define SYSC_QUIRK_GPMC_DEBUG BIT(26) #define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25)
From: Tony Lindgren tony@atomide.com
[ Upstream commit 9067839ff45a528bcb015cc2f24f656126b91e3f ]
Let's use SYSC_QUIRK_REINIT_ON_CTX_LOST quirk for am335x otg instead of SYSC_QUIRK_REINIT_ON_RESUME quirk as we can now handle the context loss in a more generic way.
Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/ti-sysc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 7c645754a82b1..bb377bb13564a 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -1567,7 +1567,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY | - SYSC_QUIRK_REINIT_ON_RESUME), + SYSC_QUIRK_REINIT_ON_CTX_LOST), SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, SYSC_MODULE_QUIRK_WDT), /* PRUSS on am3, am4 and am5 */
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 14651496a3de6807a17c310f63c894ea0c5d858e ]
It will cause null-ptr-deref if platform_get_resource() returns NULL, we need check the return value.
Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20210915034925.2399823-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/musb/tusb6010.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index c968ecda42aa8..7ed4cc348d993 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1104,6 +1104,11 @@ static int tusb_musb_init(struct musb *musb)
/* dma address for async dma */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + pr_debug("no async dma resource?\n"); + ret = -ENODEV; + goto done; + } musb->async = mem->start;
/* dma address for sync dma */
From: Sven Peter sven@svenpeter.dev
[ Upstream commit b7a0a63f3fed57d413bb857de164ea9c3984bc4e ]
Calling tps6598x_block_read with a higher than allowed len can be handled by just returning an error. There's no need to crash systems with panic-on-warn enabled.
Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Signed-off-by: Sven Peter sven@svenpeter.dev Link: https://lore.kernel.org/r/20210914140235.65955-3-sven@svenpeter.dev Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/tipd/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index ea4cc0a6e40cc..97f50f301f13b 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -117,7 +117,7 @@ tps6598x_block_read(struct tps6598x *tps, u8 reg, void *val, size_t len) u8 data[TPS_MAX_LEN + 1]; int ret;
- if (WARN_ON(len + 1 > sizeof(data))) + if (len + 1 > sizeof(data)) return -EINVAL;
if (!tps->i2c_protocol)
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 7aee0288beab72cdfa35af51f62e94373fca595d ]
AUX2 has slightly wrong voltage and AUX5 doesn't need to be always on.
Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ste-ux500-samsung-skomer.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts index 264f3e9b5fce5..86e83639fadc1 100644 --- a/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts +++ b/arch/arm/boot/dts/ste-ux500-samsung-skomer.dts @@ -292,10 +292,10 @@ };
ab8500_ldo_aux2 { - /* Supplies the Cypress TMA140 touchscreen only with 3.3V */ + /* Supplies the Cypress TMA140 touchscreen only with 3.0V */ regulator-name = "AUX2"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; };
ab8500_ldo_aux3 { @@ -314,9 +314,9 @@
ab8500_ldo_aux5 { regulator-name = "AUX5"; + /* Intended for 1V8 for touchscreen but actually left unused */ regulator-min-microvolt = <1050000>; regulator-max-microvolt = <2790000>; - regulator-always-on; };
ab8500_ldo_aux6 {
From: Fabio Aiuto fabioaiuto83@gmail.com
[ Upstream commit 54659ca026e586bbb33a7e60daa6443a3ac6b5df ]
when turning off a connection, lockdep complains with the following warning (a modprobe has been done but the same happens with a disconnection from NetworkManager, it's enough to trigger a cfg80211_disconnect call):
[ 682.855867] ====================================================== [ 682.855877] WARNING: possible circular locking dependency detected [ 682.855887] 5.14.0-rc6+ #16 Tainted: G C OE [ 682.855898] ------------------------------------------------------ [ 682.855906] modprobe/1770 is trying to acquire lock: [ 682.855916] ffffb6d000332b00 (&pxmitpriv->lock){+.-.}-{2:2}, at: rtw_free_stainfo+0x52/0x4a0 [r8723bs] [ 682.856073] but task is already holding lock: [ 682.856081] ffffb6d0003336a8 (&pstapriv->sta_hash_lock){+.-.}-{2:2}, at: rtw_free_assoc_resources+0x48/0x110 [r8723bs] [ 682.856207] which lock already depends on the new lock.
[ 682.856215] the existing dependency chain (in reverse order) is: [ 682.856223] -> #1 (&pstapriv->sta_hash_lock){+.-.}-{2:2}: [ 682.856247] _raw_spin_lock_bh+0x34/0x40 [ 682.856265] rtw_get_stainfo+0x9a/0x110 [r8723bs] [ 682.856389] rtw_xmit_classifier+0x27/0x130 [r8723bs] [ 682.856515] rtw_xmitframe_enqueue+0xa/0x20 [r8723bs] [ 682.856642] rtl8723bs_hal_xmit+0x3b/0xb0 [r8723bs] [ 682.856752] rtw_xmit+0x4ef/0x890 [r8723bs] [ 682.856879] _rtw_xmit_entry+0xba/0x350 [r8723bs] [ 682.856981] dev_hard_start_xmit+0xee/0x320 [ 682.856999] sch_direct_xmit+0x8c/0x330 [ 682.857014] __dev_queue_xmit+0xba5/0xf00 [ 682.857030] packet_sendmsg+0x981/0x1b80 [ 682.857047] sock_sendmsg+0x5b/0x60 [ 682.857060] __sys_sendto+0xf1/0x160 [ 682.857073] __x64_sys_sendto+0x24/0x30 [ 682.857087] do_syscall_64+0x3a/0x80 [ 682.857102] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 682.857117] -> #0 (&pxmitpriv->lock){+.-.}-{2:2}: [ 682.857142] __lock_acquire+0xfd9/0x1b50 [ 682.857158] lock_acquire+0xb4/0x2c0 [ 682.857172] _raw_spin_lock_bh+0x34/0x40 [ 682.857185] rtw_free_stainfo+0x52/0x4a0 [r8723bs] [ 682.857308] rtw_free_assoc_resources+0x53/0x110 [r8723bs] [ 682.857415] cfg80211_rtw_disconnect+0x4b/0x70 [r8723bs] [ 682.857522] cfg80211_disconnect+0x12e/0x2f0 [cfg80211] [ 682.857759] cfg80211_leave+0x2b/0x40 [cfg80211] [ 682.857961] cfg80211_netdev_notifier_call+0xa9/0x560 [cfg80211] [ 682.858163] raw_notifier_call_chain+0x41/0x50 [ 682.858180] __dev_close_many+0x62/0x100 [ 682.858195] dev_close_many+0x7d/0x120 [ 682.858209] unregister_netdevice_many+0x416/0x680 [ 682.858225] unregister_netdevice_queue+0xab/0xf0 [ 682.858240] unregister_netdev+0x18/0x20 [ 682.858255] rtw_unregister_netdevs+0x28/0x40 [r8723bs] [ 682.858360] rtw_dev_remove+0x24/0xd0 [r8723bs] [ 682.858463] sdio_bus_remove+0x31/0xd0 [mmc_core] [ 682.858532] device_release_driver_internal+0xf7/0x1d0 [ 682.858550] driver_detach+0x47/0x90 [ 682.858564] bus_remove_driver+0x77/0xd0 [ 682.858579] rtw_drv_halt+0xc/0x678 [r8723bs] [ 682.858685] __x64_sys_delete_module+0x13f/0x250 [ 682.858699] do_syscall_64+0x3a/0x80 [ 682.858715] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 682.858729] other info that might help us debug this:
[ 682.858737] Possible unsafe locking scenario:
[ 682.858744] CPU0 CPU1 [ 682.858751] ---- ---- [ 682.858758] lock(&pstapriv->sta_hash_lock); [ 682.858772] lock(&pxmitpriv->lock); [ 682.858786] lock(&pstapriv->sta_hash_lock); [ 682.858799] lock(&pxmitpriv->lock); [ 682.858812] *** DEADLOCK ***
[ 682.858820] 5 locks held by modprobe/1770: [ 682.858831] #0: ffff8d870697d980 (&dev->mutex){....}-{3:3}, at: device_release_driver_internal+0x1a/0x1d0 [ 682.858869] #1: ffffffffbdbbf1c8 (rtnl_mutex){+.+.}-{3:3}, at: unregister_netdev+0xe/0x20 [ 682.858906] #2: ffff8d87054ee5e8 (&rdev->wiphy.mtx){+.+.}-{3:3}, at: cfg80211_netdev_notifier_call+0x9e/0x560 [cfg80211] [ 682.859131] #3: ffff8d870f2bc8f0 (&wdev->mtx){+.+.}-{3:3}, at: cfg80211_leave+0x20/0x40 [cfg80211] [ 682.859354] #4: ffffb6d0003336a8 (&pstapriv->sta_hash_lock){+.-.}-{2:2}, at: rtw_free_assoc_resources+0x48/0x110 [r8723bs] [ 682.859482] stack backtrace: [ 682.859491] CPU: 1 PID: 1770 Comm: modprobe Tainted: G C OE 5.14.0-rc6+ #16 [ 682.859507] Hardware name: LENOVO 80NR/Madrid, BIOS DACN25WW 08/20/2015 [ 682.859517] Call Trace: [ 682.859531] dump_stack_lvl+0x56/0x6f [ 682.859551] check_noncircular+0xdb/0xf0 [ 682.859579] __lock_acquire+0xfd9/0x1b50 [ 682.859606] lock_acquire+0xb4/0x2c0 [ 682.859623] ? rtw_free_stainfo+0x52/0x4a0 [r8723bs] [ 682.859752] ? mark_held_locks+0x48/0x70 [ 682.859769] ? rtw_free_stainfo+0x4a/0x4a0 [r8723bs] [ 682.859898] _raw_spin_lock_bh+0x34/0x40 [ 682.859914] ? rtw_free_stainfo+0x52/0x4a0 [r8723bs] [ 682.860039] rtw_free_stainfo+0x52/0x4a0 [r8723bs] [ 682.860171] rtw_free_assoc_resources+0x53/0x110 [r8723bs] [ 682.860286] cfg80211_rtw_disconnect+0x4b/0x70 [r8723bs] [ 682.860397] cfg80211_disconnect+0x12e/0x2f0 [cfg80211] [ 682.860629] cfg80211_leave+0x2b/0x40 [cfg80211] [ 682.860836] cfg80211_netdev_notifier_call+0xa9/0x560 [cfg80211] [ 682.861048] ? __lock_acquire+0x4dc/0x1b50 [ 682.861070] ? lock_is_held_type+0xa8/0x110 [ 682.861089] ? lock_is_held_type+0xa8/0x110 [ 682.861104] ? find_held_lock+0x2d/0x90 [ 682.861120] ? packet_notifier+0x173/0x300 [ 682.861141] ? lock_release+0xb3/0x250 [ 682.861160] ? packet_notifier+0x192/0x300 [ 682.861184] raw_notifier_call_chain+0x41/0x50 [ 682.861205] __dev_close_many+0x62/0x100 [ 682.861224] dev_close_many+0x7d/0x120 [ 682.861245] unregister_netdevice_many+0x416/0x680 [ 682.861264] ? find_held_lock+0x2d/0x90 [ 682.861284] unregister_netdevice_queue+0xab/0xf0 [ 682.861306] unregister_netdev+0x18/0x20 [ 682.861325] rtw_unregister_netdevs+0x28/0x40 [r8723bs] [ 682.861434] rtw_dev_remove+0x24/0xd0 [r8723bs] [ 682.861542] sdio_bus_remove+0x31/0xd0 [mmc_core] [ 682.861615] device_release_driver_internal+0xf7/0x1d0 [ 682.861637] driver_detach+0x47/0x90 [ 682.861656] bus_remove_driver+0x77/0xd0 [ 682.861674] rtw_drv_halt+0xc/0x678 [r8723bs] [ 682.861782] __x64_sys_delete_module+0x13f/0x250 [ 682.861801] ? lockdep_hardirqs_on_prepare+0xf3/0x170 [ 682.861817] ? syscall_enter_from_user_mode+0x20/0x70 [ 682.861836] do_syscall_64+0x3a/0x80 [ 682.861855] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 682.861873] RIP: 0033:0x7f6dbe85400b [ 682.861890] Code: 73 01 c3 48 8b 0d 6d 1e 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 3d 1e 0c 00 f7 d8 64 89 01 48 [ 682.861906] RSP: 002b:00007ffe7a82f538 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 [ 682.861923] RAX: ffffffffffffffda RBX: 000055a64693bd20 RCX: 00007f6dbe85400b [ 682.861935] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055a64693bd88 [ 682.861946] RBP: 000055a64693bd20 R08: 0000000000000000 R09: 0000000000000000 [ 682.861957] R10: 00007f6dbe8c7ac0 R11: 0000000000000206 R12: 000055a64693bd88 [ 682.861967] R13: 0000000000000000 R14: 000055a64693bd88 R15: 00007ffe7a831848
This happens because when we enqueue a frame for transmission we do it under xmit_priv lock, then calling rtw_get_stainfo (needed for enqueuing) takes sta_hash_lock and this leads to the following lock dependency:
xmit_priv->lock -> sta_hash_lock
Turning off a connection will bring to call rtw_free_assoc_resources which will set up the inverse dependency:
sta_hash_lock -> xmit_priv_lock
This could lead to a deadlock as lockdep complains.
Fix it by removing the xmit_priv->lock around rtw_xmitframe_enqueue call inside rtl8723bs_hal_xmit and put it in a smaller critical section inside rtw_xmit_classifier, the only place where xmit_priv data are actually accessed.
Replace spin_{lock,unlock}_bh(pxmitpriv->lock) in other tx paths leading to rtw_xmitframe_enqueue call with spin_{lock,unlock}_bh(psta->sleep_q.lock) - it's not clear why accessing a sleep_q was protected by a spinlock on xmitpriv->lock.
This way is avoided the same faulty lock nesting order.
Extra changes in v2 by Hans de Goede: -Lift the taking of the struct __queue.lock spinlock out of rtw_free_xmitframe_queue() into the callers this allows also protecting a bunch of related state in rtw_free_stainfo(): -Protect psta->sleepq_len on rtw_free_xmitframe_queue(&psta->sleep_q); -Protect struct tx_servq.tx_pending and tx_servq.qcnt when calling rtw_free_xmitframe_queue(&tx_servq.sta_pending) -This also allows moving the spin_lock_bh(&pxmitpriv->lock); to below the sleep_q free-ing code, avoiding another ABBA locking issue
CC: Larry Finger Larry.Finger@lwfinger.net Co-developed-by: Hans de Goede hdegoede@redhat.com Tested-on: Lenovo Ideapad MiiX 300-10IBY Signed-off-by: Fabio Aiuto fabioaiuto83@gmail.com Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20210920145502.155454-1-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 7 ++---- drivers/staging/rtl8723bs/core/rtw_recv.c | 10 +++------ drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 22 ++++++++++--------- drivers/staging/rtl8723bs/core/rtw_xmit.c | 16 ++++++-------- .../staging/rtl8723bs/hal/rtl8723bs_xmit.c | 2 -- 5 files changed, 24 insertions(+), 33 deletions(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 375d2a742dd2d..a1ae16ec69eb6 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -5919,7 +5919,6 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf) struct sta_info *psta_bmc; struct list_head *xmitframe_plist, *xmitframe_phead, *tmp; struct xmit_frame *pxmitframe = NULL; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; struct sta_priv *pstapriv = &padapter->stapriv;
/* for BC/MC Frames */ @@ -5930,8 +5929,7 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf) if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) { msleep(10);/* 10ms, ATIM(HIQ) Windows */
- /* spin_lock_bh(&psta_bmc->sleep_q.lock); */ - spin_lock_bh(&pxmitpriv->lock); + spin_lock_bh(&psta_bmc->sleep_q.lock);
xmitframe_phead = get_list_head(&psta_bmc->sleep_q); list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) { @@ -5954,8 +5952,7 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf) rtw_hal_xmitframe_enqueue(padapter, pxmitframe); }
- /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */ - spin_unlock_bh(&pxmitpriv->lock); + spin_unlock_bh(&psta_bmc->sleep_q.lock);
/* check hi queue and bmc_sleepq */ rtw_chk_hi_queue_cmd(padapter); diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index 5b0a596eefb77..3564e2af5741b 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -953,10 +953,8 @@ static signed int validate_recv_ctrl_frame(struct adapter *padapter, union recv_ if ((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) { struct list_head *xmitframe_plist, *xmitframe_phead; struct xmit_frame *pxmitframe = NULL; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- /* spin_lock_bh(&psta->sleep_q.lock); */ - spin_lock_bh(&pxmitpriv->lock); + spin_lock_bh(&psta->sleep_q.lock);
xmitframe_phead = get_list_head(&psta->sleep_q); xmitframe_plist = get_next(xmitframe_phead); @@ -987,12 +985,10 @@ static signed int validate_recv_ctrl_frame(struct adapter *padapter, union recv_ update_beacon(padapter, WLAN_EID_TIM, NULL, true); }
- /* spin_unlock_bh(&psta->sleep_q.lock); */ - spin_unlock_bh(&pxmitpriv->lock); + spin_unlock_bh(&psta->sleep_q.lock);
} else { - /* spin_unlock_bh(&psta->sleep_q.lock); */ - spin_unlock_bh(&pxmitpriv->lock); + spin_unlock_bh(&psta->sleep_q.lock);
if (pstapriv->tim_bitmap&BIT(psta->aid)) { if (psta->sleepq_len == 0) { diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c index 67ca219f95bf8..c23d0c833ecf8 100644 --- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c @@ -289,46 +289,48 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
/* list_del_init(&psta->wakeup_list); */
- spin_lock_bh(&pxmitpriv->lock); - + spin_lock_bh(&psta->sleep_q.lock); rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q); psta->sleepq_len = 0; + spin_unlock_bh(&psta->sleep_q.lock); + + spin_lock_bh(&pxmitpriv->lock);
/* vo */ - /* spin_lock_bh(&(pxmitpriv->vo_pending.lock)); */ + spin_lock_bh(&pstaxmitpriv->vo_q.sta_pending.lock); rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); list_del_init(&(pstaxmitpriv->vo_q.tx_pending)); phwxmit = pxmitpriv->hwxmits; phwxmit->accnt -= pstaxmitpriv->vo_q.qcnt; pstaxmitpriv->vo_q.qcnt = 0; - /* spin_unlock_bh(&(pxmitpriv->vo_pending.lock)); */ + spin_unlock_bh(&pstaxmitpriv->vo_q.sta_pending.lock);
/* vi */ - /* spin_lock_bh(&(pxmitpriv->vi_pending.lock)); */ + spin_lock_bh(&pstaxmitpriv->vi_q.sta_pending.lock); rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); list_del_init(&(pstaxmitpriv->vi_q.tx_pending)); phwxmit = pxmitpriv->hwxmits+1; phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt; pstaxmitpriv->vi_q.qcnt = 0; - /* spin_unlock_bh(&(pxmitpriv->vi_pending.lock)); */ + spin_unlock_bh(&pstaxmitpriv->vi_q.sta_pending.lock);
/* be */ - /* spin_lock_bh(&(pxmitpriv->be_pending.lock)); */ + spin_lock_bh(&pstaxmitpriv->be_q.sta_pending.lock); rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending); list_del_init(&(pstaxmitpriv->be_q.tx_pending)); phwxmit = pxmitpriv->hwxmits+2; phwxmit->accnt -= pstaxmitpriv->be_q.qcnt; pstaxmitpriv->be_q.qcnt = 0; - /* spin_unlock_bh(&(pxmitpriv->be_pending.lock)); */ + spin_unlock_bh(&pstaxmitpriv->be_q.sta_pending.lock);
/* bk */ - /* spin_lock_bh(&(pxmitpriv->bk_pending.lock)); */ + spin_lock_bh(&pstaxmitpriv->bk_q.sta_pending.lock); rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); list_del_init(&(pstaxmitpriv->bk_q.tx_pending)); phwxmit = pxmitpriv->hwxmits+3; phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt; pstaxmitpriv->bk_q.qcnt = 0; - /* spin_unlock_bh(&(pxmitpriv->bk_pending.lock)); */ + spin_unlock_bh(&pstaxmitpriv->bk_q.sta_pending.lock);
spin_unlock_bh(&pxmitpriv->lock);
diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 79e4d7df1ef57..6b37b42ec2266 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -1723,15 +1723,12 @@ void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pfram struct list_head *plist, *phead, *tmp; struct xmit_frame *pxmitframe;
- spin_lock_bh(&pframequeue->lock); - phead = get_list_head(pframequeue); list_for_each_safe(plist, tmp, phead) { pxmitframe = list_entry(plist, struct xmit_frame, list);
rtw_free_xmitframe(pxmitpriv, pxmitframe); } - spin_unlock_bh(&pframequeue->lock); }
s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe) @@ -1786,6 +1783,7 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe) struct sta_info *psta; struct tx_servq *ptxservq; struct pkt_attrib *pattrib = &pxmitframe->attrib; + struct xmit_priv *xmit_priv = &padapter->xmitpriv; struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; signed int res = _SUCCESS;
@@ -1803,12 +1801,14 @@ s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
+ spin_lock_bh(&xmit_priv->lock); if (list_empty(&ptxservq->tx_pending)) list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending)); ptxservq->qcnt++; phwxmits[ac_index].accnt++; + spin_unlock_bh(&xmit_priv->lock);
exit:
@@ -2191,11 +2191,10 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta) struct list_head *xmitframe_plist, *xmitframe_phead, *tmp; struct xmit_frame *pxmitframe = NULL; struct sta_priv *pstapriv = &padapter->stapriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
psta_bmc = rtw_get_bcmc_stainfo(padapter);
- spin_lock_bh(&pxmitpriv->lock); + spin_lock_bh(&psta->sleep_q.lock);
xmitframe_phead = get_list_head(&psta->sleep_q); list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) { @@ -2296,7 +2295,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
_exit:
- spin_unlock_bh(&pxmitpriv->lock); + spin_unlock_bh(&psta->sleep_q.lock);
if (update_mask) update_beacon(padapter, WLAN_EID_TIM, NULL, true); @@ -2308,9 +2307,8 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst struct list_head *xmitframe_plist, *xmitframe_phead, *tmp; struct xmit_frame *pxmitframe = NULL; struct sta_priv *pstapriv = &padapter->stapriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- spin_lock_bh(&pxmitpriv->lock); + spin_lock_bh(&psta->sleep_q.lock);
xmitframe_phead = get_list_head(&psta->sleep_q); list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) { @@ -2363,7 +2361,7 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst } }
- spin_unlock_bh(&pxmitpriv->lock); + spin_unlock_bh(&psta->sleep_q.lock); }
void enqueue_pending_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf) diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c index 156d6aba18ca1..5f5c4719b5868 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c @@ -507,9 +507,7 @@ s32 rtl8723bs_hal_xmit( rtw_issue_addbareq_cmd(padapter, pxmitframe); }
- spin_lock_bh(&pxmitpriv->lock); err = rtw_xmitframe_enqueue(padapter, pxmitframe); - spin_unlock_bh(&pxmitpriv->lock); if (err != _SUCCESS) { rtw_free_xmitframe(pxmitpriv, pxmitframe);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit a7ac783c338bafc04d3259600646350dba989043 ]
Lockdep complains about rtw_free_assoc_resources() taking the sta_hash_lock followed by it calling rtw_free_stainfo() which takes xmitpriv->lock. While the rtl8723bs_xmit_thread takes the sta_hash_lock while already holding the xmitpriv->lock:
[ 103.849756] ====================================================== [ 103.849761] WARNING: possible circular locking dependency detected [ 103.849767] 5.15.0-rc1+ #470 Tainted: G C E [ 103.849773] ------------------------------------------------------ [ 103.849776] wpa_supplicant/695 is trying to acquire lock: [ 103.849781] ffffa5d0c0562b00 (&pxmitpriv->lock){+.-.}-{2:2}, at: rtw_free_stainfo+0x8a/0x510 [r8723bs] [ 103.849840] but task is already holding lock: [ 103.849843] ffffa5d0c05636a8 (&pstapriv->sta_hash_lock){+.-.}-{2:2}, at: rtw_free_assoc_resources+0x48/0x110 [r8723bs] [ 103.849881] which lock already depends on the new lock.
[ 103.849884] the existing dependency chain (in reverse order) is: [ 103.849887] -> #1 (&pstapriv->sta_hash_lock){+.-.}-{2:2}: [ 103.849898] _raw_spin_lock_bh+0x34/0x40 [ 103.849913] rtw_get_stainfo+0x93/0x110 [r8723bs] [ 103.849948] rtw_make_wlanhdr+0x14a/0x270 [r8723bs] [ 103.849983] rtw_xmitframe_coalesce+0x5c/0x6c0 [r8723bs] [ 103.850019] rtl8723bs_xmit_thread+0x4ac/0x620 [r8723bs] [ 103.850050] kthread+0x143/0x160 [ 103.850058] ret_from_fork+0x22/0x30 [ 103.850067] -> #0 (&pxmitpriv->lock){+.-.}-{2:2}: [ 103.850077] __lock_acquire+0x1158/0x1de0 [ 103.850084] lock_acquire+0xb5/0x2b0 [ 103.850090] _raw_spin_lock_bh+0x34/0x40 [ 103.850095] rtw_free_stainfo+0x8a/0x510 [r8723bs] [ 103.850130] rtw_free_assoc_resources+0x53/0x110 [r8723bs] [ 103.850159] PHY_IQCalibrate_8723B+0x122b/0x36a0 [r8723bs] [ 103.850189] cfg80211_disconnect+0x173/0x320 [cfg80211] [ 103.850331] nl80211_disconnect+0x6e/0xb0 [cfg80211] [ 103.850422] genl_family_rcv_msg_doit+0xcd/0x110 [ 103.850430] genl_rcv_msg+0xce/0x1c0 [ 103.850435] netlink_rcv_skb+0x50/0xf0 [ 103.850441] genl_rcv+0x24/0x40 [ 103.850446] netlink_unicast+0x16d/0x230 [ 103.850452] netlink_sendmsg+0x22b/0x450 [ 103.850457] sock_sendmsg+0x5e/0x60 [ 103.850465] ____sys_sendmsg+0x22f/0x270 [ 103.850472] ___sys_sendmsg+0x81/0xc0 [ 103.850479] __sys_sendmsg+0x49/0x80 [ 103.850485] do_syscall_64+0x3b/0x90 [ 103.850493] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 103.850500] other info that might help us debug this:
[ 103.850504] Possible unsafe locking scenario:
[ 103.850507] CPU0 CPU1 [ 103.850510] ---- ---- [ 103.850512] lock(&pstapriv->sta_hash_lock); [ 103.850518] lock(&pxmitpriv->lock); [ 103.850524] lock(&pstapriv->sta_hash_lock); [ 103.850530] lock(&pxmitpriv->lock); [ 103.850535] *** DEADLOCK ***
Push the taking of sta_hash_lock down into rtw_free_stainfo(), where the critical section is, this allows taking the lock after rtw_free_stainfo() has released pxmitpriv->lock.
This requires changing rtw_free_all_stainfo() so that it does its freeing in 2 steps, first moving all stainfo-s to free to a local list while holding the sta_hash_lock and then walking that list to call rtw_free_stainfo() on them without holding the sta_hash_lock.
Pushing the taking of sta_hash_lock down into rtw_free_stainfo(), also fixes a whole bunch of callers of rtw_free_stainfo() which were not holding that lock even though they should.
Note that this also fixes the deadlock from the "remove possible deadlock when disconnect" patch in a different way. But the changes from that patch offer a nice locking cleanup regardless.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20210920145502.155454-2-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8723bs/core/rtw_mlme.c | 5 ----- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 4 ---- drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 11 +++++++++-- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 -- 4 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index ab6a24d70cc96..1f49c49e10b45 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -897,7 +897,6 @@ void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) { struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct wlan_network *tgt_network = &pmlmepriv->cur_network; - struct sta_priv *pstapriv = &adapter->stapriv; struct dvobj_priv *psdpriv = adapter->dvobj; struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
@@ -905,11 +904,7 @@ void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) struct sta_info *psta;
psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.mac_address); - spin_lock_bh(&(pstapriv->sta_hash_lock)); rtw_free_stainfo(adapter, psta); - - spin_unlock_bh(&(pstapriv->sta_hash_lock)); - }
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) { diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index a1ae16ec69eb6..ad9c237054c4b 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -1489,9 +1489,7 @@ unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame) struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv;
- /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ /* rtw_free_stainfo(padapter, psta); */ - /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
netdev_dbg(padapter->pnetdev, "ap recv deauth reason code(%d) sta:%pM\n", reason, @@ -1565,9 +1563,7 @@ unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame) struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv;
- /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ /* rtw_free_stainfo(padapter, psta); */ - /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
netdev_dbg(padapter->pnetdev, "ap recv disassoc reason code(%d) sta:%pM\n", diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c index c23d0c833ecf8..3d269842677dd 100644 --- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c @@ -263,7 +263,6 @@ exit: return psta; }
-/* using pstapriv->sta_hash_lock to protect */ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) { int i; @@ -334,8 +333,10 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
spin_unlock_bh(&pxmitpriv->lock);
+ spin_lock_bh(&pstapriv->sta_hash_lock); list_del_init(&psta->hash_list); pstapriv->asoc_sta_count--; + spin_unlock_bh(&pstapriv->sta_hash_lock);
/* re-init sta_info; 20061114 will be init in alloc_stainfo */ /* _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv); */ @@ -430,6 +431,7 @@ void rtw_free_all_stainfo(struct adapter *padapter) struct sta_info *psta = NULL; struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter); + LIST_HEAD(stainfo_free_list);
if (pstapriv->asoc_sta_count == 1) return; @@ -442,11 +444,16 @@ void rtw_free_all_stainfo(struct adapter *padapter) psta = list_entry(plist, struct sta_info, hash_list);
if (pbcmc_stainfo != psta) - rtw_free_stainfo(padapter, psta); + list_move(&psta->hash_list, &stainfo_free_list); } }
spin_unlock_bh(&pstapriv->sta_hash_lock); + + list_for_each_safe(plist, tmp, &stainfo_free_list) { + psta = list_entry(plist, struct sta_info, hash_list); + rtw_free_stainfo(padapter, psta); + } }
/* any station allocated can be searched by hash list */ diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c index 9d4a233a861e3..295121c268bd4 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c @@ -835,9 +835,7 @@ static int rtw_add_sta(struct net_device *dev, struct ieee_param *param) psta = rtw_get_stainfo(pstapriv, param->sta_addr); if (psta) { - spin_lock_bh(&(pstapriv->sta_hash_lock)); rtw_free_stainfo(padapter, psta); - spin_unlock_bh(&(pstapriv->sta_hash_lock));
psta = NULL; }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit bdc1bbdbaa92df19a14d4c1902088c8432b46c6f ]
The assoc_timer takes the pmlmepriv->lock and various functions which take the pmlmepriv->scanned_queue.lock first take the pmlmepriv->lock, this means that we cannot have code which waits for the timer (timer_del_sync) while holding the pmlmepriv->scanned_queue.lock to avoid a triangle deadlock:
[ 363.139361] ====================================================== [ 363.139377] WARNING: possible circular locking dependency detected [ 363.139396] 5.15.0-rc1+ #470 Tainted: G C E [ 363.139413] ------------------------------------------------------ [ 363.139424] RTW_CMD_THREAD/2466 is trying to acquire lock: [ 363.139441] ffffbacd00699038 (&pmlmepriv->lock){+.-.}-{2:2}, at: _rtw_join_timeout_handler+0x3c/0x160 [r8723bs] [ 363.139598] but task is already holding lock: [ 363.139610] ffffbacd00128ea0 ((&pmlmepriv->assoc_timer)){+.-.}-{0:0}, at: call_timer_fn+0x5/0x260 [ 363.139673] which lock already depends on the new lock.
[ 363.139684] the existing dependency chain (in reverse order) is: [ 363.139696] -> #2 ((&pmlmepriv->assoc_timer)){+.-.}-{0:0}: [ 363.139734] del_timer_sync+0x59/0x100 [ 363.139762] rtw_joinbss_event_prehandle+0x342/0x640 [r8723bs] [ 363.139870] report_join_res+0xdf/0x110 [r8723bs] [ 363.139980] OnAssocRsp+0x17a/0x200 [r8723bs] [ 363.140092] rtw_recv_entry+0x190/0x1120 [r8723bs] [ 363.140209] rtl8723b_process_phy_info+0x3f9/0x750 [r8723bs] [ 363.140318] tasklet_action_common.constprop.0+0xe8/0x110 [ 363.140345] __do_softirq+0xde/0x485 [ 363.140372] __irq_exit_rcu+0xd0/0x100 [ 363.140393] irq_exit_rcu+0xa/0x20 [ 363.140413] common_interrupt+0x83/0xa0 [ 363.140440] asm_common_interrupt+0x1e/0x40 [ 363.140463] finish_task_switch.isra.0+0x157/0x3d0 [ 363.140492] __schedule+0x447/0x1880 [ 363.140516] schedule+0x59/0xc0 [ 363.140537] smpboot_thread_fn+0x161/0x1c0 [ 363.140565] kthread+0x143/0x160 [ 363.140585] ret_from_fork+0x22/0x30 [ 363.140614] -> #1 (&pmlmepriv->scanned_queue.lock){+.-.}-{2:2}: [ 363.140653] _raw_spin_lock_bh+0x34/0x40 [ 363.140675] rtw_free_network_queue+0x31/0x80 [r8723bs] [ 363.140776] rtw_sitesurvey_cmd+0x79/0x1e0 [r8723bs] [ 363.140869] rtw_cfg80211_surveydone_event_callback+0x3cf/0x470 [r8723bs] [ 363.140973] rdev_scan+0x42/0x1a0 [cfg80211] [ 363.141307] nl80211_trigger_scan+0x566/0x660 [cfg80211] [ 363.141635] genl_family_rcv_msg_doit+0xcd/0x110 [ 363.141661] genl_rcv_msg+0xce/0x1c0 [ 363.141680] netlink_rcv_skb+0x50/0xf0 [ 363.141699] genl_rcv+0x24/0x40 [ 363.141717] netlink_unicast+0x16d/0x230 [ 363.141736] netlink_sendmsg+0x22b/0x450 [ 363.141755] sock_sendmsg+0x5e/0x60 [ 363.141781] ____sys_sendmsg+0x22f/0x270 [ 363.141803] ___sys_sendmsg+0x81/0xc0 [ 363.141828] __sys_sendmsg+0x49/0x80 [ 363.141851] do_syscall_64+0x3b/0x90 [ 363.141873] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 363.141895] -> #0 (&pmlmepriv->lock){+.-.}-{2:2}: [ 363.141930] __lock_acquire+0x1158/0x1de0 [ 363.141954] lock_acquire+0xb5/0x2b0 [ 363.141974] _raw_spin_lock_bh+0x34/0x40 [ 363.141993] _rtw_join_timeout_handler+0x3c/0x160 [r8723bs] [ 363.142097] call_timer_fn+0x94/0x260 [ 363.142122] __run_timers.part.0+0x1bf/0x290 [ 363.142147] run_timer_softirq+0x26/0x50 [ 363.142171] __do_softirq+0xde/0x485 [ 363.142193] __irq_exit_rcu+0xd0/0x100 [ 363.142215] irq_exit_rcu+0xa/0x20 [ 363.142235] sysvec_apic_timer_interrupt+0x72/0x90 [ 363.142260] asm_sysvec_apic_timer_interrupt+0x12/0x20 [ 363.142283] __module_address.part.0+0x0/0xd0 [ 363.142309] is_module_address+0x25/0x40 [ 363.142334] static_obj+0x4f/0x60 [ 363.142361] lockdep_init_map_type+0x47/0x220 [ 363.142382] __init_swait_queue_head+0x45/0x60 [ 363.142408] mmc_wait_for_req+0x4a/0xc0 [mmc_core] [ 363.142504] mmc_wait_for_cmd+0x55/0x70 [mmc_core] [ 363.142592] mmc_io_rw_direct+0x75/0xe0 [mmc_core] [ 363.142691] sdio_writeb+0x2e/0x50 [mmc_core] [ 363.142788] _sd_cmd52_write+0x62/0x80 [r8723bs] [ 363.142885] sd_cmd52_write+0x6c/0xb0 [r8723bs] [ 363.142981] rtl8723bs_set_hal_ops+0x982/0x9b0 [r8723bs] [ 363.143089] rtw_write16+0x1e/0x30 [r8723bs] [ 363.143184] SetHwReg8723B+0xcc9/0xd30 [r8723bs] [ 363.143294] mlmeext_joinbss_event_callback+0x17a/0x1a0 [r8723bs] [ 363.143405] rtw_joinbss_event_callback+0x11/0x20 [r8723bs] [ 363.143507] mlme_evt_hdl+0x4d/0x70 [r8723bs] [ 363.143620] rtw_cmd_thread+0x168/0x3c0 [r8723bs] [ 363.143712] kthread+0x143/0x160 [ 363.143732] ret_from_fork+0x22/0x30 [ 363.143757] other info that might help us debug this:
[ 363.143768] Chain exists of: &pmlmepriv->lock --> &pmlmepriv->scanned_queue.lock --> (&pmlmepriv->assoc_timer)
[ 363.143809] Possible unsafe locking scenario:
[ 363.143819] CPU0 CPU1 [ 363.143831] ---- ---- [ 363.143841] lock((&pmlmepriv->assoc_timer)); [ 363.143862] lock(&pmlmepriv->scanned_queue.lock); [ 363.143882] lock((&pmlmepriv->assoc_timer)); [ 363.143902] lock(&pmlmepriv->lock); [ 363.143921] *** DEADLOCK ***
Make rtw_joinbss_event_prehandle() release the scanned_queue.lock before it deletes the timer to avoid this (it is still holding pmlmepriv->lock protecting against racing the timer).
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20210920145502.155454-3-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/rtl8723bs/core/rtw_mlme.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index 1f49c49e10b45..cf79bec916c51 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -1234,16 +1234,13 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) rtw_indicate_connect(adapter); }
+ spin_unlock_bh(&pmlmepriv->scanned_queue.lock); + /* s5. Cancel assoc_timer */ del_timer_sync(&pmlmepriv->assoc_timer); - } else { spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); - goto ignore_joinbss_callback; } - - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); - } else if (pnetwork->join_res == -4) { rtw_reset_securitypriv(adapter); _set_timer(&pmlmepriv->assoc_timer, 1);
From: Christian Lamparter chunkeey@gmail.com
[ Upstream commit 6abc4ca5a28070945e0d68cb4160b309bfbf4b8b ]
the switch identifies itself as a BCM53012 (rev 5)... This patch has been tested & verified on OpenWrt's snapshot with Linux 5.10 (didn't test any older kernels). The MR32 is able to "talk to the network" as before with OpenWrt's SWITCHDEV b53 driver.
| b53-srab-switch 18007000.ethernet-switch: found switch: BCM53012, rev 5 | libphy: dsa slave smi: probed | b53-srab-switch 18007000.ethernet-switch poe (uninitialized): | PHY [dsa-0.0:00] driver [Generic PHY] (irq=POLL) | b53-srab-switch 18007000.ethernet-switch: Using legacy PHYLIB callbacks. | Please migrate to PHYLINK! | DSA: tree 0 setup
Reported-by: Rafał Miłecki zajec5@gmail.com Signed-off-by: Christian Lamparter chunkeey@gmail.com Signed-off-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts index 612d61852bfb9..577a4dc604d93 100644 --- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts +++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts @@ -195,3 +195,25 @@ }; }; }; + +&srab { + status = "okay"; + + ports { + port@0 { + reg = <0>; + label = "poe"; + }; + + port@5 { + reg = <5>; + label = "cpu"; + ethernet = <&gmac0>; + + fixed-link { + speed = <1000>; + duplex-full; + }; + }; + }; +};
From: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org
[ Upstream commit 3f1dcaff642e75c1d2ad03f783fa8a3b1f56dd50 ]
The entry/exit latency and minimum residency in state for the idle states of MSM8998 were ..bad: first of all, for all of them the timings were written for CPU sleep but the min-residency-us param was miscalculated (supposedly, while porting this from downstream); Then, the power collapse states are setting PC on both the CPU cluster *and* the L2 cache, which have different timings: in the specific case of L2 the times are higher so these ones should be taken into account instead of the CPU ones.
This parameter misconfiguration was not giving particular issues because on MSM8998 there was no CPU scaling at all, so cluster/L2 power collapse was rarely (if ever) hit. When CPU scaling is enabled, though, the wrong timings will produce SoC unstability shown to the user as random, apparently error-less, sudden reboots and/or lockups.
This set of parameters are stabilizing the SoC when CPU scaling is ON and when power collapse is frequently hit.
Signed-off-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210901183123.1087392-3-angelogioacchino.delregno... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8998.dtsi | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index 34039b5c80175..5a221cfc41387 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -308,38 +308,42 @@ LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 { compatible = "arm,idle-state"; idle-state-name = "little-retention"; + /* CPU Retention (C2D), L2 Active */ arm,psci-suspend-param = <0x00000002>; entry-latency-us = <81>; exit-latency-us = <86>; - min-residency-us = <200>; + min-residency-us = <504>; };
LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 { compatible = "arm,idle-state"; idle-state-name = "little-power-collapse"; + /* CPU + L2 Power Collapse (C3, D4) */ arm,psci-suspend-param = <0x40000003>; - entry-latency-us = <273>; - exit-latency-us = <612>; - min-residency-us = <1000>; + entry-latency-us = <814>; + exit-latency-us = <4562>; + min-residency-us = <9183>; local-timer-stop; };
BIG_CPU_SLEEP_0: cpu-sleep-1-0 { compatible = "arm,idle-state"; idle-state-name = "big-retention"; + /* CPU Retention (C2D), L2 Active */ arm,psci-suspend-param = <0x00000002>; entry-latency-us = <79>; exit-latency-us = <82>; - min-residency-us = <200>; + min-residency-us = <1302>; };
BIG_CPU_SLEEP_1: cpu-sleep-1-1 { compatible = "arm,idle-state"; idle-state-name = "big-power-collapse"; + /* CPU + L2 Power Collapse (C3, D4) */ arm,psci-suspend-param = <0x40000003>; - entry-latency-us = <336>; - exit-latency-us = <525>; - min-residency-us = <1000>; + entry-latency-us = <724>; + exit-latency-us = <2027>; + min-residency-us = <9419>; local-timer-stop; }; };
From: Shawn Guo shawn.guo@linaro.org
[ Upstream commit 3509de752ea14c7e5781b3a56a4a0bf832f5723a ]
Property qcom,controlled-remotely should be boolean. Fix it.
Signed-off-by: Shawn Guo shawn.guo@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210829111628.5543-2-shawn.guo@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi index d2fe58e0eb7aa..7b6205c180df1 100644 --- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -200,7 +200,7 @@ clock-names = "bam_clk"; #dma-cells = <1>; qcom,ee = <1>; - qcom,controlled-remotely = <1>; + qcom,controlled-remotely; qcom,config-pipe-trust-reg = <0>; };
From: Shawn Guo shawn.guo@linaro.org
[ Upstream commit 8c97f0ac4dc8f1743eb8e8a49f66189e13ae45e9 ]
Property qcom,controlled-remotely should be boolean. Fix it.
Signed-off-by: Shawn Guo shawn.guo@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210829111628.5543-3-shawn.guo@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/ipq8074.dtsi b/arch/arm64/boot/dts/qcom/ipq8074.dtsi index db333001df4d6..97f99663c132e 100644 --- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -220,7 +220,7 @@ clock-names = "bam_clk"; #dma-cells = <1>; qcom,ee = <1>; - qcom,controlled-remotely = <1>; + qcom,controlled-remotely; status = "disabled"; };
From: Shawn Guo shawn.guo@linaro.org
[ Upstream commit 1c8bf398b6b51eb085a49036ad8f9c000171cce1 ]
Property qcom,controlled-remotely should be boolean. Fix it.
Signed-off-by: Shawn Guo shawn.guo@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210829111628.5543-4-shawn.guo@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index a810adc1a707f..519ca9a705b4f 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -2320,7 +2320,7 @@ clock-names = "bam_clk"; #dma-cells = <1>; qcom,ee = <0>; - qcom,controlled-remotely = <1>; + qcom,controlled-remotely; iommus = <&apps_smmu 0x704 0x1>, <&apps_smmu 0x706 0x1>, <&apps_smmu 0x714 0x1>,
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 7a62bfebc8c94bdb6eb8f54f49889dc6b5b79601 ]
This fixes the following warning when building with W=1: Warning (unit_address_vs_reg): /soc: node has a reg or ranges property, but no unit name
Signed-off-by: Stephan Gerhold stephan@gerhold.net Reviewed-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210921152120.6710-1-stephan@gerhold.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index fbff712639513..519abec2430f0 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -414,7 +414,7 @@ }; };
- soc: soc { + soc: soc@0 { #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0 0xffffffff>;
From: Michael Walle michael@walle.cc
[ Upstream commit 99a7cacc66cae92db40139b57689be2af75fc6b8 ]
According to Documentation/devicetree/bindings/watchdog/arm,sp805.yaml the compatible is: compatible = "arm,sp805", "arm,primecell";
The current compatible string doesn't exist at all. Fix it.
Signed-off-by: Michael Walle michael@walle.cc Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 16 ++++++++-------- arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi index f85e437f80b73..6050723172436 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -847,7 +847,7 @@ };
cluster1_core0_watchdog: wdt@c000000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -857,7 +857,7 @@ };
cluster1_core1_watchdog: wdt@c010000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -867,7 +867,7 @@ };
cluster1_core2_watchdog: wdt@c020000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc020000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -877,7 +877,7 @@ };
cluster1_core3_watchdog: wdt@c030000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc030000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -887,7 +887,7 @@ };
cluster2_core0_watchdog: wdt@c100000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc100000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -897,7 +897,7 @@ };
cluster2_core1_watchdog: wdt@c110000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc110000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -907,7 +907,7 @@ };
cluster2_core2_watchdog: wdt@c120000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc120000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, @@ -917,7 +917,7 @@ };
cluster2_core3_watchdog: wdt@c130000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc130000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(16)>, diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index 801ba9612d361..1282b61da8a55 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -387,7 +387,7 @@ };
cluster1_core0_watchdog: wdt@c000000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -397,7 +397,7 @@ };
cluster1_core1_watchdog: wdt@c010000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -407,7 +407,7 @@ };
cluster2_core0_watchdog: wdt@c100000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc100000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -417,7 +417,7 @@ };
cluster2_core1_watchdog: wdt@c110000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc110000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -427,7 +427,7 @@ };
cluster3_core0_watchdog: wdt@c200000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc200000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -437,7 +437,7 @@ };
cluster3_core1_watchdog: wdt@c210000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc210000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -447,7 +447,7 @@ };
cluster4_core0_watchdog: wdt@c300000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc300000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>, @@ -457,7 +457,7 @@ };
cluster4_core1_watchdog: wdt@c310000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc310000 0x0 0x1000>; clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL QORIQ_CLK_PLL_DIV(4)>,
From: Kuldeep Singh kuldeep.singh@nxp.com
[ Upstream commit 7f31ae6e01da140e34d6513815253e811019f016 ]
U-boot atempts to read serial alias value for ls1012a-rdb but couldn't do so as it is not initialised and thus, FDT_ERR_NOTFOUND error is reported while booting linux.
Loading fdt from FIT Image at a0000000 ... Description: ls1012ardb-dtb Type: Flat Device Tree Data Start: 0xab111474 Data Size: 11285 Bytes = 11 KiB Architecture: AArch64 Load Address: 0x90000000 Loading fdt from 0xab111474 to 0x90000000 Booting using the fdt blob at 0x90000000 Uncompressing Kernel Image Loading Device Tree to 000000008fffa000, end 000000008ffffc14 ... OK WARNING: fdt_fixup_stdout: could not read serial0 alias: FDT_ERR_NOTFOUND NOTICE: RNG: INSTANTIATED
Starting kernel ...
Fix the above error by specifying serial value to duart.
Signed-off-by: Kuldeep Singh kuldeep.singh@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts index 79f155dedb2d0..e662677a6e28f 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts @@ -15,6 +15,7 @@ compatible = "fsl,ls1012a-rdb", "fsl,ls1012a";
aliases { + serial0 = &duart0; mmc0 = &esdhc0; mmc1 = &esdhc1; };
From: Bob Pearson rpearsonhpe@gmail.com
[ Upstream commit 001345339f4ca85790a1644a74e33ae77ac116be ]
Separate software and simulated hardware lkeys and rkeys for MRs and MWs. This makes struct ib_mr and struct ib_mw isolated from hardware changes triggered by executing work requests.
This change fixes a bug seen in blktest.
Link: https://lore.kernel.org/r/20210914164206.19768-4-rpearsonhpe@gmail.com Signed-off-by: Bob Pearson rpearsonhpe@gmail.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/sw/rxe/rxe_loc.h | 1 + drivers/infiniband/sw/rxe/rxe_mr.c | 69 ++++++++++++++++++++++----- drivers/infiniband/sw/rxe/rxe_mw.c | 30 ++++++------ drivers/infiniband/sw/rxe/rxe_req.c | 14 ++---- drivers/infiniband/sw/rxe/rxe_verbs.h | 18 ++----- 5 files changed, 81 insertions(+), 51 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index f0c954575bdec..4fd73b51fabf2 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -86,6 +86,7 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length); int advance_dma_data(struct rxe_dma_info *dma, unsigned int length); int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey); +int rxe_reg_fast_mr(struct rxe_qp *qp, struct rxe_send_wqe *wqe); int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata); void rxe_mr_cleanup(struct rxe_pool_entry *arg);
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index 5890a82462161..bedcf15aaea75 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -48,8 +48,14 @@ static void rxe_mr_init(int access, struct rxe_mr *mr) u32 lkey = mr->pelem.index << 8 | rxe_get_next_key(-1); u32 rkey = (access & IB_ACCESS_REMOTE) ? lkey : 0;
- mr->ibmr.lkey = lkey; - mr->ibmr.rkey = rkey; + /* set ibmr->l/rkey and also copy into private l/rkey + * for user MRs these will always be the same + * for cases where caller 'owns' the key portion + * they may be different until REG_MR WQE is executed. + */ + mr->lkey = mr->ibmr.lkey = lkey; + mr->rkey = mr->ibmr.rkey = rkey; + mr->state = RXE_MR_STATE_INVALID; mr->type = RXE_MR_TYPE_NONE; mr->map_shift = ilog2(RXE_BUF_PER_MAP); @@ -191,10 +197,8 @@ int rxe_mr_init_fast(struct rxe_pd *pd, int max_pages, struct rxe_mr *mr) { int err;
- rxe_mr_init(0, mr); - - /* In fastreg, we also set the rkey */ - mr->ibmr.rkey = mr->ibmr.lkey; + /* always allow remote access for FMRs */ + rxe_mr_init(IB_ACCESS_REMOTE, mr);
err = rxe_mr_alloc(mr, max_pages); if (err) @@ -507,8 +511,8 @@ struct rxe_mr *lookup_mr(struct rxe_pd *pd, int access, u32 key, if (!mr) return NULL;
- if (unlikely((type == RXE_LOOKUP_LOCAL && mr_lkey(mr) != key) || - (type == RXE_LOOKUP_REMOTE && mr_rkey(mr) != key) || + if (unlikely((type == RXE_LOOKUP_LOCAL && mr->lkey != key) || + (type == RXE_LOOKUP_REMOTE && mr->rkey != key) || mr_pd(mr) != pd || (access && !(access & mr->access)) || mr->state != RXE_MR_STATE_VALID)) { rxe_drop_ref(mr); @@ -531,9 +535,9 @@ int rxe_invalidate_mr(struct rxe_qp *qp, u32 rkey) goto err; }
- if (rkey != mr->ibmr.rkey) { - pr_err("%s: rkey (%#x) doesn't match mr->ibmr.rkey (%#x)\n", - __func__, rkey, mr->ibmr.rkey); + if (rkey != mr->rkey) { + pr_err("%s: rkey (%#x) doesn't match mr->rkey (%#x)\n", + __func__, rkey, mr->rkey); ret = -EINVAL; goto err_drop_ref; } @@ -554,6 +558,49 @@ err: return ret; }
+/* user can (re)register fast MR by executing a REG_MR WQE. + * user is expected to hold a reference on the ib mr until the + * WQE completes. + * Once a fast MR is created this is the only way to change the + * private keys. It is the responsibility of the user to maintain + * the ib mr keys in sync with rxe mr keys. + */ +int rxe_reg_fast_mr(struct rxe_qp *qp, struct rxe_send_wqe *wqe) +{ + struct rxe_mr *mr = to_rmr(wqe->wr.wr.reg.mr); + u32 key = wqe->wr.wr.reg.key; + u32 access = wqe->wr.wr.reg.access; + + /* user can only register MR in free state */ + if (unlikely(mr->state != RXE_MR_STATE_FREE)) { + pr_warn("%s: mr->lkey = 0x%x not free\n", + __func__, mr->lkey); + return -EINVAL; + } + + /* user can only register mr with qp in same protection domain */ + if (unlikely(qp->ibqp.pd != mr->ibmr.pd)) { + pr_warn("%s: qp->pd and mr->pd don't match\n", + __func__); + return -EINVAL; + } + + /* user is only allowed to change key portion of l/rkey */ + if (unlikely((mr->lkey & ~0xff) != (key & ~0xff))) { + pr_warn("%s: key = 0x%x has wrong index mr->lkey = 0x%x\n", + __func__, key, mr->lkey); + return -EINVAL; + } + + mr->access = access; + mr->lkey = key; + mr->rkey = (access & IB_ACCESS_REMOTE) ? key : 0; + mr->iova = wqe->wr.wr.reg.mr->iova; + mr->state = RXE_MR_STATE_VALID; + + return 0; +} + int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) { struct rxe_mr *mr = to_rmr(ibmr); diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c index 5ba77df7598ed..a5e2ea7d80f02 100644 --- a/drivers/infiniband/sw/rxe/rxe_mw.c +++ b/drivers/infiniband/sw/rxe/rxe_mw.c @@ -21,7 +21,7 @@ int rxe_alloc_mw(struct ib_mw *ibmw, struct ib_udata *udata) }
rxe_add_index(mw); - ibmw->rkey = (mw->pelem.index << 8) | rxe_get_next_key(-1); + mw->rkey = ibmw->rkey = (mw->pelem.index << 8) | rxe_get_next_key(-1); mw->state = (mw->ibmw.type == IB_MW_TYPE_2) ? RXE_MW_STATE_FREE : RXE_MW_STATE_VALID; spin_lock_init(&mw->lock); @@ -71,6 +71,8 @@ int rxe_dealloc_mw(struct ib_mw *ibmw) static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, struct rxe_mw *mw, struct rxe_mr *mr) { + u32 key = wqe->wr.wr.mw.rkey & 0xff; + if (mw->ibmw.type == IB_MW_TYPE_1) { if (unlikely(mw->state != RXE_MW_STATE_VALID)) { pr_err_once( @@ -108,7 +110,7 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, } }
- if (unlikely((wqe->wr.wr.mw.rkey & 0xff) == (mw->ibmw.rkey & 0xff))) { + if (unlikely(key == (mw->rkey & 0xff))) { pr_err_once("attempt to bind MW with same key\n"); return -EINVAL; } @@ -161,13 +163,9 @@ static int rxe_check_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, static void rxe_do_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe, struct rxe_mw *mw, struct rxe_mr *mr) { - u32 rkey; - u32 new_rkey; - - rkey = mw->ibmw.rkey; - new_rkey = (rkey & 0xffffff00) | (wqe->wr.wr.mw.rkey & 0x000000ff); + u32 key = wqe->wr.wr.mw.rkey & 0xff;
- mw->ibmw.rkey = new_rkey; + mw->rkey = (mw->rkey & ~0xff) | key; mw->access = wqe->wr.wr.mw.access; mw->state = RXE_MW_STATE_VALID; mw->addr = wqe->wr.wr.mw.addr; @@ -197,29 +195,29 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe) struct rxe_mw *mw; struct rxe_mr *mr; struct rxe_dev *rxe = to_rdev(qp->ibqp.device); + u32 mw_rkey = wqe->wr.wr.mw.mw_rkey; + u32 mr_lkey = wqe->wr.wr.mw.mr_lkey; unsigned long flags;
- mw = rxe_pool_get_index(&rxe->mw_pool, - wqe->wr.wr.mw.mw_rkey >> 8); + mw = rxe_pool_get_index(&rxe->mw_pool, mw_rkey >> 8); if (unlikely(!mw)) { ret = -EINVAL; goto err; }
- if (unlikely(mw->ibmw.rkey != wqe->wr.wr.mw.mw_rkey)) { + if (unlikely(mw->rkey != mw_rkey)) { ret = -EINVAL; goto err_drop_mw; }
if (likely(wqe->wr.wr.mw.length)) { - mr = rxe_pool_get_index(&rxe->mr_pool, - wqe->wr.wr.mw.mr_lkey >> 8); + mr = rxe_pool_get_index(&rxe->mr_pool, mr_lkey >> 8); if (unlikely(!mr)) { ret = -EINVAL; goto err_drop_mw; }
- if (unlikely(mr->ibmr.lkey != wqe->wr.wr.mw.mr_lkey)) { + if (unlikely(mr->lkey != mr_lkey)) { ret = -EINVAL; goto err_drop_mr; } @@ -292,7 +290,7 @@ int rxe_invalidate_mw(struct rxe_qp *qp, u32 rkey) goto err; }
- if (rkey != mw->ibmw.rkey) { + if (rkey != mw->rkey) { ret = -EINVAL; goto err_drop_ref; } @@ -323,7 +321,7 @@ struct rxe_mw *rxe_lookup_mw(struct rxe_qp *qp, int access, u32 rkey) if (!mw) return NULL;
- if (unlikely((rxe_mw_rkey(mw) != rkey) || rxe_mw_pd(mw) != pd || + if (unlikely((mw->rkey != rkey) || rxe_mw_pd(mw) != pd || (mw->ibmw.type == IB_MW_TYPE_2 && mw->qp != qp) || (mw->length == 0) || (access && !(access & mw->access)) || diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index 3894197a82f62..fc996fd31e589 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -572,7 +572,6 @@ static void update_state(struct rxe_qp *qp, struct rxe_send_wqe *wqe, static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) { u8 opcode = wqe->wr.opcode; - struct rxe_mr *mr; u32 rkey; int ret;
@@ -590,14 +589,11 @@ static int rxe_do_local_ops(struct rxe_qp *qp, struct rxe_send_wqe *wqe) } break; case IB_WR_REG_MR: - mr = to_rmr(wqe->wr.wr.reg.mr); - rxe_add_ref(mr); - mr->state = RXE_MR_STATE_VALID; - mr->access = wqe->wr.wr.reg.access; - mr->ibmr.lkey = wqe->wr.wr.reg.key; - mr->ibmr.rkey = wqe->wr.wr.reg.key; - mr->iova = wqe->wr.wr.reg.mr->iova; - rxe_drop_ref(mr); + ret = rxe_reg_fast_mr(qp, wqe); + if (unlikely(ret)) { + wqe->status = IB_WC_LOC_QP_OP_ERR; + return ret; + } break; case IB_WR_BIND_MW: ret = rxe_bind_mw(qp, wqe); diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index ac2a2148027f4..d90b1d77de347 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -313,6 +313,8 @@ struct rxe_mr {
struct ib_umem *umem;
+ u32 lkey; + u32 rkey; enum rxe_mr_state state; enum rxe_mr_type type; u64 va; @@ -350,6 +352,7 @@ struct rxe_mw { enum rxe_mw_state state; struct rxe_qp *qp; /* Type 2 only */ struct rxe_mr *mr; + u32 rkey; int access; u64 addr; u64 length; @@ -474,26 +477,11 @@ static inline struct rxe_pd *mr_pd(struct rxe_mr *mr) return to_rpd(mr->ibmr.pd); }
-static inline u32 mr_lkey(struct rxe_mr *mr) -{ - return mr->ibmr.lkey; -} - -static inline u32 mr_rkey(struct rxe_mr *mr) -{ - return mr->ibmr.rkey; -} - static inline struct rxe_pd *rxe_mw_pd(struct rxe_mw *mw) { return to_rpd(mw->ibmw.pd); }
-static inline u32 rxe_mw_rkey(struct rxe_mw *mw) -{ - return mw->ibmw.rkey; -} - int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name);
void rxe_mc_cleanup(struct rxe_pool_entry *arg);
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit a20f3b10de61add5e14b6ce4df982f4df2a4cbbc ]
The initial hdac_stream code was adapted a third time with the same locking issues. Move the spin_lock outside the loops and make sure the fields are protected on read/write.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Acked-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20210924192417.169243-5-pierre-louis.bossart@linux... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/intel/hda-dai.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index c1f9f0f584647..6704dbcd101cd 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -68,6 +68,7 @@ static struct hdac_ext_stream * return NULL; }
+ spin_lock_irq(&bus->reg_lock); list_for_each_entry(stream, &bus->stream_list, list) { struct hdac_ext_stream *hstream = stream_to_hdac_ext_stream(stream); @@ -107,12 +108,12 @@ static struct hdac_ext_stream * * is updated in snd_hdac_ext_stream_decouple(). */ if (!res->decoupled) - snd_hdac_ext_stream_decouple(bus, res, true); - spin_lock_irq(&bus->reg_lock); + snd_hdac_ext_stream_decouple_locked(bus, res, true); + res->link_locked = 1; res->link_substream = substream; - spin_unlock_irq(&bus->reg_lock); } + spin_unlock_irq(&bus->reg_lock);
return res; }
From: Damien Le Moal damien.lemoal@wdc.com
[ Upstream commit 17b49bcbf8351d3dbe57204468ac34f033ed60bc ]
Several problems exist with scsi_mode_sense() buffer length handling:
1) The allocation length field of the MODE SENSE(10) command is 16-bits, occupying bytes 7 and 8 of the CDB. With this command, access to mode pages larger than 255 bytes is thus possible. However, the CDB allocation length field is set by assigning len to byte 8 only, thus truncating buffer length larger than 255.
2) If scsi_mode_sense() is called with len smaller than 8 with sdev->use_10_for_ms set, or smaller than 4 otherwise, the buffer length is increased to 8 and 4 respectively, and the buffer is zero filled with these increased values, thus corrupting the memory following the buffer.
Fix these 2 problems by using put_unaligned_be16() to set the allocation length field of MODE SENSE(10) CDB and by returning an error when len is too small.
Furthermore, if len is larger than 255B, always try MODE SENSE(10) first, even if the device driver did not set sdev->use_10_for_ms. In case of invalid opcode error for MODE SENSE(10), access to mode pages larger than 255 bytes are not retried using MODE SENSE(6). To avoid buffer length overflows for the MODE_SENSE(10) case, check that len is smaller than 65535 bytes.
While at it, also fix the folowing:
* Use get_unaligned_be16() to retrieve the mode data length and block descriptor length fields of the mode sense reply header instead of using an open coded calculation.
* Fix the kdoc dbd argument explanation: the DBD bit stands for Disable Block Descriptor, which is the opposite of what the dbd argument description was.
Link: https://lore.kernel.org/r/20210820070255.682775-2-damien.lemoal@wdc.com Signed-off-by: Damien Le Moal damien.lemoal@wdc.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_lib.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 0e023547ff15a..ef4361b2d1423 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2074,7 +2074,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select); /** * scsi_mode_sense - issue a mode sense, falling back from 10 to six bytes if necessary. * @sdev: SCSI device to be queried - * @dbd: set if mode sense will allow block descriptors to be returned + * @dbd: set to prevent mode sense from returning block descriptors * @modepage: mode page being requested * @buffer: request buffer (may not be smaller than eight bytes) * @len: length of request buffer. @@ -2109,18 +2109,18 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, sshdr = &my_sshdr;
retry: - use_10_for_ms = sdev->use_10_for_ms; + use_10_for_ms = sdev->use_10_for_ms || len > 255;
if (use_10_for_ms) { - if (len < 8) - len = 8; + if (len < 8 || len > 65535) + return -EINVAL;
cmd[0] = MODE_SENSE_10; - cmd[8] = len; + put_unaligned_be16(len, &cmd[7]); header_length = 8; } else { if (len < 4) - len = 4; + return -EINVAL;
cmd[0] = MODE_SENSE; cmd[4] = len; @@ -2144,9 +2144,15 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, if ((sshdr->sense_key == ILLEGAL_REQUEST) && (sshdr->asc == 0x20) && (sshdr->ascq == 0)) { /* - * Invalid command operation code + * Invalid command operation code: retry using + * MODE SENSE(6) if this was a MODE SENSE(10) + * request, except if the request mode page is + * too large for MODE SENSE single byte + * allocation length field. */ if (use_10_for_ms) { + if (len > 255) + return -EIO; sdev->use_10_for_ms = 0; goto retry; } @@ -2170,12 +2176,11 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, data->longlba = 0; data->block_descriptor_length = 0; } else if (use_10_for_ms) { - data->length = buffer[0]*256 + buffer[1] + 2; + data->length = get_unaligned_be16(&buffer[0]) + 2; data->medium_type = buffer[2]; data->device_specific = buffer[3]; data->longlba = buffer[4] & 0x01; - data->block_descriptor_length = buffer[6]*256 - + buffer[7]; + data->block_descriptor_length = get_unaligned_be16(&buffer[6]); } else { data->length = buffer[0] + 1; data->medium_type = buffer[1];
From: Geraldo Nascimento geraldogabriel@gmail.com
[ Upstream commit 28c369e60827f706cef4604a3e2848198f25bd26 ]
Behringer UFX1204 and UFX1604 have Synchronous endpoints to which current ALSA code applies implicit feedback sync as if they were Asynchronous endpoints. This breaks UAC compliance and is unneeded.
The commit 5e35dc0338d85ccebacf3f77eca1e5dea73155e8 and subsequent 1a15718b41df026cffd0e42cfdc38a1384ce19f9 were meant to clear up noise.
Unfortunately, noise persisted for those using higher sample rates and this was only solved by commit d2e8f641257d0d3af6e45d6ac2d6f9d56b8ea964
Since there are no more reports of noise, let's get rid of the implicit-fb quirks breaking UAC compliance.
Signed-off-by: Geraldo Nascimento geraldogabriel@gmail.com Link: https://lore.kernel.org/r/YVYSnoQ7nxLXT0Dq@geday Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/implicit.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c index 23767a14d1266..70319c822c10b 100644 --- a/sound/usb/implicit.c +++ b/sound/usb/implicit.c @@ -54,8 +54,6 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
/* Fixed EP */ /* FIXME: check the availability of generic matching */ - IMPLICIT_FB_FIXED_DEV(0x1397, 0x0001, 0x81, 1), /* Behringer UFX1604 */ - IMPLICIT_FB_FIXED_DEV(0x1397, 0x0002, 0x81, 1), /* Behringer UFX1204 */ IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */ IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0001, 0x81, 2), /* Solid State Logic SSL2 */ IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */
From: Stefan Riedmueller s.riedmueller@phytec.de
[ Upstream commit 2f9d61869640f732599ec36b984c2b5c46067519 ]
The csi_sel mux register is located in the CCM register base and not the CCM_ANALOG register base. So move it to the correct position in code.
Otherwise changing the parent of the csi clock can lead to a complete system failure due to the CCM_ANALOG_PLL_SYS_TOG register being falsely modified.
Also remove the SET_RATE_PARENT flag since one possible supply for the csi_sel mux is the system PLL which we don't want to modify.
Signed-off-by: Stefan Riedmueller s.riedmueller@phytec.de Reviewed-by: Abel Vesa abel.vesa@nxp.com Link: https://lore.kernel.org/r/20210927072857.3940880-1-s.riedmueller@phytec.de Signed-off-by: Abel Vesa abel.vesa@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/imx/clk-imx6ul.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 5dbb6a9377324..206e4c43f68f8 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -161,7 +161,6 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); hws[IMX6UL_PLL6_BYPASS] = imx_clk_hw_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); hws[IMX6UL_PLL7_BYPASS] = imx_clk_hw_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); - hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT);
/* Do not bypass PLLs initially */ clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk); @@ -270,6 +269,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) hws[IMX6UL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); hws[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_hw_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT); hws[IMX6UL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); + hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
hws[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); hws[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels));
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 1cf2aa665901054b140eb71748661ceae99b6b5a ]
Use the new IRQF_NO_AUTOEN flag when requesting the IRQ, rather then disabling it immediately after requesting it.
This fixes a possible race where the IRQ might trigger between requesting and disabling it; and this also leads to a small code cleanup.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20211003132255.31743-1-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/es8316.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/es8316.c b/sound/soc/codecs/es8316.c index 067757d1d70a3..5fb02635c1406 100644 --- a/sound/soc/codecs/es8316.c +++ b/sound/soc/codecs/es8316.c @@ -811,12 +811,9 @@ static int es8316_i2c_probe(struct i2c_client *i2c_client, mutex_init(&es8316->lock);
ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, "es8316", es8316); - if (ret == 0) { - /* Gets re-enabled by es8316_set_jack() */ - disable_irq(es8316->irq); - } else { + if (ret) { dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret); es8316->irq = -ENXIO; }
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 6e037b72cf4ea6c28a131ea021d63ee4e7e6fa64 ]
Use the new IRQF_NO_AUTOEN flag when requesting the IRQ, rather then disabling it immediately after requesting it.
This fixes a possible race where the IRQ might trigger between requesting and disabling it; and this also leads to a small code cleanup.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20211003132255.31743-2-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt5651.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c index fc0c83b73f099..93820561b9f5d 100644 --- a/sound/soc/codecs/rt5651.c +++ b/sound/soc/codecs/rt5651.c @@ -2261,11 +2261,8 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
ret = devm_request_irq(&i2c->dev, rt5651->irq, rt5651_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING - | IRQF_ONESHOT, "rt5651", rt5651); - if (ret == 0) { - /* Gets re-enabled by rt5651_set_jack() */ - disable_irq(rt5651->irq); - } else { + | IRQF_ONESHOT | IRQF_NO_AUTOEN, "rt5651", rt5651); + if (ret) { dev_warn(&i2c->dev, "Failed to reguest IRQ %d: %d\n", rt5651->irq, ret); rt5651->irq = -ENXIO;
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 92d3360108f1839ca40451bad20ff67dd24a1964 ]
Add a quirk mechanism to allow specifying that active-high jack-detection should be used on platforms where this info is not available in devicetree.
And add an entry for the Cyberbook T116 tablet to the DMI table, so that jack-detection will work properly on this tablet.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20211002211459.110124-2-hdegoede@redhat.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/nau8824.c | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index f946ef65a4c19..f7018f2dd21fd 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c @@ -8,6 +8,7 @@
#include <linux/module.h> #include <linux/delay.h> +#include <linux/dmi.h> #include <linux/init.h> #include <linux/i2c.h> #include <linux/regmap.h> @@ -27,6 +28,12 @@
#include "nau8824.h"
+#define NAU8824_JD_ACTIVE_HIGH BIT(0) + +static int nau8824_quirk; +static int quirk_override = -1; +module_param_named(quirk, quirk_override, uint, 0444); +MODULE_PARM_DESC(quirk, "Board-specific quirk override");
static int nau8824_config_sysclk(struct nau8824 *nau8824, int clk_id, unsigned int freq); @@ -1845,6 +1852,34 @@ static int nau8824_read_device_properties(struct device *dev, return 0; }
+/* Please keep this list alphabetically sorted */ +static const struct dmi_system_id nau8824_quirk_table[] = { + { + /* Cyberbook T116 rugged tablet */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "20170531"), + }, + .driver_data = (void *)(NAU8824_JD_ACTIVE_HIGH), + }, + {} +}; + +static void nau8824_check_quirks(void) +{ + const struct dmi_system_id *dmi_id; + + if (quirk_override != -1) { + nau8824_quirk = quirk_override; + return; + } + + dmi_id = dmi_first_match(nau8824_quirk_table); + if (dmi_id) + nau8824_quirk = (unsigned long)dmi_id->driver_data; +} + static int nau8824_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -1869,6 +1904,11 @@ static int nau8824_i2c_probe(struct i2c_client *i2c, nau8824->irq = i2c->irq; sema_init(&nau8824->jd_sem, 1);
+ nau8824_check_quirks(); + + if (nau8824_quirk & NAU8824_JD_ACTIVE_HIGH) + nau8824->jkdet_polarity = 0; + nau8824_print_device_properties(nau8824);
ret = regmap_read(nau8824->regmap, NAU8824_REG_I2C_DEVICE_ID, &value);
From: Guo Zhi qtxuning1999@sjtu.edu.cn
[ Upstream commit d4996c6eac4c81b8872043e9391563f67f13e406 ]
Pointers should be printed with %p or %px rather than cast to 'unsigned long' and printed with %lx.
Change %lx to %p to print the hashed pointer.
Link: https://lore.kernel.org/r/20210929122538.1158235-1-qtxuning1999@sjtu.edu.cn Signed-off-by: Guo Zhi qtxuning1999@sjtu.edu.cn Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/advansys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ffb3919675734..97be0765cb9bd 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -3308,8 +3308,8 @@ static void asc_prt_adv_board_info(struct seq_file *m, struct Scsi_Host *shost) shost->host_no);
seq_printf(m, - " iop_base 0x%lx, cable_detect: %X, err_code %u\n", - (unsigned long)v->iop_base, + " iop_base 0x%p, cable_detect: %X, err_code %u\n", + v->iop_base, AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT, v->err_code);
From: Mahesh Rajashekhara mahesh.rajashekhara@microchip.com
[ Upstream commit 9ee5d6e9ac52a3c8625697535f8e35864d9fd38c ]
Correct kdump hangs when controller is locked up.
There are occasions when a controller reboot (controller soft reset) is issued when a controller firmware crash dump is in progress.
This leads to incomplete controller firmware crash dump:
- When the controller crash dump is in progress, and a kdump is initiated, the driver issues inbound doorbell reset to bring back the controller in SIS mode.
- If the controller is in locked up state, the inbound doorbell reset does not work causing controller initialization failures. This results in the driver hanging waiting for SIS mode.
To avoid an incomplete controller crash dump, add in a controller crash dump handshake:
- Controller will indicate start and end of the controller crash dump by setting some register bits.
- Driver will look these bits when a kdump is initiated. If a controller crash dump is in progress, the driver will wait for the controller crash dump to complete before issuing the controller soft reset then complete driver initialization.
Link: https://lore.kernel.org/r/20210928235442.201875-3-don.brace@microchip.com Reviewed-by: Scott Benesh scott.benesh@microchip.com Reviewed-by: Scott Teel scott.teel@microchip.com Reviewed-by: Mike McGowen mike.mcgowen@microchip.com Acked-by: John Donnelly john.p.donnelly@oracle.com Signed-off-by: Mahesh Rajashekhara mahesh.rajashekhara@microchip.com Signed-off-by: Don Brace don.brace@microchip.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/smartpqi/smartpqi_init.c | 41 +++++++++++++++++++-- drivers/scsi/smartpqi/smartpqi_sis.c | 51 +++++++++++++++++++++++++++ drivers/scsi/smartpqi/smartpqi_sis.h | 1 + 3 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index ecb2af3f43ca3..a5453f5e87c3e 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -234,15 +234,46 @@ static inline bool pqi_is_hba_lunid(u8 *scsi3addr) return pqi_scsi3addr_equal(scsi3addr, RAID_CTLR_LUNID); }
+#define PQI_DRIVER_SCRATCH_PQI_MODE 0x1 +#define PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED 0x2 + static inline enum pqi_ctrl_mode pqi_get_ctrl_mode(struct pqi_ctrl_info *ctrl_info) { - return sis_read_driver_scratch(ctrl_info); + return sis_read_driver_scratch(ctrl_info) & PQI_DRIVER_SCRATCH_PQI_MODE ? PQI_MODE : SIS_MODE; }
static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info, enum pqi_ctrl_mode mode) { - sis_write_driver_scratch(ctrl_info, mode); + u32 driver_scratch; + + driver_scratch = sis_read_driver_scratch(ctrl_info); + + if (mode == PQI_MODE) + driver_scratch |= PQI_DRIVER_SCRATCH_PQI_MODE; + else + driver_scratch &= ~PQI_DRIVER_SCRATCH_PQI_MODE; + + sis_write_driver_scratch(ctrl_info, driver_scratch); +} + +static inline bool pqi_is_fw_triage_supported(struct pqi_ctrl_info *ctrl_info) +{ + return (sis_read_driver_scratch(ctrl_info) & PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED) != 0; +} + +static inline void pqi_save_fw_triage_setting(struct pqi_ctrl_info *ctrl_info, bool is_supported) +{ + u32 driver_scratch; + + driver_scratch = sis_read_driver_scratch(ctrl_info); + + if (is_supported) + driver_scratch |= PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED; + else + driver_scratch &= ~PQI_DRIVER_SCRATCH_FW_TRIAGE_SUPPORTED; + + sis_write_driver_scratch(ctrl_info, driver_scratch); }
static inline void pqi_ctrl_block_scan(struct pqi_ctrl_info *ctrl_info) @@ -7301,6 +7332,7 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, ctrl_info->unique_wwid_in_report_phys_lun_supported = firmware_feature->enabled; break; + pqi_save_fw_triage_setting(ctrl_info, firmware_feature->enabled); }
pqi_firmware_feature_status(ctrl_info, firmware_feature); @@ -7627,6 +7659,11 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) u32 product_id;
if (reset_devices) { + if (pqi_is_fw_triage_supported(ctrl_info)) { + rc = sis_wait_for_fw_triage_completion(ctrl_info); + if (rc) + return rc; + } sis_soft_reset(ctrl_info); msleep(PQI_POST_RESET_DELAY_SECS * PQI_HZ); } else { diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index d63c46a8e38bb..8acd3a80f5822 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -51,12 +51,20 @@ #define SIS_BASE_STRUCT_REVISION 9 #define SIS_BASE_STRUCT_ALIGNMENT 16
+#define SIS_CTRL_KERNEL_FW_TRIAGE 0x3 #define SIS_CTRL_KERNEL_UP 0x80 #define SIS_CTRL_KERNEL_PANIC 0x100 #define SIS_CTRL_READY_TIMEOUT_SECS 180 #define SIS_CTRL_READY_RESUME_TIMEOUT_SECS 90 #define SIS_CTRL_READY_POLL_INTERVAL_MSECS 10
+enum sis_fw_triage_status { + FW_TRIAGE_NOT_STARTED = 0, + FW_TRIAGE_STARTED, + FW_TRIAGE_COND_INVALID, + FW_TRIAGE_COMPLETED +}; + #pragma pack(1)
/* for use with SIS_CMD_INIT_BASE_STRUCT_ADDRESS command */ @@ -419,12 +427,55 @@ u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info) return readl(&ctrl_info->registers->sis_driver_scratch); }
+static inline enum sis_fw_triage_status + sis_read_firmware_triage_status(struct pqi_ctrl_info *ctrl_info) +{ + return ((enum sis_fw_triage_status)(readl(&ctrl_info->registers->sis_firmware_status) & + SIS_CTRL_KERNEL_FW_TRIAGE)); +} + void sis_soft_reset(struct pqi_ctrl_info *ctrl_info) { writel(SIS_SOFT_RESET, &ctrl_info->registers->sis_host_to_ctrl_doorbell); }
+#define SIS_FW_TRIAGE_STATUS_TIMEOUT_SECS 300 +#define SIS_FW_TRIAGE_STATUS_POLL_INTERVAL_SECS 1 + +int sis_wait_for_fw_triage_completion(struct pqi_ctrl_info *ctrl_info) +{ + int rc; + enum sis_fw_triage_status status; + unsigned long timeout; + + timeout = (SIS_FW_TRIAGE_STATUS_TIMEOUT_SECS * PQI_HZ) + jiffies; + while (1) { + status = sis_read_firmware_triage_status(ctrl_info); + if (status == FW_TRIAGE_COND_INVALID) { + dev_err(&ctrl_info->pci_dev->dev, + "firmware triage condition invalid\n"); + rc = -EINVAL; + break; + } else if (status == FW_TRIAGE_NOT_STARTED || + status == FW_TRIAGE_COMPLETED) { + rc = 0; + break; + } + + if (time_after(jiffies, timeout)) { + dev_err(&ctrl_info->pci_dev->dev, + "timed out waiting for firmware triage status\n"); + rc = -ETIMEDOUT; + break; + } + + ssleep(SIS_FW_TRIAGE_STATUS_POLL_INTERVAL_SECS); + } + + return rc; +} + static void __attribute__((unused)) verify_structures(void) { BUILD_BUG_ON(offsetof(struct sis_base_struct, diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index d29c1352a826a..c1db93054c863 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -28,5 +28,6 @@ void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value); u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info); void sis_soft_reset(struct pqi_ctrl_info *ctrl_info); u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info); +int sis_wait_for_fw_triage_completion(struct pqi_ctrl_info *ctrl_info);
#endif /* _SMARTPQI_SIS_H */
From: Frieder Schrempf frieder.schrempf@kontron.de
[ Upstream commit 315e7b884190a6c9c28e95ad3b724dde9e922b99 ]
According to the datasheet the VSC8531 PHY expects a reset pulse of 100 ns and a delay of 15 ms after the reset has been deasserted. Set the matching values in the devicetree.
Reported-by: Heiko Thiery heiko.thiery@gmail.com Signed-off-by: Frieder Schrempf frieder.schrempf@kontron.de Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts index e99e7644ff392..49d7470812eef 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-n801x-s.dts @@ -123,8 +123,8 @@
ethphy: ethernet-phy@0 { reg = <0>; - reset-assert-us = <100>; - reset-deassert-us = <100>; + reset-assert-us = <1>; + reset-deassert-us = <15000>; reset-gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; }; };
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 9d36ceab94151f07cf3fcb067213ac87937adf12 ]
These devices are based on an I2C/I2S device, we need to force the use of the SOF driver otherwise the legacy HDaudio driver will be loaded - only HDMI will be supported.
Co-developed-by: Huajun Li huajun.li@intel.com Signed-off-by: Huajun Li huajun.li@intel.com Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Link: https://lore.kernel.org/r/20211004213512.220836-3-pierre-louis.bossart@linux... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/hda/intel-dsp-config.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/sound/hda/intel-dsp-config.c b/sound/hda/intel-dsp-config.c index c9d0ba353463b..b9ac9e9e45a48 100644 --- a/sound/hda/intel-dsp-config.c +++ b/sound/hda/intel-dsp-config.c @@ -31,6 +31,7 @@ struct config_entry { u16 device; u8 acpi_hid[ACPI_ID_LEN]; const struct dmi_system_id *dmi_table; + u8 codec_hid[ACPI_ID_LEN]; };
/* @@ -56,7 +57,7 @@ static const struct config_entry config_table[] = { /* * Apollolake (Broxton-P) * the legacy HDAudio driver is used except on Up Squared (SOF) and - * Chromebooks (SST) + * Chromebooks (SST), as well as devices based on the ES8336 codec */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) { @@ -73,6 +74,11 @@ static const struct config_entry config_table[] = { {} } }, + { + .flags = FLAG_SOF, + .device = 0x5a98, + .codec_hid = "ESSX8336", + }, #endif #if IS_ENABLED(CONFIG_SND_SOC_INTEL_APL) { @@ -137,7 +143,7 @@ static const struct config_entry config_table[] = {
/* * Geminilake uses legacy HDAudio driver except for Google - * Chromebooks + * Chromebooks and devices based on the ES8336 codec */ /* Geminilake */ #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) @@ -154,6 +160,11 @@ static const struct config_entry config_table[] = { {} } }, + { + .flags = FLAG_SOF, + .device = 0x3198, + .codec_hid = "ESSX8336", + }, #endif
/* @@ -311,6 +322,11 @@ static const struct config_entry config_table[] = { .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .device = 0x43c8, }, + { + .flags = FLAG_SOF, + .device = 0xa0c8, + .codec_hid = "ESSX8336", + }, #endif
/* Elkhart Lake */ @@ -354,6 +370,8 @@ static const struct config_entry *snd_intel_dsp_find_config continue; if (table->dmi_table && !dmi_check_system(table->dmi_table)) continue; + if (table->codec_hid[0] && !acpi_dev_present(table->codec_hid, NULL, -1)) + continue; return table; } return NULL;
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit f2470679b070a77ea22f8b791fae7084c2340c7d ]
We don't have a configuration for a single amp on link1.
BugLink: https://github.com/thesofproject/linux/issues/3161 Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Reviewed-by: Bard Liao bard.liao@intel.com Link: https://lore.kernel.org/r/20211004213512.220836-5-pierre-louis.bossart@linux... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../intel/common/soc-acpi-intel-tgl-match.c | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index 785d5f5f8a9c9..11801b905ecc2 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -156,6 +156,15 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { } };
+static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { + { + .adr = 0x000131025D131601ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1316-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { { .adr = 0x000131025D131601ull, /* unique ID is set for some reason */ @@ -320,6 +329,25 @@ static const struct snd_soc_acpi_link_adr tgl_3_in_1_sdca[] = { {} };
+static const struct snd_soc_acpi_link_adr tgl_3_in_1_sdca_mono[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_single_adr), + .adr_d = rt1316_1_single_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt714_3_adr), + .adr_d = rt714_3_adr, + }, + {} +}; + static const struct snd_soc_acpi_codecs tgl_max98373_amp = { .num_codecs = 1, .codecs = {"MX98373"} @@ -412,6 +440,19 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-tgl-rt711-rt1316-rt714.tplg", }, + { + /* + * link_mask should be 0xB, but all links are enabled by BIOS. + * This entry will be selected if there is no rt1316 amplifier exposed + * on link2 since it will fail to match the above entry. + */ + + .link_mask = 0xF, /* 4 active links required */ + .links = tgl_3_in_1_sdca_mono, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-tgl-rt711-l0-rt1316-l1-mono-rt714-l3.tplg", + }, + { .link_mask = 0x3, /* rt711 on link 0 and 1 rt1308 on link 1 */ .links = tgl_hp,
From: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
[ Upstream commit 64ba6d2ce72ffde70dc5a1794917bf1573203716 ]
This device is based on SDCA codecs but with a single amplifier instead of two.
BugLink: https://github.com/thesofproject/linux/issues/3161 Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Rander Wang rander.wang@intel.com Reviewed-by: Bard Liao bard.liao@intel.com Link: https://lore.kernel.org/r/20211004213512.220836-6-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_sdw.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 6b06248a9327a..f10496206ceed 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -213,6 +213,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A45") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_RT715_DAI_ID_FIX), + }, /* AlderLake devices */ { .callback = sof_sdw_quirk_cb,
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit f7a07f7b96033df7709042ff38e998720a3f7119 ]
The firmware_loader can be used with a pre-allocated buffer through the use of the API calls:
o request_firmware_into_buf() o request_partial_firmware_into_buf()
If the firmware was built-in and present, our current check for if the built-in firmware fits into the pre-allocated buffer does not return any errors, and we proceed to tell the caller that everything worked fine. It's a lie and no firmware would end up being copied into the pre-allocated buffer. So if the caller trust the result it may end up writing a bunch of 0's to a device!
Fix this by making the function that checks for the pre-allocated buffer return non-void. Since the typical use case is when no pre-allocated buffer is provided make this return successfully for that case. If the built-in firmware does *not* fit into the pre-allocated buffer size return a failure as we should have been doing before.
I'm not aware of users of the built-in firmware using the API calls with a pre-allocated buffer, as such I doubt this fixes any real life issue. But you never know... perhaps some oddball private tree might use it.
In so far as upstream is concerned this just fixes our code for correctness.
Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20210917182226.3532898-2-mcgrof@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/firmware_loader/main.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index bdbedc6660a87..ef904b8b112e6 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -100,12 +100,15 @@ static struct firmware_cache fw_cache; extern struct builtin_fw __start_builtin_fw[]; extern struct builtin_fw __end_builtin_fw[];
-static void fw_copy_to_prealloc_buf(struct firmware *fw, +static bool fw_copy_to_prealloc_buf(struct firmware *fw, void *buf, size_t size) { - if (!buf || size < fw->size) - return; + if (!buf) + return true; + if (size < fw->size) + return false; memcpy(buf, fw->data, fw->size); + return true; }
static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, @@ -117,9 +120,7 @@ static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, if (strcmp(name, b_fw->name) == 0) { fw->size = b_fw->size; fw->data = b_fw->data; - fw_copy_to_prealloc_buf(fw, buf, size); - - return true; + return fw_copy_to_prealloc_buf(fw, buf, size); } }
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit bdb1ffdad3b73e4d0538098fc02e2ea87a6b27cd ]
Check whether PMC is ready before proceeding with the cpuidle registration. This fixes racing with the PMC driver probe order, which results in a disabled deepest CC6 idling state if cpuidle driver is probed before the PMC.
Acked-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Dmitry Osipenko digetx@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/cpuidle-tegra.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/cpuidle/cpuidle-tegra.c b/drivers/cpuidle/cpuidle-tegra.c index 508bd9f237929..9845629aeb6d4 100644 --- a/drivers/cpuidle/cpuidle-tegra.c +++ b/drivers/cpuidle/cpuidle-tegra.c @@ -337,6 +337,9 @@ static void tegra_cpuidle_setup_tegra114_c7_state(void)
static int tegra_cpuidle_probe(struct platform_device *pdev) { + if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NOT_READY) + return -EPROBE_DEFER; + /* LP2 could be disabled in device-tree */ if (tegra_pmc_get_suspend_mode() < TEGRA_SUSPEND_LP2) tegra_cpuidle_disable_state(TEGRA_CC6);
From: José Expósito jose.exposito89@gmail.com
[ Upstream commit 08b9a61a87bc339a73c584d8924c86ab36d204a7 ]
When a finger is on the screen, the UPERFECT Y portable touchscreen monitor reports a contact in the first place. However, after this initial report, contacts are not reported at the refresh rate of the screen as required by the Windows 8 specs.
This behaviour triggers the release_timer, removing the fingers even though they are still present.
To avoid it, add a new class, similar to MT_CLS_WIN_8 but without the MT_QUIRK_STICKY_FINGERS quirk for this device.
Suggested-by: Benjamin Tissoires benjamin.tissoires@redhat.com Signed-off-by: José Expósito jose.exposito89@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-multitouch.c | 13 +++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 29564b370341e..3706c635b12ee 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1276,6 +1276,9 @@ #define USB_DEVICE_ID_WEIDA_8752 0xC300 #define USB_DEVICE_ID_WEIDA_8755 0xC301
+#define USB_VENDOR_ID_WINBOND 0x0416 +#define USB_DEVICE_ID_TSTP_MTOUCH 0xc168 + #define USB_VENDOR_ID_WISEGROUP 0x0925 #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 #define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3ea7cb1cda84c..e1afddb7b33d8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -193,6 +193,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); /* reserved 0x0014 */ #define MT_CLS_WIN_8_FORCE_MULTI_INPUT 0x0015 #define MT_CLS_WIN_8_DISABLE_WAKEUP 0x0016 +#define MT_CLS_WIN_8_NO_STICKY_FINGERS 0x0017
/* vendor specific classes */ #define MT_CLS_3M 0x0101 @@ -294,6 +295,13 @@ static const struct mt_class mt_classes[] = { MT_QUIRK_WIN8_PTP_BUTTONS | MT_QUIRK_DISABLE_WAKEUP, .export_all_inputs = true }, + { .name = MT_CLS_WIN_8_NO_STICKY_FINGERS, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_IGNORE_DUPLICATES | + MT_QUIRK_HOVERING | + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_WIN8_PTP_BUTTONS, + .export_all_inputs = true },
/* * vendor specific classes @@ -2120,6 +2128,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_VTL, USB_DEVICE_ID_VTL_MULTITOUCH_FF3F) },
+ /* Winbond Electronics Corp. */ + { .driver_data = MT_CLS_WIN_8_NO_STICKY_FINGERS, + HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_WINBOND, USB_DEVICE_ID_TSTP_MTOUCH) }, + /* Wistron panels */ { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_WISTRON,
From: William Overton willovertonuk@gmail.com
[ Upstream commit 6d27788160362a7ee6c0d317636fe4b1ddbe59a7 ]
The kernel already has support for very similar Pioneer djm products and this work is based on that.
Added device to quirks-table.h and added control info to mixer_quirks.c.
Tested on my hardware and all working.
Signed-off-by: William Overton willovertonuk@gmail.com Link: https://lore.kernel.org/r/20211010145841.11907-1-willovertonuk@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/mixer_quirks.c | 34 +++++++++++++++++++++++ sound/usb/quirks-table.h | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+)
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 46082dc57be09..d489c1de3baec 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -2795,6 +2795,7 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) #define SND_DJM_750_IDX 0x1 #define SND_DJM_850_IDX 0x2 #define SND_DJM_900NXS2_IDX 0x3 +#define SND_DJM_750MK2_IDX 0x4
#define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \ @@ -2984,10 +2985,40 @@ static const struct snd_djm_ctl snd_djm_ctls_900nxs2[] = { SND_DJM_CTL("Ch5 Input", 900nxs2_cap5, 3, SND_DJM_WINDEX_CAP) };
+// DJM-750MK2 +static const u16 snd_djm_opts_750mk2_cap1[] = { + 0x0100, 0x0102, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a }; +static const u16 snd_djm_opts_750mk2_cap2[] = { + 0x0200, 0x0202, 0x0203, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a }; +static const u16 snd_djm_opts_750mk2_cap3[] = { + 0x0300, 0x0302, 0x0303, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a }; +static const u16 snd_djm_opts_750mk2_cap4[] = { + 0x0400, 0x0402, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a }; +static const u16 snd_djm_opts_750mk2_cap5[] = { + 0x0507, 0x0508, 0x0509, 0x050a, 0x0511, 0x0512, 0x0513, 0x0514 }; + +static const u16 snd_djm_opts_750mk2_pb1[] = { 0x0100, 0x0101, 0x0104 }; +static const u16 snd_djm_opts_750mk2_pb2[] = { 0x0200, 0x0201, 0x0204 }; +static const u16 snd_djm_opts_750mk2_pb3[] = { 0x0300, 0x0301, 0x0304 }; + + +static const struct snd_djm_ctl snd_djm_ctls_750mk2[] = { + SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), + SND_DJM_CTL("Ch1 Input", 750mk2_cap1, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch2 Input", 750mk2_cap2, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch3 Input", 750mk2_cap3, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch4 Input", 750mk2_cap4, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch5 Input", 750mk2_cap5, 3, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch1 Output", 750mk2_pb1, 0, SND_DJM_WINDEX_PB), + SND_DJM_CTL("Ch2 Output", 750mk2_pb2, 1, SND_DJM_WINDEX_PB), + SND_DJM_CTL("Ch3 Output", 750mk2_pb3, 2, SND_DJM_WINDEX_PB) +}; +
static const struct snd_djm_device snd_djm_devices[] = { SND_DJM_DEVICE(250mk2), SND_DJM_DEVICE(750), + SND_DJM_DEVICE(750mk2), SND_DJM_DEVICE(850), SND_DJM_DEVICE(900nxs2) }; @@ -3235,6 +3266,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */ err = snd_djm_controls_create(mixer, SND_DJM_750_IDX); break; + case USB_ID(0x2b73, 0x001b): /* Pioneer DJ DJM-750MK2 */ + err = snd_djm_controls_create(mixer, SND_DJM_750MK2_IDX); + break; case USB_ID(0x08e4, 0x0163): /* Pioneer DJ DJM-850 */ err = snd_djm_controls_create(mixer, SND_DJM_850_IDX); break; diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 2af8c68fac275..b1522e43173e1 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -3892,6 +3892,64 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, +{ + /* + * Pioneer DJ DJM-750MK2 + * 10 channels playback & 12 channels capture @ 48kHz S24LE + */ + USB_DEVICE_VENDOR_SPEC(0x2b73, 0x001b), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S24_3LE, + .channels = 10, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x01, + .ep_attr = USB_ENDPOINT_XFER_ISOC| + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { + 48000 + } + } + }, + { + .ifnum = 0, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S24_3LE, + .channels = 12, + .iface = 0, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x82, + .ep_idx = 1, + .ep_attr = USB_ENDPOINT_XFER_ISOC| + USB_ENDPOINT_SYNC_ASYNC| + USB_ENDPOINT_USAGE_IMPLICIT_FB, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { 48000 } + } + }, + { + .ifnum = -1 + } + } + } +}, { /* * Pioneer DJ DJM-850
From: Roger Quadros rogerq@kernel.org
[ Upstream commit 51b9e22ffd3c4c56cbb7caae9750f70e55ffa603 ]
gpmc,mux-add-data is not boolean.
Fixes the below errors flagged by dtbs_check.
"ethernet@4,0:gpmc,mux-add-data: True is not of type 'array'"
Signed-off-by: Roger Quadros rogerq@kernel.org Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi | 2 +- arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi index 7f6aefd134514..e7534fe9c53cf 100644 --- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi +++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi @@ -29,7 +29,7 @@ compatible = "smsc,lan9221","smsc,lan9115"; bank-width = <2>;
- gpmc,mux-add-data; + gpmc,mux-add-data = <0>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <42>; gpmc,cs-wr-off-ns = <36>; diff --git a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi index e5da3bc6f1050..218a10c0d8159 100644 --- a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi +++ b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi @@ -22,7 +22,7 @@ compatible = "smsc,lan9221","smsc,lan9115"; bank-width = <2>;
- gpmc,mux-add-data; + gpmc,mux-add-data = <0>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <42>; gpmc,cs-wr-off-ns = <36>;
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 9eff2b2e59fda25051ab36cd1cb5014661df657b ]
It will cause null-ptr-deref if platform_get_resource() returns NULL, we need check the return value.
Acked-by: Alan Stern stern@rowland.harvard.edu Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211011134920.118477-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/ohci-tmio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 08ec2ab0d95a5..3f3d62dc06746 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -199,7 +199,7 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) if (usb_disabled()) return -ENODEV;
- if (!cell) + if (!cell || !regs || !config || !sram) return -EINVAL;
if (irq < 0)
From: Derek Fang derek.fang@realtek.com
[ Upstream commit 4b19e4a77cc6baa0f840e8bae62ab974667f6207 ]
A little pop can be heard obviously from HP while playing a silent. This patch fixes it by using two functions: 1. Enable HP 1bit output mode. 2. Change the charge pump switch size during playback on and off.
Signed-off-by: Derek Fang derek.fang@realtek.com Link: https://lore.kernel.org/r/20211014094054.811-1-derek.fang@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt5682.c | 56 +++++++++++++++++++++++++++++++++------ sound/soc/codecs/rt5682.h | 20 ++++++++++++++ 2 files changed, 68 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 4a64cab99c55b..d550c0705c28b 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -46,6 +46,8 @@ static const struct reg_sequence patch_list[] = { {RT5682_SAR_IL_CMD_1, 0x22b7}, {RT5682_SAR_IL_CMD_3, 0x0365}, {RT5682_SAR_IL_CMD_6, 0x0110}, + {RT5682_CHARGE_PUMP_1, 0x0210}, + {RT5682_HP_LOGIC_CTRL_2, 0x0007}, };
void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev) @@ -1515,21 +1517,29 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
switch (event) { case SND_SOC_DAPM_PRE_PMU: - snd_soc_component_write(component, - RT5682_HP_LOGIC_CTRL_2, 0x0012); - snd_soc_component_write(component, - RT5682_HP_CTRL_2, 0x6000); + snd_soc_component_update_bits(component, RT5682_HP_CTRL_2, + RT5682_HP_C2_DAC_AMP_MUTE, 0); + snd_soc_component_update_bits(component, RT5682_HP_LOGIC_CTRL_2, + RT5682_HP_LC2_SIG_SOUR2_MASK, RT5682_HP_LC2_SIG_SOUR2_REG); snd_soc_component_update_bits(component, RT5682_DEPOP_1, 0x60, 0x60); snd_soc_component_update_bits(component, RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0080); + snd_soc_component_update_bits(component, RT5682_HP_CTRL_2, + RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN, + RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN); + usleep_range(5000, 10000); + snd_soc_component_update_bits(component, RT5682_CHARGE_PUMP_1, + RT5682_CP_SW_SIZE_MASK, RT5682_CP_SW_SIZE_L); break;
case SND_SOC_DAPM_POST_PMD: + snd_soc_component_update_bits(component, RT5682_HP_CTRL_2, + RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN, 0); + snd_soc_component_update_bits(component, RT5682_CHARGE_PUMP_1, + RT5682_CP_SW_SIZE_MASK, RT5682_CP_SW_SIZE_M); snd_soc_component_update_bits(component, RT5682_DEPOP_1, 0x60, 0x0); - snd_soc_component_write(component, - RT5682_HP_CTRL_2, 0x0000); snd_soc_component_update_bits(component, RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0000); break; @@ -1637,6 +1647,23 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5682_adcdat_pin_enum, static const struct snd_kcontrol_new rt5682_adcdat_pin_ctrl = SOC_DAPM_ENUM("ADCDAT", rt5682_adcdat_pin_enum);
+static const unsigned int rt5682_hpo_sig_out_values[] = { + 2, + 7, +}; + +static const char * const rt5682_hpo_sig_out_mode[] = { + "Legacy", + "OneBit", +}; + +static SOC_VALUE_ENUM_SINGLE_DECL(rt5682_hpo_sig_out_enum, + RT5682_HP_LOGIC_CTRL_2, 0, RT5682_HP_LC2_SIG_SOUR1_MASK, + rt5682_hpo_sig_out_mode, rt5682_hpo_sig_out_values); + +static const struct snd_kcontrol_new rt5682_hpo_sig_demux = + SOC_DAPM_ENUM("HPO Signal Demux", rt5682_hpo_sig_out_enum); + static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("LDO2", RT5682_PWR_ANLG_3, RT5682_PWR_LDO2_BIT, 0, NULL, 0), @@ -1820,6 +1847,10 @@ static const struct snd_soc_dapm_widget rt5682_dapm_widgets[] = { SND_SOC_DAPM_SWITCH("HPOR Playback", SND_SOC_NOPM, 0, 0, &hpor_switch),
+ SND_SOC_DAPM_OUT_DRV("HPO Legacy", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_OUT_DRV("HPO OneBit", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_DEMUX("HPO Signal Demux", SND_SOC_NOPM, 0, 0, &rt5682_hpo_sig_demux), + /* CLK DET */ SND_SOC_DAPM_SUPPLY("CLKDET SYS", RT5682_CLK_DET, RT5682_SYS_CLK_DET_SFT, 0, NULL, 0), @@ -1987,10 +2018,19 @@ static const struct snd_soc_dapm_route rt5682_dapm_routes[] = { {"HP Amp", NULL, "Charge Pump"}, {"HP Amp", NULL, "CLKDET SYS"}, {"HP Amp", NULL, "Vref1"}, - {"HPOL Playback", "Switch", "HP Amp"}, - {"HPOR Playback", "Switch", "HP Amp"}, + + {"HPO Signal Demux", NULL, "HP Amp"}, + + {"HPO Legacy", "Legacy", "HPO Signal Demux"}, + {"HPO OneBit", "OneBit", "HPO Signal Demux"}, + + {"HPOL Playback", "Switch", "HPO Legacy"}, + {"HPOR Playback", "Switch", "HPO Legacy"}, + {"HPOL", NULL, "HPOL Playback"}, {"HPOR", NULL, "HPOR Playback"}, + {"HPOL", NULL, "HPO OneBit"}, + {"HPOR", NULL, "HPO OneBit"}, };
static int rt5682_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, diff --git a/sound/soc/codecs/rt5682.h b/sound/soc/codecs/rt5682.h index b59221048ebf9..8e3244a62c160 100644 --- a/sound/soc/codecs/rt5682.h +++ b/sound/soc/codecs/rt5682.h @@ -375,6 +375,14 @@ #define RT5682_R_VOL_MASK (0x3f) #define RT5682_R_VOL_SFT 0
+/* Headphone Amp Control 2 (0x0003) */ +#define RT5682_HP_C2_DAC_AMP_MUTE_SFT 15 +#define RT5682_HP_C2_DAC_AMP_MUTE (0x1 << 15) +#define RT5682_HP_C2_DAC_L_EN_SFT 14 +#define RT5682_HP_C2_DAC_L_EN (0x1 << 14) +#define RT5682_HP_C2_DAC_R_EN_SFT 13 +#define RT5682_HP_C2_DAC_R_EN (0x1 << 13) + /*Headphone Amp L/R Analog Gain and Digital NG2 Gain Control (0x0005 0x0006)*/ #define RT5682_G_HP (0xf << 8) #define RT5682_G_HP_SFT 8 @@ -1265,6 +1273,10 @@ #define RT5682_HPA_CP_BIAS_6UA (0x3 << 2)
/* Charge Pump Internal Register1 (0x0125) */ +#define RT5682_CP_SW_SIZE_MASK (0x7 << 8) +#define RT5682_CP_SW_SIZE_L (0x4 << 8) +#define RT5682_CP_SW_SIZE_M (0x2 << 8) +#define RT5682_CP_SW_SIZE_S (0x1 << 8) #define RT5682_CP_CLK_HP_MASK (0x3 << 4) #define RT5682_CP_CLK_HP_100KHZ (0x0 << 4) #define RT5682_CP_CLK_HP_200KHZ (0x1 << 4) @@ -1315,6 +1327,14 @@ #define RT5682_DEB_STO_DAC_MASK (0x7 << 4) #define RT5682_DEB_80_MS (0x0 << 4)
+/* HP Behavior Logic Control 2 (0x01db) */ +#define RT5682_HP_LC2_SIG_SOUR2_MASK (0x1 << 4) +#define RT5682_HP_LC2_SIG_SOUR2_REG (0x1 << 4) +#define RT5682_HP_LC2_SIG_SOUR2_DC_CAL (0x0 << 4) +#define RT5682_HP_LC2_SIG_SOUR1_MASK (0x7) +#define RT5682_HP_LC2_SIG_SOUR1_1BIT (0x7) +#define RT5682_HP_LC2_SIG_SOUR1_LEGA (0x2) + /* SAR ADC Inline Command Control 1 (0x0210) */ #define RT5682_SAR_BUTT_DET_MASK (0x1 << 15) #define RT5682_SAR_BUTT_DET_EN (0x1 << 15)
From: Li Yang leoyang.li@nxp.com
[ Upstream commit 1ee1500ef717eefb5d9bdaf97905cb81b4e69aa4 ]
This fixes dtbs-check error from simple-bus schema: soc: thermal-zones: {'type': 'object'} is not allowed for {'cpu-thermal': ..... } From schema: /home/leo/.local/lib/python3.8/site-packages/dtschema/schemas/simple-bus.yaml
Signed-off-by: Li Yang leoyang.li@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ls1021a.dtsi | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-)
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 4fce81422943b..f3b8540750b61 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -329,39 +329,6 @@ #thermal-sensor-cells = <1>; };
- thermal-zones { - cpu_thermal: cpu-thermal { - polling-delay-passive = <1000>; - polling-delay = <5000>; - - thermal-sensors = <&tmu 0>; - - trips { - cpu_alert: cpu-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - cpu_crit: cpu-crit { - temperature = <95000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu_alert>; - cooling-device = - <&cpu0 THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>; - }; - }; - }; - }; - dspi0: spi@2100000 { compatible = "fsl,ls1021a-v1.0-dspi"; #address-cells = <1>; @@ -1016,4 +983,37 @@ big-endian; }; }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + + thermal-sensors = <&tmu 0>; + + trips { + cpu_alert: cpu-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit: cpu-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + }; };
From: Li Yang leoyang.li@nxp.com
[ Upstream commit 05e63b48b20fa70726be505a7660d1a07bc1cffb ]
We cannot list all the possible chips used in different board revisions, just use the generic "jedec,spi-nor" compatible instead. This also fixes dtbs_check error: ['jedec,spi-nor', 's25fl256s1', 's25fl512s'] is too long
Signed-off-by: Li Yang leoyang.li@nxp.com Reviewed-by: Kuldeep Singh kuldeep.singh@nxp.com Signed-off-by: Shawn Guo shawnguo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/ls1021a-tsn.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/ls1021a-tsn.dts b/arch/arm/boot/dts/ls1021a-tsn.dts index 9d8f0c2a8aba3..aca78b5eddf20 100644 --- a/arch/arm/boot/dts/ls1021a-tsn.dts +++ b/arch/arm/boot/dts/ls1021a-tsn.dts @@ -251,7 +251,7 @@
flash@0 { /* Rev. A uses 64MB flash, Rev. B & C use 32MB flash */ - compatible = "jedec,spi-nor", "s25fl256s1", "s25fl512s"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; #address-cells = <1>; #size-cells = <1>;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 3c05f1477e62ea5a0a8797ba6a545b1dc751fb31 ]
On m68k, compiling drivers under SND_ISA causes build errors:
../sound/core/isadma.c: In function 'snd_dma_program': ../sound/core/isadma.c:33:17: error: implicit declaration of function 'claim_dma_lock' [-Werror=implicit-function-declaration] 33 | flags = claim_dma_lock(); | ^~~~~~~~~~~~~~ ../sound/core/isadma.c:41:9: error: implicit declaration of function 'release_dma_lock' [-Werror=implicit-function-declaration] 41 | release_dma_lock(flags); | ^~~~~~~~~~~~~~~~
../sound/isa/sb/sb16_main.c: In function 'snd_sb16_playback_prepare': ../sound/isa/sb/sb16_main.c:253:72: error: 'DMA_AUTOINIT' undeclared (first use in this function) 253 | snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT); | ^~~~~~~~~~~~ ../sound/isa/sb/sb16_main.c:253:72: note: each undeclared identifier is reported only once for each function it appears in ../sound/isa/sb/sb16_main.c: In function 'snd_sb16_capture_prepare': ../sound/isa/sb/sb16_main.c:322:71: error: 'DMA_AUTOINIT' undeclared (first use in this function) 322 | snd_dma_program(dma, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT); | ^~~~~~~~~~~~
and more...
Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: alsa-devel@alsa-project.org Cc: linux-m68k@lists.linux-m68k.org Cc: Geert Uytterhoeven geert@linux-m68k.org Link: https://lore.kernel.org/r/20211016062602.3588-1-rdunlap@infradead.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/Makefile | 2 ++ sound/isa/Kconfig | 2 +- sound/pci/Kconfig | 1 + 3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/core/Makefile b/sound/core/Makefile index d774792850f31..79e1407cd0de7 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -9,7 +9,9 @@ ifneq ($(CONFIG_SND_PROC_FS),) snd-y += info.o snd-$(CONFIG_SND_OSSEMUL) += info_oss.o endif +ifneq ($(CONFIG_M68K),y) snd-$(CONFIG_ISA_DMA_API) += isadma.o +endif snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o snd-$(CONFIG_SND_VMASTER) += vmaster.o snd-$(CONFIG_SND_JACK) += ctljack.o jack.o diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 6ffa48dd59830..570b88e0b2018 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -22,7 +22,7 @@ config SND_SB16_DSP menuconfig SND_ISA bool "ISA sound devices" depends on ISA || COMPILE_TEST - depends on ISA_DMA_API + depends on ISA_DMA_API && !M68K default y help Support for sound devices connected via the ISA bus. diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 93bc9bef7641f..41ce125971777 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -279,6 +279,7 @@ config SND_CS46XX_NEW_DSP config SND_CS5530 tristate "CS5530 Audio" depends on ISA_DMA_API && (X86_32 || COMPILE_TEST) + depends on !M68K select SND_SB16_DSP help Say Y here to include support for audio on Cyrix/NatSemi CS5530 chips.
From: Tvrtko Ursulin tvrtko.ursulin@intel.com
[ Upstream commit 5240aed2cd2594fb392239f11b9681e5e1591619 ]
Handling of intel_iommu kernel command line option should return "true" to indicate option is valid and so avoid logging it as unknown by the core parsing code.
Also log unknown sub-options at the notice level to let user know of potential typos or similar.
Reported-by: Eero Tamminen eero.t.tamminen@intel.com Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@intel.com Link: https://lore.kernel.org/r/20210831112947.310080-1-tvrtko.ursulin@linux.intel... Signed-off-by: Lu Baolu baolu.lu@linux.intel.com Link: https://lore.kernel.org/r/20211014053839.727419-2-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/intel/iommu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index d75f59ae28e6e..9a356075d3450 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -412,6 +412,7 @@ static int __init intel_iommu_setup(char *str) { if (!str) return -EINVAL; + while (*str) { if (!strncmp(str, "on", 2)) { dmar_disabled = 0; @@ -441,13 +442,16 @@ static int __init intel_iommu_setup(char *str) } else if (!strncmp(str, "tboot_noforce", 13)) { pr_info("Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n"); intel_iommu_tboot_noforce = 1; + } else { + pr_notice("Unknown option - '%s'\n", str); }
str += strcspn(str, ","); while (*str == ',') str++; } - return 0; + + return 1; } __setup("intel_iommu=", intel_iommu_setup);
From: Guanghui Feng guanghuifeng@linux.alibaba.com
[ Upstream commit 3968ddcf05fb4b9409cd1859feb06a5b0550a1c1 ]
When running ltp testcase(ltp/testcases/kernel/pty/pty04.c) with arm64, there is a soft lockup, which look like this one:
Workqueue: events_unbound flush_to_ldisc Call trace: dump_backtrace+0x0/0x1ec show_stack+0x24/0x30 dump_stack+0xd0/0x128 panic+0x15c/0x374 watchdog_timer_fn+0x2b8/0x304 __run_hrtimer+0x88/0x2c0 __hrtimer_run_queues+0xa4/0x120 hrtimer_interrupt+0xfc/0x270 arch_timer_handler_phys+0x40/0x50 handle_percpu_devid_irq+0x94/0x220 __handle_domain_irq+0x88/0xf0 gic_handle_irq+0x84/0xfc el1_irq+0xc8/0x180 slip_unesc+0x80/0x214 [slip] tty_ldisc_receive_buf+0x64/0x80 tty_port_default_receive_buf+0x50/0x90 flush_to_ldisc+0xbc/0x110 process_one_work+0x1d4/0x4b0 worker_thread+0x180/0x430 kthread+0x11c/0x120
In the testcase pty04, The first process call the write syscall to send data to the pty master. At the same time, the workqueue will do the flush_to_ldisc to pop data in a loop until there is no more data left. When the sender and workqueue running in different core, the sender sends data fastly in full time which will result in workqueue doing work in loop for a long time and occuring softlockup in flush_to_ldisc with kernel configured without preempt. So I add need_resched check and cond_resched in the flush_to_ldisc loop to avoid it.
Signed-off-by: Guanghui Feng guanghuifeng@linux.alibaba.com Link: https://lore.kernel.org/r/1633961304-24759-1-git-send-email-guanghuifeng@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/tty_buffer.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 635d0af229b72..6c7e65b1d9a1c 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -544,6 +544,9 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) break; head->read += count; + + if (need_resched()) + cond_resched(); }
mutex_unlock(&buf->lock);
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit c91cf42f61dc77b289784ea7b15a8531defa41c0 ]
This patch fixes the following gcc 10 build error:
arch/mips/sni/time.c: In function ‘a20r_set_periodic’: arch/mips/sni/time.c:15:26: error: unsigned conversion from ‘int’ to ‘u8’ {aka ‘volatile unsigned char’} changes value from ‘576’ to ‘64’ [-Werror=overflow] 15 | #define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ) | ^ arch/mips/sni/time.c:21:45: note: in expansion of macro ‘SNI_COUNTER0_DIV’ 21 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV; | ^~~~~~~~~~~~~~~~
Cc: linux-mips@vger.kernel.org Signed-off-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/sni/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c index 240bb68ec2478..ff3ba7e778901 100644 --- a/arch/mips/sni/time.c +++ b/arch/mips/sni/time.c @@ -18,14 +18,14 @@ static int a20r_set_periodic(struct clock_event_device *evt) { *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV; + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV & 0xff; wmb(); *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8; wmb();
*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV; + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV & 0xff; wmb(); *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8; wmb();
From: Ye Bin yebin10@huawei.com
[ Upstream commit 4e3ace0051e7e504b55d239daab8789dd89b863c ]
The following warning was observed running syzkaller:
[ 3813.830724] sg_write: data in/out 65466/242 bytes for SCSI command 0x9e-- guessing data in; [ 3813.830724] program syz-executor not setting count and/or reply_len properly [ 3813.836956] ================================================================== [ 3813.839465] BUG: KASAN: stack-out-of-bounds in sg_copy_buffer+0x157/0x1e0 [ 3813.841773] Read of size 4096 at addr ffff8883cf80f540 by task syz-executor/1549 [ 3813.846612] Call Trace: [ 3813.846995] dump_stack+0x108/0x15f [ 3813.847524] print_address_description+0xa5/0x372 [ 3813.848243] kasan_report.cold+0x236/0x2a8 [ 3813.849439] check_memory_region+0x240/0x270 [ 3813.850094] memcpy+0x30/0x80 [ 3813.850553] sg_copy_buffer+0x157/0x1e0 [ 3813.853032] sg_copy_from_buffer+0x13/0x20 [ 3813.853660] fill_from_dev_buffer+0x135/0x370 [ 3813.854329] resp_readcap16+0x1ac/0x280 [ 3813.856917] schedule_resp+0x41f/0x1630 [ 3813.858203] scsi_debug_queuecommand+0xb32/0x17e0 [ 3813.862699] scsi_dispatch_cmd+0x330/0x950 [ 3813.863329] scsi_request_fn+0xd8e/0x1710 [ 3813.863946] __blk_run_queue+0x10b/0x230 [ 3813.864544] blk_execute_rq_nowait+0x1d8/0x400 [ 3813.865220] sg_common_write.isra.0+0xe61/0x2420 [ 3813.871637] sg_write+0x6c8/0xef0 [ 3813.878853] __vfs_write+0xe4/0x800 [ 3813.883487] vfs_write+0x17b/0x530 [ 3813.884008] ksys_write+0x103/0x270 [ 3813.886268] __x64_sys_write+0x77/0xc0 [ 3813.886841] do_syscall_64+0x106/0x360 [ 3813.887415] entry_SYSCALL_64_after_hwframe+0x44/0xa9
This issue can be reproduced with the following syzkaller log:
r0 = openat(0xffffffffffffff9c, &(0x7f0000000040)='./file0\x00', 0x26e1, 0x0) r1 = syz_open_procfs(0xffffffffffffffff, &(0x7f0000000000)='fd/3\x00') open_by_handle_at(r1, &(0x7f00000003c0)=ANY=[@ANYRESHEX], 0x602000) r2 = syz_open_dev$sg(&(0x7f0000000000), 0x0, 0x40782) write$binfmt_aout(r2, &(0x7f0000000340)=ANY=[@ANYBLOB="00000000deff000000000000000000000000000000000000000000000000000047f007af9e107a41ec395f1bded7be24277a1501ff6196a83366f4e6362bc0ff2b247f68a972989b094b2da4fb3607fcf611a22dd04310d28c75039d"], 0x126)
In resp_readcap16() we get "int alloc_len" value -1104926854, and then pass the huge arr_len to fill_from_dev_buffer(), but arr is only 32 bytes. This leads to OOB in sg_copy_buffer().
To solve this issue, define alloc_len as u32.
Link: https://lore.kernel.org/r/20211013033913.2551004-2-yebin10@huawei.com Acked-by: Douglas Gilbert dgilbert@interlog.com Signed-off-by: Ye Bin yebin10@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 66f507469a31a..be04405457447 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1856,7 +1856,7 @@ static int resp_readcap16(struct scsi_cmnd *scp, { unsigned char *cmd = scp->cmnd; unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; - int alloc_len; + u32 alloc_len;
alloc_len = get_unaligned_be32(cmd + 10); /* following just in case virtual_gb changed */ @@ -1885,7 +1885,7 @@ static int resp_readcap16(struct scsi_cmnd *scp, }
return fill_from_dev_buffer(scp, arr, - min_t(int, alloc_len, SDEBUG_READCAP16_ARR_SZ)); + min_t(u32, alloc_len, SDEBUG_READCAP16_ARR_SZ)); }
#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
From: Ye Bin yebin10@huawei.com
[ Upstream commit f347c26836c270199de1599c3cd466bb7747caa9 ]
The following issue was observed running syzkaller:
BUG: KASAN: slab-out-of-bounds in memcpy include/linux/string.h:377 [inline] BUG: KASAN: slab-out-of-bounds in sg_copy_buffer+0x150/0x1c0 lib/scatterlist.c:831 Read of size 2132 at addr ffff8880aea95dc8 by task syz-executor.0/9815
CPU: 0 PID: 9815 Comm: syz-executor.0 Not tainted 4.19.202-00874-gfc0fe04215a9 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0xe4/0x14a lib/dump_stack.c:118 print_address_description+0x73/0x280 mm/kasan/report.c:253 kasan_report_error mm/kasan/report.c:352 [inline] kasan_report+0x272/0x370 mm/kasan/report.c:410 memcpy+0x1f/0x50 mm/kasan/kasan.c:302 memcpy include/linux/string.h:377 [inline] sg_copy_buffer+0x150/0x1c0 lib/scatterlist.c:831 fill_from_dev_buffer+0x14f/0x340 drivers/scsi/scsi_debug.c:1021 resp_report_tgtpgs+0x5aa/0x770 drivers/scsi/scsi_debug.c:1772 schedule_resp+0x464/0x12f0 drivers/scsi/scsi_debug.c:4429 scsi_debug_queuecommand+0x467/0x1390 drivers/scsi/scsi_debug.c:5835 scsi_dispatch_cmd+0x3fc/0x9b0 drivers/scsi/scsi_lib.c:1896 scsi_request_fn+0x1042/0x1810 drivers/scsi/scsi_lib.c:2034 __blk_run_queue_uncond block/blk-core.c:464 [inline] __blk_run_queue+0x1a4/0x380 block/blk-core.c:484 blk_execute_rq_nowait+0x1c2/0x2d0 block/blk-exec.c:78 sg_common_write.isra.19+0xd74/0x1dc0 drivers/scsi/sg.c:847 sg_write.part.23+0x6e0/0xd00 drivers/scsi/sg.c:716 sg_write+0x64/0xa0 drivers/scsi/sg.c:622 __vfs_write+0xed/0x690 fs/read_write.c:485 kill_bdev:block_device:00000000e138492c vfs_write+0x184/0x4c0 fs/read_write.c:549 ksys_write+0x107/0x240 fs/read_write.c:599 do_syscall_64+0xc2/0x560 arch/x86/entry/common.c:293 entry_SYSCALL_64_after_hwframe+0x49/0xbe
We get 'alen' from command its type is int. If userspace passes a large length we will get a negative 'alen'.
Switch n, alen, and rlen to u32.
Link: https://lore.kernel.org/r/20211013033913.2551004-3-yebin10@huawei.com Acked-by: Douglas Gilbert dgilbert@interlog.com Signed-off-by: Ye Bin yebin10@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_debug.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index be04405457447..ead65cdfb522e 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1896,8 +1896,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd *scp, unsigned char *cmd = scp->cmnd; unsigned char *arr; int host_no = devip->sdbg_host->shost->host_no; - int n, ret, alen, rlen; int port_group_a, port_group_b, port_a, port_b; + u32 alen, n, rlen; + int ret;
alen = get_unaligned_be32(cmd + 6); arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC); @@ -1959,9 +1960,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd *scp, * - The constructed command length * - The maximum array size */ - rlen = min_t(int, alen, n); + rlen = min(alen, n); ret = fill_from_dev_buffer(scp, arr, - min_t(int, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); + min_t(u32, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); kfree(arr); return ret; }
From: Mike Christie michael.christie@oracle.com
[ Upstream commit ed1227e080990ffec5bf39006ec8a57358e6689a ]
This patch fixes the following bugs:
1. If there are multiple ordered cmds queued and multiple simple cmds completing, target_restart_delayed_cmds() could be called on different CPUs and each instance could start a ordered cmd. They could then run in different orders than they were queued.
2. target_restart_delayed_cmds() and target_handle_task_attr() can race where:
1. target_handle_task_attr() has passed the simple_cmds == 0 check.
2. transport_complete_task_attr() then decrements simple_cmds to 0.
3. transport_complete_task_attr() runs target_restart_delayed_cmds() and it does not see any cmds on the delayed_cmd_list.
4. target_handle_task_attr() adds the cmd to the delayed_cmd_list.
The cmd will then end up timing out.
3. If we are sent > 1 ordered cmds and simple_cmds == 0, we can execute them out of order, because target_handle_task_attr() will hit that simple_cmds check first and return false for all ordered cmds sent.
4. We run target_restart_delayed_cmds() after every cmd completion, so if there is more than 1 simple cmd running, we start executing ordered cmds after that first cmd instead of waiting for all of them to complete.
5. Ordered cmds are not supposed to start until HEAD OF QUEUE and all older cmds have completed, and not just simple.
6. It's not a bug but it doesn't make sense to take the delayed_cmd_lock for every cmd completion when ordered cmds are almost never used. Just replacing that lock with an atomic increases IOPs by up to 10% when completions are spread over multiple CPUs and there are multiple sessions/ mqs/thread accessing the same device.
This patch moves the queued delayed handling to a per device work to serialze the cmd executions for each device and adds a new counter to track HEAD_OF_QUEUE and SIMPLE cmds. We can then check the new counter to determine when to run the work on the completion path.
Link: https://lore.kernel.org/r/20210930020422.92578-3-michael.christie@oracle.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_device.c | 2 + drivers/target/target_core_internal.h | 1 + drivers/target/target_core_transport.c | 76 ++++++++++++++++++-------- include/target/target_core_base.h | 6 +- 4 files changed, 61 insertions(+), 24 deletions(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8cb1fa0c05857..44bb380e7390c 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -772,6 +772,8 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) INIT_LIST_HEAD(&dev->t10_alua.lba_map_list); spin_lock_init(&dev->t10_alua.lba_map_lock);
+ INIT_WORK(&dev->delayed_cmd_work, target_do_delayed_work); + dev->t10_wwn.t10_dev = dev; /* * Use OpenFabrics IEEE Company ID: 00 14 05 diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index a343bcfa2180f..a889a6237d9c1 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -151,6 +151,7 @@ int transport_dump_vpd_ident(struct t10_vpd *, unsigned char *, int); void transport_clear_lun_ref(struct se_lun *); sense_reason_t target_cmd_size_check(struct se_cmd *cmd, unsigned int size); void target_qf_do_work(struct work_struct *work); +void target_do_delayed_work(struct work_struct *work); bool target_check_wce(struct se_device *dev); bool target_check_fua(struct se_device *dev); void __target_execute_cmd(struct se_cmd *, bool); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index e60abd230e90f..72edf5bd75ee6 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2189,32 +2189,35 @@ static bool target_handle_task_attr(struct se_cmd *cmd) */ switch (cmd->sam_task_attr) { case TCM_HEAD_TAG: + atomic_inc_mb(&dev->non_ordered); pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x\n", cmd->t_task_cdb[0]); return false; case TCM_ORDERED_TAG: - atomic_inc_mb(&dev->dev_ordered_sync); + atomic_inc_mb(&dev->delayed_cmd_count);
pr_debug("Added ORDERED for CDB: 0x%02x to ordered list\n", cmd->t_task_cdb[0]); - - /* - * Execute an ORDERED command if no other older commands - * exist that need to be completed first. - */ - if (!atomic_read(&dev->simple_cmds)) - return false; break; default: /* * For SIMPLE and UNTAGGED Task Attribute commands */ - atomic_inc_mb(&dev->simple_cmds); + atomic_inc_mb(&dev->non_ordered); + + if (atomic_read(&dev->delayed_cmd_count) == 0) + return false; break; }
- if (atomic_read(&dev->dev_ordered_sync) == 0) - return false; + if (cmd->sam_task_attr != TCM_ORDERED_TAG) { + atomic_inc_mb(&dev->delayed_cmd_count); + /* + * We will account for this when we dequeue from the delayed + * list. + */ + atomic_dec_mb(&dev->non_ordered); + }
spin_lock(&dev->delayed_cmd_lock); list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); @@ -2222,6 +2225,12 @@ static bool target_handle_task_attr(struct se_cmd *cmd)
pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to delayed CMD listn", cmd->t_task_cdb[0], cmd->sam_task_attr); + /* + * We may have no non ordered cmds when this function started or we + * could have raced with the last simple/head cmd completing, so kick + * the delayed handler here. + */ + schedule_work(&dev->delayed_cmd_work); return true; }
@@ -2259,29 +2268,48 @@ EXPORT_SYMBOL(target_execute_cmd); * Process all commands up to the last received ORDERED task attribute which * requires another blocking boundary */ -static void target_restart_delayed_cmds(struct se_device *dev) +void target_do_delayed_work(struct work_struct *work) { - for (;;) { + struct se_device *dev = container_of(work, struct se_device, + delayed_cmd_work); + + spin_lock(&dev->delayed_cmd_lock); + while (!dev->ordered_sync_in_progress) { struct se_cmd *cmd;
- spin_lock(&dev->delayed_cmd_lock); - if (list_empty(&dev->delayed_cmd_list)) { - spin_unlock(&dev->delayed_cmd_lock); + if (list_empty(&dev->delayed_cmd_list)) break; - }
cmd = list_entry(dev->delayed_cmd_list.next, struct se_cmd, se_delayed_node); + + if (cmd->sam_task_attr == TCM_ORDERED_TAG) { + /* + * Check if we started with: + * [ordered] [simple] [ordered] + * and we are now at the last ordered so we have to wait + * for the simple cmd. + */ + if (atomic_read(&dev->non_ordered) > 0) + break; + + dev->ordered_sync_in_progress = true; + } + list_del(&cmd->se_delayed_node); + atomic_dec_mb(&dev->delayed_cmd_count); spin_unlock(&dev->delayed_cmd_lock);
+ if (cmd->sam_task_attr != TCM_ORDERED_TAG) + atomic_inc_mb(&dev->non_ordered); + cmd->transport_state |= CMD_T_SENT;
__target_execute_cmd(cmd, true);
- if (cmd->sam_task_attr == TCM_ORDERED_TAG) - break; + spin_lock(&dev->delayed_cmd_lock); } + spin_unlock(&dev->delayed_cmd_lock); }
/* @@ -2299,14 +2327,17 @@ static void transport_complete_task_attr(struct se_cmd *cmd) goto restart;
if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { - atomic_dec_mb(&dev->simple_cmds); + atomic_dec_mb(&dev->non_ordered); dev->dev_cur_ordered_id++; } else if (cmd->sam_task_attr == TCM_HEAD_TAG) { + atomic_dec_mb(&dev->non_ordered); dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for HEAD_OF_QUEUE\n", dev->dev_cur_ordered_id); } else if (cmd->sam_task_attr == TCM_ORDERED_TAG) { - atomic_dec_mb(&dev->dev_ordered_sync); + spin_lock(&dev->delayed_cmd_lock); + dev->ordered_sync_in_progress = false; + spin_unlock(&dev->delayed_cmd_lock);
dev->dev_cur_ordered_id++; pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n", @@ -2315,7 +2346,8 @@ static void transport_complete_task_attr(struct se_cmd *cmd) cmd->se_cmd_flags &= ~SCF_TASK_ATTR_SET;
restart: - target_restart_delayed_cmds(dev); + if (atomic_read(&dev->delayed_cmd_count) > 0) + schedule_work(&dev->delayed_cmd_work); }
static void transport_complete_qf(struct se_cmd *cmd) diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index fb11c7693b257..2121a323fd6c3 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -812,8 +812,9 @@ struct se_device { atomic_long_t read_bytes; atomic_long_t write_bytes; /* Active commands on this virtual SE device */ - atomic_t simple_cmds; - atomic_t dev_ordered_sync; + atomic_t non_ordered; + bool ordered_sync_in_progress; + atomic_t delayed_cmd_count; atomic_t dev_qf_count; u32 export_count; spinlock_t delayed_cmd_lock; @@ -834,6 +835,7 @@ struct se_device { struct list_head dev_sep_list; struct list_head dev_tmr_list; struct work_struct qf_work_queue; + struct work_struct delayed_cmd_work; struct list_head delayed_cmd_list; struct list_head qf_cmd_list; /* Pointer to associated SE HBA */
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 1283c0d1a32bb924324481586b5d6e8e76f676ba ]
We can't free the tg_pt_gp in core_alua_set_tg_pt_gp_id() because it's still accessed via configfs. Its release must go through the normal configfs/refcount process.
The max alua_tg_pt_gps_count check should probably have been done in core_alua_allocate_tg_pt_gp(), but with the current code userspace could have created 0x0000ffff + 1 groups, but only set the id for 0x0000ffff. Then it could have deleted a group with an ID set, and then set the ID for that extra group and it would work ok.
It's unlikely, but just in case this patch continues to allow that type of behavior, and just fixes the kfree() while in use bug.
Link: https://lore.kernel.org/r/20210930020422.92578-4-michael.christie@oracle.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_alua.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index cb1de1ecaaa61..bd0f2ce011dd7 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -1674,7 +1674,6 @@ int core_alua_set_tg_pt_gp_id( pr_err("Maximum ALUA alua_tg_pt_gps_count:" " 0x0000ffff reached\n"); spin_unlock(&dev->t10_alua.tg_pt_gps_lock); - kmem_cache_free(t10_alua_tg_pt_gp_cache, tg_pt_gp); return -ENOSPC; } again:
From: Teng Qi starmiku1207184332@gmail.com
[ Upstream commit 94be878c882d8d784ff44c639bf55f3b029f85af ]
The length of hw->settings->odr_table is 2 and ref_sensor->id is an enum variable whose value is between 0 and 5. However, the value ST_LSM6DSX_ID_MAX (i.e. 5) is not caught properly in switch (sensor->id) {
If ref_sensor->id is ST_LSM6DSX_ID_MAX, an array overflow will ocurrs in function st_lsm6dsx_check_odr(): odr_table = &sensor->hw->settings->odr_table[sensor->id];
and in function st_lsm6dsx_set_odr(): reg = &hw->settings->odr_table[ref_sensor->id].reg;
To avoid this array overflow, handle ST_LSM6DSX_ID_GYRO explicitly and return -EINVAL for the default case.
The enum value ST_LSM6DSX_ID_MAX is only present as an easy way to check the limit and as such is never used, however this is not locally obvious.
Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Teng Qi starmiku1207184332@gmail.com Acked-by: Lorenzo Bianconi lorenzo@kernel.org Link: https://lore.kernel.org/r/20211011114003.976221-1-starmiku1207184332@gmail.c... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index db45f1fc0b817..8dbf744c5651f 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -1279,6 +1279,8 @@ st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr) int err;
switch (sensor->id) { + case ST_LSM6DSX_ID_GYRO: + break; case ST_LSM6DSX_ID_EXT0: case ST_LSM6DSX_ID_EXT1: case ST_LSM6DSX_ID_EXT2: @@ -1304,8 +1306,8 @@ st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr) } break; } - default: - break; + default: /* should never occur */ + return -EINVAL; }
if (req_odr > 0) {
From: wangyugui wangyugui@e16-tech.com
[ Upstream commit 911a81c9c7092bfd75432ce79b2ef879127ea065 ]
The 'struct attribute' flex array contains some struct lock_class_key's which become big when lockdep is turned on. Big enough that some drivers will not load when CONFIG_PROVE_LOCKING=y because they cannot allocate enough memory:
WARNING: CPU: 36 PID: 8 at mm/page_alloc.c:5350 __alloc_pages+0x27e/0x3e0 Call Trace: kmalloc_order+0x2a/0xb0 kmalloc_order_trace+0x19/0xf0 __kmalloc+0x231/0x270 ib_setup_port_attrs+0xd8/0x870 [ib_core] ib_register_device+0x419/0x4e0 [ib_core] bnxt_re_task+0x208/0x2d0 [bnxt_re]
Link: https://lore.kernel.org/r/20211019002656.17745-1-wangyugui@e16-tech.com Signed-off-by: wangyugui wangyugui@e16-tech.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 6146c3c1cbe5c..8d709986b88c7 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -757,7 +757,7 @@ static void ib_port_release(struct kobject *kobj) if (port->hw_stats_data) kfree(port->hw_stats_data->stats); kfree(port->hw_stats_data); - kfree(port); + kvfree(port); }
static void ib_port_gid_attr_release(struct kobject *kobj) @@ -1189,7 +1189,7 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, struct ib_port *p; int ret;
- p = kzalloc(struct_size(p, attrs_list, + p = kvzalloc(struct_size(p, attrs_list, attr->gid_tbl_len + attr->pkey_tbl_len), GFP_KERNEL); if (!p)
From: James Smart jsmart2021@gmail.com
[ Upstream commit 79b20beccea3a3938a8500acef4e6b9d7c66142f ]
An error is detected with the following report when unloading the driver: "KASAN: use-after-free in lpfc_unreg_rpi+0x1b1b"
The NLP_REG_LOGIN_SEND nlp_flag is set in lpfc_reg_fab_ctrl_node(), but the flag is not cleared upon completion of the login.
This allows a second call to lpfc_unreg_rpi() to proceed with nlp_rpi set to LPFC_RPI_ALLOW_ERROR. This results in a use after free access when used as an rpi_ids array index.
Fix by clearing the NLP_REG_LOGIN_SEND nlp_flag in lpfc_mbx_cmpl_fc_reg_login().
Link: https://lore.kernel.org/r/20211020211417.88754-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_hbadisc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 6f2e07c30f98f..e1c02229c82d9 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4360,6 +4360,7 @@ lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) ndlp->nlp_state);
ndlp->nlp_flag |= NLP_RPI_REGISTERED; + ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
From: James Smart jsmart2021@gmail.com
[ Upstream commit 1854f53ccd88ad4e7568ddfafafffe71f1ceb0a6 ]
If an FC link down transition while PLOGIs are outstanding to fabric well known addresses, outstanding ABTS requests may result in a NULL pointer dereference. Driver unload requests may hang with repeated "2878" log messages.
The Link down processing results in ABTS requests for outstanding ELS requests. The Abort WQEs are sent for the ELSs before the driver had set the link state to down. Thus the driver is sending the Abort with the expectation that an ABTS will be sent on the wire. The Abort request is stalled waiting for the link to come up. In some conditions the driver may auto-complete the ELSs thus if the link does come up, the Abort completions may reference an invalid structure.
Fix by ensuring that Abort set the flag to avoid link traffic if issued due to conditions where the link failed.
Link: https://lore.kernel.org/r/20211020211417.88754-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_sli.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 8e689f06afc92..9c1f485952ef7 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12404,17 +12404,17 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
/* ABTS WQE must go to the same WQ as the WQE to be aborted */ abtsiocbp->hba_wqidx = cmdiocb->hba_wqidx; - if (cmdiocb->iocb_flag & LPFC_IO_FCP) { - abtsiocbp->iocb_flag |= LPFC_IO_FCP; - abtsiocbp->iocb_flag |= LPFC_USE_FCPWQIDX; - } + if (cmdiocb->iocb_flag & LPFC_IO_FCP) + abtsiocbp->iocb_flag |= (LPFC_IO_FCP | LPFC_USE_FCPWQIDX); if (cmdiocb->iocb_flag & LPFC_IO_FOF) abtsiocbp->iocb_flag |= LPFC_IO_FOF;
- if (phba->link_state >= LPFC_LINK_UP) - iabt->ulpCommand = CMD_ABORT_XRI_CN; - else + 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)) iabt->ulpCommand = CMD_CLOSE_XRI_CN; + else + iabt->ulpCommand = CMD_ABORT_XRI_CN;
if (cmpl) abtsiocbp->iocb_cmpl = cmpl;
From: James Smart jsmart2021@gmail.com
[ Upstream commit af984c87293b19dccbd0b16afc57c5c9a4a279c7 ]
A link bounce to a slow fabric may observe FDISC response delays lasting longer than devloss tmo. Current logic decrements the final fabric node kref during a devloss tmo event. This results in a NULL ptr dereference crash if the FDISC completes for that fabric node after devloss tmo.
Fix by adding the NLP_IN_RECOV_POST_DEV_LOSS flag, which is set when devloss tmo triggers and we've noticed that fabric node recovery has already started or finished in between the time lpfc_dev_loss_tmo_callbk queues lpfc_dev_loss_tmo_handler. If fabric node recovery succeeds, then the driver reverses the devloss tmo marked kref put with a kref get. If fabric node recovery fails, then the final kref put relies on the ELS timing out or the REG_LOGIN cmpl routine.
Link: https://lore.kernel.org/r/20211020211417.88754-8-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_crtn.h | 2 + drivers/scsi/lpfc/lpfc_disc.h | 12 +++- drivers/scsi/lpfc/lpfc_els.c | 7 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 111 ++++++++++++++++++++++++++++++- drivers/scsi/lpfc/lpfc_init.c | 12 ++-- drivers/scsi/lpfc/lpfc_scsi.c | 10 +-- 6 files changed, 139 insertions(+), 15 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index c512f41991429..c9770b1d2366a 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -119,6 +119,8 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_nodelist *lpfc_nlp_init(struct lpfc_vport *vport, uint32_t did); struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); int lpfc_nlp_put(struct lpfc_nodelist *); +void lpfc_check_nlp_post_devloss(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp); void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb); int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp); diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 871b665bd72e3..37a4b79010bfc 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -85,6 +85,13 @@ enum lpfc_fc4_xpt_flags { NLP_XPT_HAS_HH = 0x10 };
+enum lpfc_nlp_save_flags { + /* devloss occurred during recovery */ + NLP_IN_RECOV_POST_DEV_LOSS = 0x1, + /* wait for outstanding LOGO to cmpl */ + NLP_WAIT_FOR_LOGO = 0x2, +}; + struct lpfc_nodelist { struct list_head nlp_listp; struct serv_parm fc_sparam; /* buffer for service params */ @@ -144,8 +151,9 @@ struct lpfc_nodelist { unsigned long *active_rrqs_xri_bitmap; struct lpfc_scsicmd_bkt *lat_data; /* Latency data */ uint32_t fc4_prli_sent; - u32 upcall_flags; -#define NLP_WAIT_FOR_LOGO 0x2 + + /* flags to keep ndlp alive until special conditions are met */ + enum lpfc_nlp_save_flags save_flags;
enum lpfc_fc4_xpt_flags fc4_xpt_flags;
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 666b0a1b558ac..1a406df251cbf 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2898,9 +2898,9 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp = &(rspiocb->iocb); spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_LOGO_SND; - if (ndlp->upcall_flags & NLP_WAIT_FOR_LOGO) { + if (ndlp->save_flags & NLP_WAIT_FOR_LOGO) { wake_up_waiter = 1; - ndlp->upcall_flags &= ~NLP_WAIT_FOR_LOGO; + ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO; } spin_unlock_irq(&ndlp->lock);
@@ -10713,6 +10713,9 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4]); goto fdisc_failed; } + + lpfc_check_nlp_post_devloss(vport, ndlp); + spin_lock_irq(shost->host_lock); vport->fc_flag &= ~FC_VPORT_CVL_RCVD; vport->fc_flag &= ~FC_VPORT_LOGO_RCVD; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index e1c02229c82d9..9ccb904e35fcf 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -209,7 +209,12 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
spin_lock_irqsave(&ndlp->lock, iflags); ndlp->nlp_flag |= NLP_IN_DEV_LOSS; - ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; + + /* If there is a PLOGI in progress, and we are in a + * NLP_NPR_2B_DISC state, don't turn off the flag. + */ + if (ndlp->nlp_state != NLP_STE_PLOGI_ISSUE) + ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
/* * The backend does not expect any more calls associated with this @@ -340,6 +345,37 @@ static void lpfc_check_inactive_vmid(struct lpfc_hba *phba) lpfc_destroy_vport_work_array(phba, vports); }
+/** + * lpfc_check_nlp_post_devloss - Check to restore ndlp refcnt after devloss + * @vport: Pointer to vport object. + * @ndlp: Pointer to remote node object. + * + * If NLP_IN_RECOV_POST_DEV_LOSS flag was set due to outstanding recovery of + * node during dev_loss_tmo processing, then this function restores the nlp_put + * kref decrement from lpfc_dev_loss_tmo_handler. + **/ +void +lpfc_check_nlp_post_devloss(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp) +{ + unsigned long iflags; + + spin_lock_irqsave(&ndlp->lock, iflags); + if (ndlp->save_flags & NLP_IN_RECOV_POST_DEV_LOSS) { + ndlp->save_flags &= ~NLP_IN_RECOV_POST_DEV_LOSS; + spin_unlock_irqrestore(&ndlp->lock, iflags); + lpfc_nlp_get(ndlp); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_NODE, + "8438 Devloss timeout reversed on DID x%x " + "refcnt %d ndlp %p flag x%x " + "port_state = x%x\n", + ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp, + ndlp->nlp_flag, vport->port_state); + spin_lock_irqsave(&ndlp->lock, iflags); + } + spin_unlock_irqrestore(&ndlp->lock, iflags); +} + /** * lpfc_dev_loss_tmo_handler - Remote node devloss timeout handler * @ndlp: Pointer to remote node object. @@ -358,6 +394,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) uint8_t *name; int warn_on = 0; int fcf_inuse = 0; + bool recovering = false; + struct fc_vport *fc_vport = NULL; unsigned long iflags;
vport = ndlp->vport; @@ -394,6 +432,64 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
/* Fabric nodes are done. */ if (ndlp->nlp_type & NLP_FABRIC) { + spin_lock_irqsave(&ndlp->lock, iflags); + /* In massive vport configuration settings, it's possible + * dev_loss_tmo fired during node recovery. So, check if + * fabric nodes are in discovery states outstanding. + */ + switch (ndlp->nlp_DID) { + case Fabric_DID: + fc_vport = vport->fc_vport; + if (fc_vport && + fc_vport->vport_state == FC_VPORT_INITIALIZING) + recovering = true; + break; + case Fabric_Cntl_DID: + if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND) + recovering = true; + break; + case FDMI_DID: + fallthrough; + case NameServer_DID: + if (ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state <= NLP_STE_REG_LOGIN_ISSUE) + recovering = true; + break; + } + spin_unlock_irqrestore(&ndlp->lock, iflags); + + /* Mark an NLP_IN_RECOV_POST_DEV_LOSS flag to know if reversing + * the following lpfc_nlp_put is necessary after fabric node is + * recovered. + */ + if (recovering) { + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY | LOG_NODE, + "8436 Devloss timeout marked on " + "DID x%x refcnt %d ndlp %p " + "flag x%x port_state = x%x\n", + ndlp->nlp_DID, kref_read(&ndlp->kref), + ndlp, ndlp->nlp_flag, + vport->port_state); + spin_lock_irqsave(&ndlp->lock, iflags); + ndlp->save_flags |= NLP_IN_RECOV_POST_DEV_LOSS; + spin_unlock_irqrestore(&ndlp->lock, iflags); + } else if (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { + /* Fabric node fully recovered before this dev_loss_tmo + * queue work is processed. Thus, ignore the + * dev_loss_tmo event. + */ + lpfc_printf_vlog(vport, KERN_INFO, + LOG_DISCOVERY | LOG_NODE, + "8437 Devloss timeout ignored on " + "DID x%x refcnt %d ndlp %p " + "flag x%x port_state = x%x\n", + ndlp->nlp_DID, kref_read(&ndlp->kref), + ndlp, ndlp->nlp_flag, + vport->port_state); + return fcf_inuse; + } + lpfc_nlp_put(ndlp); return fcf_inuse; } @@ -423,6 +519,14 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) ndlp->nlp_state, ndlp->nlp_rpi); }
+ /* If we are devloss, but we are in the process of rediscovering the + * ndlp, don't issue a NLP_EVT_DEVICE_RM event. + */ + if (ndlp->nlp_state >= NLP_STE_PLOGI_ISSUE && + ndlp->nlp_state <= NLP_STE_PRLI_ISSUE) { + return fcf_inuse; + } + if (!(ndlp->fc4_xpt_flags & NVME_XPT_REGD)) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
@@ -4351,6 +4455,8 @@ lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) goto out; }
+ lpfc_check_nlp_post_devloss(vport, ndlp); + if (phba->sli_rev < LPFC_SLI_REV4) ndlp->nlp_rpi = mb->un.varWords[0];
@@ -4528,9 +4634,10 @@ lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count) void lpfc_nlp_reg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { - unsigned long iflags;
+ lpfc_check_nlp_post_devloss(vport, ndlp); + spin_lock_irqsave(&ndlp->lock, iflags); if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) { /* Already registered with backend, trigger rescan */ diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 195169badb372..0fee8d590b0c4 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3694,12 +3694,16 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_disc_state_machine(vports[i], ndlp, NULL, NLP_EVT_DEVICE_RECOVERY);
- /* Don't remove the node unless the + /* Don't remove the node unless the node * has been unregistered with the - * transport. If so, let dev_loss - * take care of the node. + * transport, and we're not in recovery + * before dev_loss_tmo triggered. + * Otherwise, let dev_loss take care of + * the node. */ - if (!(ndlp->fc4_xpt_flags & + if (!(ndlp->save_flags & + NLP_IN_RECOV_POST_DEV_LOSS) && + !(ndlp->fc4_xpt_flags & (NVME_XPT_REGD | SCSI_XPT_REGD))) lpfc_disc_state_machine (vports[i], ndlp, diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 364c8a9b99095..3d9175f1b6787 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6455,28 +6455,28 @@ lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
/* Issue LOGO, if no LOGO is outstanding */ spin_lock_irqsave(&pnode->lock, flags); - if (!(pnode->upcall_flags & NLP_WAIT_FOR_LOGO) && + if (!(pnode->save_flags & NLP_WAIT_FOR_LOGO) && !pnode->logo_waitq) { pnode->logo_waitq = &waitq; pnode->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; pnode->nlp_flag |= NLP_ISSUE_LOGO; - pnode->upcall_flags |= NLP_WAIT_FOR_LOGO; + pnode->save_flags |= NLP_WAIT_FOR_LOGO; spin_unlock_irqrestore(&pnode->lock, flags); lpfc_unreg_rpi(vport, pnode); wait_event_timeout(waitq, - (!(pnode->upcall_flags & + (!(pnode->save_flags & NLP_WAIT_FOR_LOGO)), msecs_to_jiffies(dev_loss_tmo * 1000));
- if (pnode->upcall_flags & NLP_WAIT_FOR_LOGO) { + if (pnode->save_flags & NLP_WAIT_FOR_LOGO) { lpfc_printf_vlog(vport, KERN_ERR, logit, "0725 SCSI layer TGTRST " "failed & LOGO TMO (%d, %llu) " "return x%x\n", tgt_id, lun_id, status); spin_lock_irqsave(&pnode->lock, flags); - pnode->upcall_flags &= ~NLP_WAIT_FOR_LOGO; + pnode->save_flags &= ~NLP_WAIT_FOR_LOGO; } else { spin_lock_irqsave(&pnode->lock, flags); }
From: Dmitry Osipenko digetx@gmail.com
[ Upstream commit 14b43c20c283de36131da0cb44f3170b9ffa7630 ]
Tegra20 EMC driver uses simple devfreq governor. Add simple devfreq governor to the list of the Tegra20 EMC driver module softdeps to allow userspace initramfs tools like dracut to automatically pull the devfreq module into ramfs image together with the EMC module.
Reported-by: Nicolas Chauvet kwizart@gmail.com Suggested-by: Nicolas Chauvet kwizart@gmail.com Signed-off-by: Dmitry Osipenko digetx@gmail.com Link: https://lore.kernel.org/r/20211019231524.888-1-digetx@gmail.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memory/tegra/tegra20-emc.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index c3462dbc8c22b..6fc90f2160e93 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -1117,4 +1117,5 @@ module_platform_driver(tegra_emc_driver);
MODULE_AUTHOR("Dmitry Osipenko digetx@gmail.com"); MODULE_DESCRIPTION("NVIDIA Tegra20 EMC driver"); +MODULE_SOFTDEP("pre: governor_simpleondemand"); MODULE_LICENSE("GPL v2");
From: Anatolij Gustschin agust@denx.de
[ Upstream commit aed2886a5e9ffc8269a4220bff1e9e030d3d2eb1 ]
Fixes build warnings: Warning (unit_address_vs_reg): /memory: node has a reg or ranges property, but no unit name
Signed-off-by: Anatolij Gustschin agust@denx.de Reviewed-by: Rob Herring robh@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211013220532.24759-4-agust@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/boot/dts/charon.dts | 2 +- arch/powerpc/boot/dts/digsy_mtc.dts | 2 +- arch/powerpc/boot/dts/lite5200.dts | 2 +- arch/powerpc/boot/dts/lite5200b.dts | 2 +- arch/powerpc/boot/dts/media5200.dts | 2 +- arch/powerpc/boot/dts/mpc5200b.dtsi | 2 +- arch/powerpc/boot/dts/o2d.dts | 2 +- arch/powerpc/boot/dts/o2d.dtsi | 2 +- arch/powerpc/boot/dts/o2dnt2.dts | 2 +- arch/powerpc/boot/dts/o3dnt.dts | 2 +- arch/powerpc/boot/dts/pcm032.dts | 2 +- arch/powerpc/boot/dts/tqm5200.dts | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts index 408b486b13dff..cd589539f313f 100644 --- a/arch/powerpc/boot/dts/charon.dts +++ b/arch/powerpc/boot/dts/charon.dts @@ -35,7 +35,7 @@ }; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB }; diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts index 0e5e9d3acf79f..19a14e62e65f4 100644 --- a/arch/powerpc/boot/dts/digsy_mtc.dts +++ b/arch/powerpc/boot/dts/digsy_mtc.dts @@ -16,7 +16,7 @@ model = "intercontrol,digsy-mtc"; compatible = "intercontrol,digsy-mtc";
- memory { + memory@0 { reg = <0x00000000 0x02000000>; // 32MB };
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts index cb2782dd6132c..e7b194775d783 100644 --- a/arch/powerpc/boot/dts/lite5200.dts +++ b/arch/powerpc/boot/dts/lite5200.dts @@ -32,7 +32,7 @@ }; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; // 64MB }; diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts index 2b86c81f90485..547cbe726ff23 100644 --- a/arch/powerpc/boot/dts/lite5200b.dts +++ b/arch/powerpc/boot/dts/lite5200b.dts @@ -31,7 +31,7 @@ led4 { gpios = <&gpio_simple 2 1>; }; };
- memory { + memory@0 { reg = <0x00000000 0x10000000>; // 256MB };
diff --git a/arch/powerpc/boot/dts/media5200.dts b/arch/powerpc/boot/dts/media5200.dts index 61cae9dcddef4..f3188018faceb 100644 --- a/arch/powerpc/boot/dts/media5200.dts +++ b/arch/powerpc/boot/dts/media5200.dts @@ -32,7 +32,7 @@ }; };
- memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB RAM };
diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi index 648fe31795f49..8b796f3b11da7 100644 --- a/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/arch/powerpc/boot/dts/mpc5200b.dtsi @@ -33,7 +33,7 @@ }; };
- memory: memory { + memory: memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; // 64MB }; diff --git a/arch/powerpc/boot/dts/o2d.dts b/arch/powerpc/boot/dts/o2d.dts index 24a46f65e5299..e0a8d3034417f 100644 --- a/arch/powerpc/boot/dts/o2d.dts +++ b/arch/powerpc/boot/dts/o2d.dts @@ -12,7 +12,7 @@ model = "ifm,o2d"; compatible = "ifm,o2d";
- memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB };
diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi index 6661955a2be47..b55a9e5bd828c 100644 --- a/arch/powerpc/boot/dts/o2d.dtsi +++ b/arch/powerpc/boot/dts/o2d.dtsi @@ -19,7 +19,7 @@ model = "ifm,o2d"; compatible = "ifm,o2d";
- memory { + memory@0 { reg = <0x00000000 0x04000000>; // 64MB };
diff --git a/arch/powerpc/boot/dts/o2dnt2.dts b/arch/powerpc/boot/dts/o2dnt2.dts index eeba7f5507d5d..c2eedbd1f5fcb 100644 --- a/arch/powerpc/boot/dts/o2dnt2.dts +++ b/arch/powerpc/boot/dts/o2dnt2.dts @@ -12,7 +12,7 @@ model = "ifm,o2dnt2"; compatible = "ifm,o2d";
- memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB };
diff --git a/arch/powerpc/boot/dts/o3dnt.dts b/arch/powerpc/boot/dts/o3dnt.dts index fd00396b0593e..e4c1bdd412716 100644 --- a/arch/powerpc/boot/dts/o3dnt.dts +++ b/arch/powerpc/boot/dts/o3dnt.dts @@ -12,7 +12,7 @@ model = "ifm,o3dnt"; compatible = "ifm,o2d";
- memory { + memory@0 { reg = <0x00000000 0x04000000>; // 64MB };
diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts index 780e13d99e7b8..1895bc95900cc 100644 --- a/arch/powerpc/boot/dts/pcm032.dts +++ b/arch/powerpc/boot/dts/pcm032.dts @@ -20,7 +20,7 @@ model = "phytec,pcm032"; compatible = "phytec,pcm032";
- memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB };
diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts index 9ed0bc78967e1..5bb25a9e40a01 100644 --- a/arch/powerpc/boot/dts/tqm5200.dts +++ b/arch/powerpc/boot/dts/tqm5200.dts @@ -32,7 +32,7 @@ }; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; // 64MB };
From: David Heidelberg david@ixit.cz
[ Upstream commit 14a1f6c9d8017ffbf388e82e1a1f023196d98612 ]
Fixes warnings regarding to memory and mdio nodes and apply new naming following dt-schema.
Signed-off-by: David Heidelberg david@ixit.cz Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211020214741.261509-1-david@ixit.cz Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-ipq8064-rb3011.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts index f7ea2e5dd1914..971d2e2292600 100644 --- a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts +++ b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts @@ -19,12 +19,12 @@ stdout-path = "serial0:115200n8"; };
- memory@0 { + memory@42000000 { reg = <0x42000000 0x3e000000>; device_type = "memory"; };
- mdio0: mdio@0 { + mdio0: mdio-0 { status = "okay"; compatible = "virtual,mdio-gpio"; gpios = <&qcom_pinmux 1 GPIO_ACTIVE_HIGH>, @@ -91,7 +91,7 @@ }; };
- mdio1: mdio@1 { + mdio1: mdio-1 { status = "okay"; compatible = "virtual,mdio-gpio"; gpios = <&qcom_pinmux 11 GPIO_ACTIVE_HIGH>,
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 179811bebc7b91e0f9d0adee9bfa3d2af9c43869 ]
According to the new DT schema for qcom,rpm-msg-ram the node name should be sram@. memory@ is reserved for definition of physical RAM (usable by Linux).
This fixes the following dtbs_check error on various device trees: memory@60000: 'device_type' is a required property From schema: dtschema/schemas/memory.yaml
Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211018110009.30837-1-stephan@gerhold.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8994.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8996.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8998.dtsi | 2 +- arch/arm64/boot/dts/qcom/qcs404.dtsi | 2 +- arch/arm64/boot/dts/qcom/sdm630.dtsi | 2 +- arch/arm64/boot/dts/qcom/sm6125.dtsi | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-)
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -445,7 +445,7 @@ }; };
- rpm_msg_ram: memory@60000 { + rpm_msg_ram: sram@60000 { compatible = "qcom,rpm-msg-ram"; reg = <0x00060000 0x8000>; }; --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -715,7 +715,7 @@ reg = <0xfc400000 0x2000>; };
- rpm_msg_ram: memory@fc428000 { + rpm_msg_ram: sram@fc428000 { compatible = "qcom,rpm-msg-ram"; reg = <0xfc428000 0x4000>; }; --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -638,7 +638,7 @@ }; };
- rpm_msg_ram: memory@68000 { + rpm_msg_ram: sram@68000 { compatible = "qcom,rpm-msg-ram"; reg = <0x00068000 0x6000>; }; --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -861,7 +861,7 @@ reg = <0x00100000 0xb0000>; };
- rpm_msg_ram: memory@778000 { + rpm_msg_ram: sram@778000 { compatible = "qcom,rpm-msg-ram"; reg = <0x00778000 0x7000>; }; --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -318,7 +318,7 @@ status = "disabled"; };
- rpm_msg_ram: memory@60000 { + rpm_msg_ram: sram@60000 { compatible = "qcom,rpm-msg-ram"; reg = <0x00060000 0x6000>; }; --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi @@ -541,7 +541,7 @@ <&sleep_clk>; };
- rpm_msg_ram: memory@778000 { + rpm_msg_ram: sram@778000 { compatible = "qcom,rpm-msg-ram"; reg = <0x00778000 0x7000>; }; --- a/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -380,7 +380,7 @@ status = "disabled"; };
- rpm_msg_ram: memory@45f0000 { + rpm_msg_ram: sram@45f0000 { compatible = "qcom,rpm-msg-ram"; reg = <0x045f0000 0x7000>; };
From: Chengfeng Ye cyeaa@connect.ust.hk
[ Upstream commit a0d21bb3279476c777434c40d969ea88ca64f9aa ]
The pointer block return from snd_gf1_dma_next_block could be null, so there is a potential null pointer dereference issue. Fix this by adding a null check before dereference.
Signed-off-by: Chengfeng Ye cyeaa@connect.ust.hk Link: https://lore.kernel.org/r/20211024104611.9919-1-cyeaa@connect.ust.hk Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/isa/gus/gus_dma.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index a1c770d826dda..6d664dd8dde0b 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c @@ -126,6 +126,8 @@ static void snd_gf1_dma_interrupt(struct snd_gus_card * gus) } block = snd_gf1_dma_next_block(gus); spin_unlock(&gus->dma_lock); + if (!block) + return; snd_gf1_dma_program(gus, block->addr, block->buf_addr, block->count, (unsigned short) block->cmd); kfree(block); #if 0
From: Chengfeng Ye cyeaa@connect.ust.hk
[ Upstream commit b97053df0f04747c3c1e021ecbe99db675342954 ]
The pointer cs_desc return from snd_usb_find_clock_source could be null, so there is a potential null pointer dereference issue. Fix this by adding a null check before dereference.
Signed-off-by: Chengfeng Ye cyeaa@connect.ust.hk Link: https://lore.kernel.org/r/20211024111736.11342-1-cyeaa@connect.ust.hk Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/clock.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 81d5ce07d548b..98345a695dccb 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -496,6 +496,10 @@ int snd_usb_set_sample_rate_v2v3(struct snd_usb_audio *chip, union uac23_clock_source_desc *cs_desc;
cs_desc = snd_usb_find_clock_source(chip, clock, fmt->protocol); + + if (!cs_desc) + return 0; + if (fmt->protocol == UAC_VERSION_3) bmControls = le32_to_cpu(cs_desc->v3.bmControls); else
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit facb87ad75603813bc3b1314f5a87377f020fcb8 ]
On SAMA7G5 the prescaler part of master clock has been implemented as a changeable one. Everytime the prescaler is changed the PMC_SR.MCKRDY bit must be polled. Value 1 for PMC_SR.MCKRDY means the prescaler update is done. Driver polls for this bit until it becomes 1. On SAMA7G5 it has been discovered that in some conditions the PMC_SR.MCKRDY is not rising but the rate it provides it's stable. The workaround is to add a timeout when polling for PMC_SR.MCKRDY. At the moment, for SAMA7G5, the prescaler will be removed from Linux clock tree as all the frequencies for CPU could be obtained from PLL and also there will be less overhead when changing frequency via DVFS.
Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20211011112719.3951784-14-claudiu.beznea@microchip... Acked-by: Nicolas Ferre nicolas.ferre@microchip.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/at91/sama7g5.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c index cf8c079aa086a..019e712f90d6f 100644 --- a/drivers/clk/at91/sama7g5.c +++ b/drivers/clk/at91/sama7g5.c @@ -982,16 +982,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) }
parent_names[0] = "cpupll_divpmcck"; - hw = at91_clk_register_master_pres(regmap, "cpuck", 1, parent_names, - &mck0_layout, &mck0_characteristics, - &pmc_mck0_lock, - CLK_SET_RATE_PARENT, 0); - if (IS_ERR(hw)) - goto err_free; - - sama7g5_pmc->chws[PMC_CPU] = hw; - - hw = at91_clk_register_master_div(regmap, "mck0", "cpuck", + hw = at91_clk_register_master_div(regmap, "mck0", "cpupll_divpmcck", &mck0_layout, &mck0_characteristics, &pmc_mck0_lock, 0); if (IS_ERR(hw))
From: Sven Peter sven@svenpeter.dev
[ Upstream commit 5a009fc1364170b240a4d351b345e69bb3728b3e ]
DART has an additional global register to control which streams are isolated. This register is a bit redundant since DART_TCR can already be used to control isolation and is usually initialized to DART_STREAM_ALL by the time we get control. Some DARTs (namely the one used for the audio controller) however have some streams disabled initially. Make sure those work by initializing DART_STREAMS_ENABLE during reset.
Reported-by: Martin Povišer povik@protonmail.com Signed-off-by: Sven Peter sven@svenpeter.dev Reviewed-by: Hector Martin marcan@marcan.st Link: https://lore.kernel.org/r/20211019162253.45919-1-sven@svenpeter.dev Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/apple-dart.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index fdfa39ec2a4d4..ad69eeb5ac5ba 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -70,6 +70,8 @@ #define DART_ERROR_ADDR_HI 0x54 #define DART_ERROR_ADDR_LO 0x50
+#define DART_STREAMS_ENABLE 0xfc + #define DART_TCR(sid) (0x100 + 4 * (sid)) #define DART_TCR_TRANSLATE_ENABLE BIT(7) #define DART_TCR_BYPASS0_ENABLE BIT(8) @@ -301,6 +303,9 @@ static int apple_dart_hw_reset(struct apple_dart *dart) apple_dart_hw_disable_dma(&stream_map); apple_dart_hw_clear_all_ttbrs(&stream_map);
+ /* enable all streams globally since TCR is used to control isolation */ + writel(DART_STREAM_ALL, dart->regs + DART_STREAMS_ENABLE); + /* clear any pending errors before the interrupt is unmasked */ writel(readl(dart->regs + DART_ERROR), dart->regs + DART_ERROR);
From: Michael Ellerman mpe@ellerman.id.au
[ Upstream commit fef071be57dc43679a32d5b0e6ee176d6f12e9f2 ]
In dcr-low.S we use cmpli with three arguments, instead of four arguments as defined in the ISA:
cmpli cr0,r3,1024
This appears to be a PPC440-ism, looking at the "PPC440x5 CPU Core User’s Manual" it shows cmpli having no L field, but implied to be 0 due to the core being 32-bit. It mentions that the ISA defines four arguments and recommends using cmplwi.
It also corresponds to the old POWER instruction set, which had no L field there, a reserved bit instead.
dcr-low.S is only built 32-bit, because it is only built when DCR_NATIVE=y, which is only selected by 40x and 44x. Looking at the generated code (with gcc/gas) we see cmplwi as expected.
Although gas is happy with the 3-argument version when building for 32-bit, the LLVM assembler is not and errors out with:
arch/powerpc/sysdev/dcr-low.S:27:10: error: invalid operand for instruction cmpli 0,%r3,1024; ... ^
Switch to the cmplwi extended opcode, which avoids any confusion when reading the ISA, fixes the issue with the LLVM assembler, and also means the code could be built 64-bit in future (though that's very unlikely).
Reported-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au BugLink: https://github.com/ClangBuiltLinux/linux/issues/1419 Link: https://lore.kernel.org/r/20211014024424.528848-1-mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/sysdev/dcr-low.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S index efeeb1b885a17..329b9c4ae5429 100644 --- a/arch/powerpc/sysdev/dcr-low.S +++ b/arch/powerpc/sysdev/dcr-low.S @@ -11,7 +11,7 @@ #include <asm/export.h>
#define DCR_ACCESS_PROLOG(table) \ - cmpli cr0,r3,1024; \ + cmplwi cr0,r3,1024; \ rlwinm r3,r3,4,18,27; \ lis r5,table@h; \ ori r5,r5,table@l; \
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit c12ab8dbc492b992e1ea717db933cee568780c47 ]
Until now, all tests involving CONFIG_STRICT_KERNEL_RWX were done with DEBUG_RODATA_TEST to check the result. But now that CONFIG_STRICT_KERNEL_RWX is selected by default, it came without CONFIG_DEBUG_RODATA_TEST and led to the following Oops
[ 6.830908] Freeing unused kernel image (initmem) memory: 352K [ 6.840077] BUG: Unable to handle kernel data access on write at 0xc1285200 [ 6.846836] Faulting instruction address: 0xc0004b6c [ 6.851745] Oops: Kernel access of bad area, sig: 11 [#1] [ 6.857075] BE PAGE_SIZE=16K PREEMPT CMPC885 [ 6.861348] SAF3000 DIE NOTIFICATION [ 6.864830] CPU: 0 PID: 1 Comm: swapper Not tainted 5.15.0-rc5-s3k-dev-02255-g2747d7b7916f #451 [ 6.873429] NIP: c0004b6c LR: c0004b60 CTR: 00000000 [ 6.878419] REGS: c902be60 TRAP: 0300 Not tainted (5.15.0-rc5-s3k-dev-02255-g2747d7b7916f) [ 6.886852] MSR: 00009032 <EE,ME,IR,DR,RI> CR: 53000335 XER: 8000ff40 [ 6.893564] DAR: c1285200 DSISR: 82000000 [ 6.893564] GPR00: 0c000000 c902bf20 c20f4000 08000000 00000001 04001f00 c1800000 00000035 [ 6.893564] GPR08: ff0001ff c1280000 00000002 c0004b60 00001000 00000000 c0004b1c 00000000 [ 6.893564] GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 6.893564] GPR24: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c1060000 [ 6.932034] NIP [c0004b6c] kernel_init+0x50/0x138 [ 6.936682] LR [c0004b60] kernel_init+0x44/0x138 [ 6.941245] Call Trace: [ 6.943653] [c902bf20] [c0004b60] kernel_init+0x44/0x138 (unreliable) [ 6.950022] [c902bf30] [c001122c] ret_from_kernel_thread+0x5c/0x64 [ 6.956135] Instruction dump: [ 6.959060] 48ffc521 48045469 4800d8cd 3d20c086 89295fa0 2c090000 41820058 480796c9 [ 6.966890] 4800e48d 3d20c128 39400002 3fe0c106 <91495200> 3bff8000 4806fa1d 481f7d75 [ 6.974902] ---[ end trace 1e397bacba4aa610 ]---
0xc1285200 corresponds to 'system_state' global var that the kernel is trying to set to SYSTEM_RUNNING. This var is above the RO/RW limit so it shouldn't Oops.
It oopses because the dirty bit is missing.
Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/3d5800b0bbcd7b19761b98f50421358667b45331.163552023... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/head_8xx.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 9bdb95f5694f7..2d596881b70e7 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -755,7 +755,7 @@ _GLOBAL(mmu_pin_tlb) cmplw r6, r9 bdnzt lt, 2b
-4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) +4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) 2: ori r0, r6, MD_EVALID mtspr SPRN_MD_CTR, r5 mtspr SPRN_MD_EPN, r0
From: Nick Desaulniers ndesaulniers@google.com
[ Upstream commit 0e38225c92c7964482a8bb6b3e37fde4319e965c ]
request_irq is marked __must_check, but the call in shx3_prepare_cpus has a void return type, so it can't propagate failure to the caller. Follow cues from hexagon and just print an error.
Fixes: c7936b9abcf5 ("sh: smp: Hook in to the generic IPI handler for SH-X3 SMP.") Cc: Miguel Ojeda miguel.ojeda.sandonis@gmail.com Cc: Paul Mundt lethal@linux-sh.org Reported-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Nick Desaulniers ndesaulniers@google.com Tested-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Reviewed-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Rich Felker dalias@libc.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/kernel/cpu/sh4a/smp-shx3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c index f8a2bec0f260b..1261dc7b84e8b 100644 --- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -73,8 +73,9 @@ static void shx3_prepare_cpus(unsigned int max_cpus) BUILD_BUG_ON(SMP_MSG_NR >= 8);
for (i = 0; i < SMP_MSG_NR; i++) - request_irq(104 + i, ipi_interrupt_handler, - IRQF_PERCPU, "IPI", (void *)(long)i); + if (request_irq(104 + i, ipi_interrupt_handler, + IRQF_PERCPU, "IPI", (void *)(long)i)) + pr_err("Failed to request irq %d\n", i);
for (i = 0; i < max_cpus; i++) set_cpu_present(i, true);
From: Lu Wei luwei32@huawei.com
[ Upstream commit bde82ee391fa6d3ad054313c4aa7b726d32515ce ]
If KMEM_CACHE or maple_alloc_dev failed, the maple_bus_init() will return 0 rather than error, because the retval is not changed after KMEM_CACHE or maple_alloc_dev failed.
Fixes: 17be2d2b1c33 ("sh: Add maple bus support for the SEGA Dreamcast.") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Lu Wei luwei32@huawei.com Acked-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Rich Felker dalias@libc.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/sh/maple/maple.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index bd0fbcdbdefe9..e24e220e56eea 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -834,8 +834,10 @@ static int __init maple_bus_init(void)
maple_queue_cache = KMEM_CACHE(maple_buffer, SLAB_HWCACHE_ALIGN);
- if (!maple_queue_cache) + if (!maple_queue_cache) { + retval = -ENOMEM; goto cleanup_bothirqs; + }
INIT_LIST_HEAD(&maple_waitq); INIT_LIST_HEAD(&maple_sentq); @@ -848,6 +850,7 @@ static int __init maple_bus_init(void) if (!mdev[i]) { while (i-- > 0) maple_free_dev(mdev[i]); + retval = -ENOMEM; goto cleanup_cache; } baseunits[i] = mdev[i];
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit 70a9ac36ffd807ac506ed0b849f3e8ce3c6623f2 ]
Fix up a misuse that the filename pointer isn't always valid in the ring buffer, and we should copy the content instead.
Fixes: 0c5e36db17f5 ("f2fs: trace f2fs_lookup") Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/trace/events/f2fs.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 4e881d91c8744..4cb055af1ec0b 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -807,20 +807,20 @@ TRACE_EVENT(f2fs_lookup_start, TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) - __field(const char *, name) + __string(name, dentry->d_name.name) __field(unsigned int, flags) ),
TP_fast_assign( __entry->dev = dir->i_sb->s_dev; __entry->ino = dir->i_ino; - __entry->name = dentry->d_name.name; + __assign_str(name, dentry->d_name.name); __entry->flags = flags; ),
TP_printk("dev = (%d,%d), pino = %lu, name:%s, flags:%u", show_dev_ino(__entry), - __entry->name, + __get_str(name), __entry->flags) );
@@ -834,7 +834,7 @@ TRACE_EVENT(f2fs_lookup_end, TP_STRUCT__entry( __field(dev_t, dev) __field(ino_t, ino) - __field(const char *, name) + __string(name, dentry->d_name.name) __field(nid_t, cino) __field(int, err) ), @@ -842,14 +842,14 @@ TRACE_EVENT(f2fs_lookup_end, TP_fast_assign( __entry->dev = dir->i_sb->s_dev; __entry->ino = dir->i_ino; - __entry->name = dentry->d_name.name; + __assign_str(name, dentry->d_name.name); __entry->cino = ino; __entry->err = err; ),
TP_printk("dev = (%d,%d), pino = %lu, name:%s, ino:%u, err:%d", show_dev_ino(__entry), - __entry->name, + __get_str(name), __entry->cino, __entry->err) );
From: Keoseong Park keosung.park@samsung.com
[ Upstream commit 011e0868e0cf1237675b22e36fffa958fb08f46e ]
Since active_logs can be set to 2 or 4 or NR_CURSEG_PERSIST_TYPE(6), it cannot be set to NR_CURSEG_TYPE(8). That is, whint_mode is always off.
Therefore, the condition is changed from NR_CURSEG_TYPE to NR_CURSEG_PERSIST_TYPE.
Cc: Chao Yu chao@kernel.org Fixes: d0b9e42ab615 (f2fs: introduce inmem curseg) Reported-by: tanghuan tanghuan@vivo.com Signed-off-by: Keoseong Park keosung.park@samsung.com Signed-off-by: Fengnan Chang changfengnan@vivo.com Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index dbe040b66802c..4d24146b4f471 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1292,7 +1292,7 @@ default_check: /* Not pass down write hints if the number of active logs is lesser * than NR_CURSEG_PERSIST_TYPE. */ - if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE) + if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_PERSIST_TYPE) F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) {
From: Chao Yu chao@kernel.org
[ Upstream commit cd6d697a6e2013a0a85f8b261b16c8cfd50c1f5f ]
In f2fs_balance_fs_bg(), it needs to check both NAT_ENTRIES and INO_ENTRIES memory usage to decide whether we should skip background checkpoint, otherwise we may always skip checking INO_ENTRIES memory usage, so that INO_ENTRIES may potentially cause high memory footprint.
Fixes: 493720a48543 ("f2fs: fix to avoid REQ_TIME and CP_TIME collision") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/segment.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index a135d22474154..d716553bdc025 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -561,7 +561,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg) goto do_sync;
/* checkpoint is the only way to shrink partial cached entries */ - if (f2fs_available_free_memory(sbi, NAT_ENTRIES) || + if (f2fs_available_free_memory(sbi, NAT_ENTRIES) && f2fs_available_free_memory(sbi, INO_ENTRIES)) return;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit fda1bc533094a7db68b11e7503d2c6c73993d12a ]
FRAME_POINTER depends on DEBUG_KERNEL so DWARF_UNWINDER should depend on DEBUG_KERNEL before selecting FRAME_POINTER.
WARNING: unmet direct dependencies detected for FRAME_POINTER Depends on [n]: DEBUG_KERNEL [=n] && (M68K || UML || SUPERH [=y]) || ARCH_WANT_FRAME_POINTERS [=n] Selected by [y]: - DWARF_UNWINDER [=y]
Fixes: bd353861c735 ("sh: dwarf unwinder support.") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Matt Fleming matt@console-pimps.org Cc: Matt Fleming matt@codeblueprint.co.uk Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Cc: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Tested-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Rich Felker dalias@libc.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/Kconfig.debug | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 958f790273ab9..10290e5c1f438 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -54,6 +54,7 @@ config DUMP_CODE
config DWARF_UNWINDER bool "Enable the DWARF unwinder for stacktraces" + depends on DEBUG_KERNEL select FRAME_POINTER default n help
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit e25c252a9b033523c626f039d4b9a304f12f6775 ]
Delete ieee_fpe_handler() since it is not used. After that is done, delete denormal_to_double() since it is not used:
.../arch/sh/math-emu/math.c:505:12: error: 'ieee_fpe_handler' defined but not used [-Werror=unused-function] 505 | static int ieee_fpe_handler(struct pt_regs *regs)
.../arch/sh/math-emu/math.c:477:13: error: 'denormal_to_double' defined but not used [-Werror=unused-function] 477 | static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n)
Fixes: 7caf62de25554da3 ("sh: remove unused do_fpu_error") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Takashi YOSHII takasi-y@ops.dti.ne.jp Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Rich Felker dalias@libc.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/math-emu/math.c | 103 ---------------------------------------- 1 file changed, 103 deletions(-)
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c index e8be0eca0444a..615ba932c398e 100644 --- a/arch/sh/math-emu/math.c +++ b/arch/sh/math-emu/math.c @@ -467,109 +467,6 @@ static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_reg return id_sys(fregs, regs, code); }
-/** - * denormal_to_double - Given denormalized float number, - * store double float - * - * @fpu: Pointer to sh_fpu_soft structure - * @n: Index to FP register - */ -static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n) -{ - unsigned long du, dl; - unsigned long x = fpu->fpul; - int exp = 1023 - 126; - - if (x != 0 && (x & 0x7f800000) == 0) { - du = (x & 0x80000000); - while ((x & 0x00800000) == 0) { - x <<= 1; - exp--; - } - x &= 0x007fffff; - du |= (exp << 20) | (x >> 3); - dl = x << 29; - - fpu->fp_regs[n] = du; - fpu->fp_regs[n+1] = dl; - } -} - -/** - * ieee_fpe_handler - Handle denormalized number exception - * - * @regs: Pointer to register structure - * - * Returns 1 when it's handled (should not cause exception). - */ -static int ieee_fpe_handler(struct pt_regs *regs) -{ - unsigned short insn = *(unsigned short *)regs->pc; - unsigned short finsn; - unsigned long nextpc; - int nib[4] = { - (insn >> 12) & 0xf, - (insn >> 8) & 0xf, - (insn >> 4) & 0xf, - insn & 0xf}; - - if (nib[0] == 0xb || - (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */ - regs->pr = regs->pc + 4; - - if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */ - nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3); - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */ - if (regs->sr & 1) - nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); - else - nextpc = regs->pc + 4; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */ - if (regs->sr & 1) - nextpc = regs->pc + 4; - else - nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x4 && nib[3] == 0xb && - (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */ - nextpc = regs->regs[nib[1]]; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x0 && nib[3] == 0x3 && - (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */ - nextpc = regs->pc + 4 + regs->regs[nib[1]]; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (insn == 0x000b) { /* rts */ - nextpc = regs->pr; - finsn = *(unsigned short *) (regs->pc + 2); - } else { - nextpc = regs->pc + 2; - finsn = insn; - } - - if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ - struct task_struct *tsk = current; - - if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) { - /* FPU error */ - denormal_to_double (&tsk->thread.xstate->softfpu, - (finsn >> 8) & 0xf); - tsk->thread.xstate->softfpu.fpscr &= - ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); - task_thread_info(tsk)->status |= TS_USEDFPU; - } else { - force_sig_fault(SIGFPE, FPE_FLTINV, - (void __user *)regs->pc); - } - - regs->pc = nextpc; - return 1; - } - - return 0; -} - /** * fpu_init - Initialize FPU registers * @fpu: Pointer to software emulated FPU registers.
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit b929926f01f2d14635345d22eafcf60feed1085e ]
Fix this by defining both ENDIAN macros in <asm/sfp-machine.h> so that they can be utilized in <math-emu/soft-fp.h> according to the latter's comment: /* Allow sfp-machine to have its own byte order definitions. */
(This is what is done in arch/nds32/include/asm/sfp-machine.h.)
This placates these build warnings:
In file included from ../arch/sh/math-emu/math.c:23: .../include/math-emu/single.h:50:21: warning: "__BIG_ENDIAN" is not defined, evaluates to 0 [-Wundef] 50 | #if __BYTE_ORDER == __BIG_ENDIAN In file included from ../arch/sh/math-emu/math.c:24: .../include/math-emu/double.h:59:21: warning: "__BIG_ENDIAN" is not defined, evaluates to 0 [-Wundef] 59 | #if __BYTE_ORDER == __BIG_ENDIAN
Fixes: 4b565680d163 ("sh: math-emu support") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Tested-by: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Rich Felker dalias@libc.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/include/asm/sfp-machine.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/sh/include/asm/sfp-machine.h b/arch/sh/include/asm/sfp-machine.h index cbc7cf8c97ce6..2d2423478b71d 100644 --- a/arch/sh/include/asm/sfp-machine.h +++ b/arch/sh/include/asm/sfp-machine.h @@ -13,6 +13,14 @@ #ifndef _SFP_MACHINE_H #define _SFP_MACHINE_H
+#ifdef __BIG_ENDIAN__ +#define __BYTE_ORDER __BIG_ENDIAN +#define __LITTLE_ENDIAN 0 +#else +#define __BYTE_ORDER __LITTLE_ENDIAN +#define __BIG_ENDIAN 0 +#endif + #define _FP_W_TYPE_SIZE 32 #define _FP_W_TYPE unsigned long #define _FP_WS_TYPE signed long
From: Hyeong-Jun Kim hj514.kim@samsung.com
[ Upstream commit 02d58cd253d7536c412993573fc6b3b4454960eb ]
Compresse file and normal file has differ in i_addr addressing, specifically addrs per inode/block. So, we will face data loss, if we disable the compression flag on non-empty files. Therefore we should disallow not only enabling but disabling the compression flag on non-empty files.
Fixes: 4c8ff7095bef ("f2fs: support data compression") Signed-off-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Hyeong-Jun Kim hj514.kim@samsung.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/f2fs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b339ae89c1ad1..c242274e3479b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4152,8 +4152,7 @@ static inline bool f2fs_disable_compressed_file(struct inode *inode)
if (!f2fs_compressed_file(inode)) return true; - if (S_ISREG(inode->i_mode) && - (get_dirty_pages(inode) || atomic_read(&fi->i_compr_blocks))) + if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode)) return false;
fi->i_flags &= ~F2FS_COMPR_FL;
From: Chao Yu chao@kernel.org
[ Upstream commit ca98d72141dd81f42893a9a43d7ededab3355fba ]
As Pavel Machek reported in [1]
This code looks quite confused: part of function returns 1 on corruption, part returns -errno. The problem is not stable-specific.
[1] https://lkml.org/lkml/2021/9/19/207
Let's fix to make 'insane cp_payload case' to return 1 rater than EFSCORRUPTED, so that return value can be kept consistent for all error cases, it can avoid confusion of code logic.
Fixes: 65ddf6564843 ("f2fs: fix to do sanity check for sb/cp fields correctly") Reported-by: Pavel Machek pavel@denx.de Reviewed-by: Pavel Machek pavel@denx.de Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 4d24146b4f471..8795a5a8d4e89 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3487,7 +3487,7 @@ skip_cross: NR_CURSEG_PERSIST_TYPE + nat_bits_blocks >= blocks_per_seg)) { f2fs_warn(sbi, "Insane cp_payload: %u, nat_bits_blocks: %u)", cp_payload, nat_bits_blocks); - return -EFSCORRUPTED; + return 1; }
if (unlikely(f2fs_cp_error(sbi))) {
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit ed84ef1cd7eddf933d4ffce2caa8161d6f947245 ]
Two fixes in one:
- In the "impose hardware constraints" block, the "logical" divider value (aka. not translated to the hardware) was clamped to fit in the register area, but this totally ignored the fact that the divider value can itself have a fixed divider.
- The code that made sure that the divider value returned by the function was a multiple of its own fixed divider could result in a wrong value being calculated, because it was rounded down instead of rounded up.
Fixes: 4afe2d1a6ed5 ("clk: ingenic: Allow divider value to be divided") Co-developed-by: Artur Rojek contact@artur-rojek.eu Signed-off-by: Artur Rojek contact@artur-rojek.eu Signed-off-by: Paul Cercueil paul@crapouillou.net Link: https://lore.kernel.org/r/20211001172033.122329-1-paul@crapouillou.net Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/ingenic/cgu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 266c7595d3302..af31633a8862e 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -453,15 +453,15 @@ ingenic_clk_calc_div(struct clk_hw *hw, }
/* Impose hardware constraints */ - div = min_t(unsigned, div, 1 << clk_info->div.bits); - div = max_t(unsigned, div, 1); + div = clamp_t(unsigned int, div, clk_info->div.div, + clk_info->div.div << clk_info->div.bits);
/* * If the divider value itself must be divided before being written to * the divider register, we must ensure we don't have any bits set that * would be lost as a result of doing so. */ - div /= clk_info->div.div; + div = DIV_ROUND_UP(div, clk_info->div.div); div *= clk_info->div.div;
return div;
From: Joel Stanley joel@jms.id.au
[ Upstream commit f45c5b1c27293f834682e89003f88b3512329ab4 ]
Move the soc revision parsing to the initial probe, saving the driver from parsing the register multiple times.
Use this variable to select the correct divisor table for the AHB clock. Before this fix the A2 would have used the A0 table.
Fixes: 2d491066ccd4 ("clk: ast2600: Fix AHB clock divider for A1") Signed-off-by: Joel Stanley joel@jms.id.au Link: https://lore.kernel.org/r/20210922235449.213631-1-joel@jms.id.au Reviewed-by: Andrew Jeffery andrew@aj.id.au Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk-ast2600.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c index bc3be5f3eae15..24dab2312bc6f 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/clk-ast2600.c @@ -51,6 +51,8 @@ static DEFINE_SPINLOCK(aspeed_g6_clk_lock); static struct clk_hw_onecell_data *aspeed_g6_clk_data;
static void __iomem *scu_g6_base; +/* AST2600 revision: A0, A1, A2, etc */ +static u8 soc_rev;
/* * Clocks marked with CLK_IS_CRITICAL: @@ -191,9 +193,8 @@ static struct clk_hw *ast2600_calc_pll(const char *name, u32 val) static struct clk_hw *ast2600_calc_apll(const char *name, u32 val) { unsigned int mult, div; - u32 chip_id = readl(scu_g6_base + ASPEED_G6_SILICON_REV);
- if (((chip_id & CHIP_REVISION_ID) >> 16) >= 2) { + if (soc_rev >= 2) { if (val & BIT(24)) { /* Pass through mode */ mult = div = 1; @@ -707,7 +708,7 @@ static const u32 ast2600_a1_axi_ahb200_tbl[] = { static void __init aspeed_g6_cc(struct regmap *map) { struct clk_hw *hw; - u32 val, div, divbits, chip_id, axi_div, ahb_div; + u32 val, div, divbits, axi_div, ahb_div;
clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, 25000000);
@@ -738,8 +739,7 @@ static void __init aspeed_g6_cc(struct regmap *map) axi_div = 2;
divbits = (val >> 11) & 0x3; - regmap_read(map, ASPEED_G6_SILICON_REV, &chip_id); - if (chip_id & BIT(16)) { + if (soc_rev >= 1) { if (!divbits) { ahb_div = ast2600_a1_axi_ahb200_tbl[(val >> 8) & 0x3]; if (val & BIT(16)) @@ -784,6 +784,8 @@ static void __init aspeed_g6_cc_init(struct device_node *np) if (!scu_g6_base) return;
+ soc_rev = (readl(scu_g6_base + ASPEED_G6_SILICON_REV) & CHIP_REVISION_ID) >> 16; + aspeed_g6_clk_data = kzalloc(struct_size(aspeed_g6_clk_data, hws, ASPEED_G6_NUM_CLKS), GFP_KERNEL); if (!aspeed_g6_clk_data)
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 05cf3ec00d460b50088d421fb878a0f83f57e262 ]
The gcc_aggre1_pnoc_ahb_clk is crucial for the proper MSM8996/APQ8096 functioning. If it gets disabled, several subsytems will stop working (including eMMC/SDCC and USB). There are no in-kernel users of this clock, so it is much simpler to remove from the kernel.
The clock was first removed in the commit 9e60de1cf270 ("clk: qcom: Remove gcc_aggre1_pnoc_ahb_clk from msm8996") by Stephen Boyd, but got added back in the commit b567752144e3 ("clk: qcom: Add some missing gcc clks for msm8996") by Rajendra Nayak.
Let's remove it again in hope that nobody adds it back.
Reported-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Cc: Rajendra Nayak rnayak@codeaurora.org Cc: Konrad Dybcio konrad.dybcio@somainline.org Fixes: b567752144e3 ("clk: qcom: Add some missing gcc clks for msm8996") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://lore.kernel.org/r/20211104011155.2209654-1-dmitry.baryshkov@linaro.o... Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/qcom/gcc-msm8996.c | 15 --------------- 1 file changed, 15 deletions(-)
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 3c3a7ff045621..9b1674b28d45d 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -2937,20 +2937,6 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { }, };
-static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { - .halt_reg = 0x82014, - .clkr = { - .enable_reg = 0x82014, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre1_pnoc_ahb_clk", - .parent_names = (const char *[]){ "periph_noc_clk_src" }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_aggre2_ufs_axi_clk = { .halt_reg = 0x83014, .clkr = { @@ -3474,7 +3460,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, - [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr,
From: Quentin Perret qperret@google.com
[ Upstream commit 50a8d3315960c74095c59e204db44abd937d4b5d ]
We currently walk the hypervisor stage-1 page-table towards the end of hyp init in nVHE protected mode and adjust the host page ownership attributes in its stage-2 in order to get a consistent state from both point of views. The walk is done on the entire hyp VA space, and expects to only ever find page-level mappings. While this expectation is reasonable in the half of hyp VA space that maps memory with a fixed offset (see the loop in pkvm_create_mappings_locked()), it can be incorrect in the other half where nothing prevents the usage of block mappings. For instance, on systems where memory is physically aligned at an address that happens to maps to a PMD aligned VA in the hyp_vmemmap, kvm_pgtable_hyp_map() will install block mappings when backing the hyp_vmemmap, which will later cause finalize_host_mappings() to fail. Furthermore, it should be noted that all pages backing the hyp_vmemmap are also mapped in the 'fixed offset range' of the hypervisor, which implies that finalize_host_mappings() will walk both aliases and update the host stage-2 attributes twice. The order in which this happens is unpredictable, though, since the hyp VA layout is highly dependent on the position of the idmap page, hence resulting in a fragile mess at best.
In order to fix all of this, let's restrict the finalization walk to only cover memory regions in the 'fixed-offset range' of the hyp VA space and nothing else. This not only fixes a correctness issue, but will also result in a slighlty faster hyp initialization overall.
Fixes: 2c50166c62ba ("KVM: arm64: Mark host bss and rodata section as shared") Signed-off-by: Quentin Perret qperret@google.com Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211108154636.393384-1-qperret@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kvm/hyp/nvhe/setup.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index 57c27846320f4..58ad9c5ba3112 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -177,7 +177,7 @@ static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
phys = kvm_pte_to_phys(pte); if (!addr_is_memory(phys)) - return 0; + return -EINVAL;
/* * Adjust the host stage-2 mappings to match the ownership attributes @@ -206,8 +206,18 @@ static int finalize_host_mappings(void) .cb = finalize_host_mappings_walker, .flags = KVM_PGTABLE_WALK_LEAF, }; + int i, ret; + + for (i = 0; i < hyp_memblock_nr; i++) { + struct memblock_region *reg = &hyp_memory[i]; + u64 start = (u64)hyp_phys_to_virt(reg->base); + + ret = kvm_pgtable_walk(&pkvm_pgtable, start, reg->size, &walker); + if (ret) + return ret; + }
- return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker); + return 0; }
void __noreturn __pkvm_init_finalise(void)
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 5eeaafc8d69373c095e461bdb39e5c9b62228ac5 ]
Several header files need info on CONFIG_32BIT or CONFIG_64BIT, but kconfig symbol BCM63XX does not provide that info. This leads to many build errors, e.g.:
arch/mips/include/asm/page.h:196:13: error: use of undeclared identifier 'CAC_BASE' return x - PAGE_OFFSET + PHYS_OFFSET; arch/mips/include/asm/mach-generic/spaces.h:91:23: note: expanded from macro 'PAGE_OFFSET' #define PAGE_OFFSET (CAC_BASE + PHYS_OFFSET) arch/mips/include/asm/io.h:134:28: error: use of undeclared identifier 'CAC_BASE' return (void *)(address + PAGE_OFFSET - PHYS_OFFSET); arch/mips/include/asm/mach-generic/spaces.h:91:23: note: expanded from macro 'PAGE_OFFSET' #define PAGE_OFFSET (CAC_BASE + PHYS_OFFSET)
arch/mips/include/asm/uaccess.h:82:10: error: use of undeclared identifier '__UA_LIMIT' return (__UA_LIMIT & (addr | (addr + size) | __ua_size(size))) == 0;
Selecting the SYS_HAS_CPU_BMIPS* symbols causes SYS_HAS_CPU_BMIPS to be set, which then selects CPU_SUPPORT_32BIT_KERNEL, which causes CONFIG_32BIT to be set. (a bit more indirect than v1 [RFC].)
Fixes: e7300d04bd08 ("MIPS: BCM63xx: Add support for the Broadcom BCM63xx family of SOCs.") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Cc: Thomas Bogendoerfer tsbogend@alpha.franken.de Cc: Florian Fainelli f.fainelli@gmail.com Cc: bcm-kernel-feedback-list@broadcom.com Cc: linux-mips@vger.kernel.org Cc: Paul Burton paulburton@kernel.org Cc: Maxime Bizon mbizon@freebox.fr Cc: Ralf Baechle ralf@linux-mips.org Suggested-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cbbb302a460eb..a917d408d27d8 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -332,6 +332,9 @@ config BCM63XX select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_HAS_EARLY_PRINTK + select SYS_HAS_CPU_BMIPS32_3300 + select SYS_HAS_CPU_BMIPS4350 + select SYS_HAS_CPU_BMIPS4380 select SWAP_IO_SPACE select GPIOLIB select MIPS_L1_CACHE_SHIFT_4
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit e2f4b3be1d3c73176db734565b160250cc1300dd ]
For MIPS pre-boot, when CONFIG_KERNEL_ZSTD=y, the decompressor function uses __bswapdi2(), so this object file should be added to the target object file.
Fixes these build errors:
mips-linux-ld: arch/mips/boot/compressed/decompress.o: in function `xxh64': decompress.c:(.text+0x8be0): undefined reference to `__bswapdi2' mips-linux-ld: decompress.c:(.text+0x8c78): undefined reference to `__bswapdi2' mips-linux-ld: decompress.c:(.text+0x8d04): undefined reference to `__bswapdi2' mips-linux-ld: arch/mips/boot/compressed/decompress.o:decompress.c:(.text+0xa010): more undefined references to `__bswapdi2' follow
Fixes: 0652035a5794 ("asm-generic: unaligned: remove byteshift helpers") Fixes: cddc40f5617e ("mips: always link byteswap helpers into decompressor") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Cc: Arnd Bergmann arnd@arndb.de Cc: Thomas Bogendoerfer tsbogend@alpha.franken.de Cc: linux-mips@vger.kernel.org Acked-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/boot/compressed/Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 3548b3b452699..9112bdb86be45 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -56,6 +56,8 @@ $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c
vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o
+vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o + extra-y += ashldi3.c $(obj)/ashldi3.c: $(obj)/%.c: $(srctree)/lib/%.c FORCE $(call if_changed,shipped) @@ -64,6 +66,10 @@ extra-y += bswapsi.c $(obj)/bswapsi.c: $(obj)/%.c: $(srctree)/arch/mips/lib/%.c FORCE $(call if_changed,shipped)
+extra-y += bswapdi.c +$(obj)/bswapdi.c: $(obj)/%.c: $(srctree)/arch/mips/lib/%.c FORCE + $(call if_changed,shipped) + targets := $(notdir $(vmlinuzobjs-y))
targets += vmlinux.bin
From: Vincent Donnefort vincent.donnefort@arm.com
[ Upstream commit 42dc938a590c96eeb429e1830123fef2366d9c80 ]
Nothing protects the access to the per_cpu variable sd_llc_id. When testing the same CPU (i.e. this_cpu == that_cpu), a race condition exists with update_top_cache_domain(). One scenario being:
CPU1 CPU2 ==================================================================
per_cpu(sd_llc_id, CPUX) => 0 partition_sched_domains_locked() detach_destroy_domains() cpus_share_cache(CPUX, CPUX) update_top_cache_domain(CPUX) per_cpu(sd_llc_id, CPUX) => 0 per_cpu(sd_llc_id, CPUX) = CPUX per_cpu(sd_llc_id, CPUX) => CPUX return false
ttwu_queue_cond() wouldn't catch smp_processor_id() == cpu and the result is a warning triggered from ttwu_queue_wakelist().
Avoid a such race in cpus_share_cache() by always returning true when this_cpu == that_cpu.
Fixes: 518cd6234178 ("sched: Only queue remote wakeups when crossing cache boundaries") Reported-by: Jing-Ting Wu jing-ting.wu@mediatek.com Signed-off-by: Vincent Donnefort vincent.donnefort@arm.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Valentin Schneider valentin.schneider@arm.com Reviewed-by: Vincent Guittot vincent.guittot@linaro.org Link: https://lore.kernel.org/r/20211104175120.857087-1-vincent.donnefort@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/core.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index aea60eae21a7f..2c34c7bd559f2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3707,6 +3707,9 @@ out:
bool cpus_share_cache(int this_cpu, int that_cpu) { + if (this_cpu == that_cpu) + return true; + return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu); }
From: Mathias Krause minipli@grsecurity.net
[ Upstream commit b027789e5e50494c2325cc70c8642e7fd6059479 ]
Kevin is reporting crashes which point to a use-after-free of a cfs_rq in update_blocked_averages(). Initial debugging revealed that we've live cfs_rq's (on_list=1) in an about to be kfree()'d task group in free_fair_sched_group(). However, it was unclear how that can happen.
His kernel config happened to lead to a layout of struct sched_entity that put the 'my_q' member directly into the middle of the object which makes it incidentally overlap with SLUB's freelist pointer. That, in combination with SLAB_FREELIST_HARDENED's freelist pointer mangling, leads to a reliable access violation in form of a #GP which made the UAF fail fast.
Michal seems to have run into the same issue[1]. He already correctly diagnosed that commit a7b359fc6a37 ("sched/fair: Correctly insert cfs_rq's to list on unthrottle") is causing the preconditions for the UAF to happen by re-adding cfs_rq's also to task groups that have no more running tasks, i.e. also to dead ones. His analysis, however, misses the real root cause and it cannot be seen from the crash backtrace only, as the real offender is tg_unthrottle_up() getting called via sched_cfs_period_timer() via the timer interrupt at an inconvenient time.
When unregister_fair_sched_group() unlinks all cfs_rq's from the dying task group, it doesn't protect itself from getting interrupted. If the timer interrupt triggers while we iterate over all CPUs or after unregister_fair_sched_group() has finished but prior to unlinking the task group, sched_cfs_period_timer() will execute and walk the list of task groups, trying to unthrottle cfs_rq's, i.e. re-add them to the dying task group. These will later -- in free_fair_sched_group() -- be kfree()'ed while still being linked, leading to the fireworks Kevin and Michal are seeing.
To fix this race, ensure the dying task group gets unlinked first. However, simply switching the order of unregistering and unlinking the task group isn't sufficient, as concurrent RCU walkers might still see it, as can be seen below:
CPU1: CPU2: : timer IRQ: : do_sched_cfs_period_timer(): : : : distribute_cfs_runtime(): : rcu_read_lock(); : : : unthrottle_cfs_rq(): sched_offline_group(): : : walk_tg_tree_from(…,tg_unthrottle_up,…): list_del_rcu(&tg->list); : (1) : list_for_each_entry_rcu(child, &parent->children, siblings) : : (2) list_del_rcu(&tg->siblings); : : tg_unthrottle_up(): unregister_fair_sched_group(): struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)]; : : list_del_leaf_cfs_rq(tg->cfs_rq[cpu]); : : : : if (!cfs_rq_is_decayed(cfs_rq) || cfs_rq->nr_running) (3) : list_add_leaf_cfs_rq(cfs_rq); : : : : : : : : : : (4) : rcu_read_unlock();
CPU 2 walks the task group list in parallel to sched_offline_group(), specifically, it'll read the soon to be unlinked task group entry at (1). Unlinking it on CPU 1 at (2) therefore won't prevent CPU 2 from still passing it on to tg_unthrottle_up(). CPU 1 now tries to unlink all cfs_rq's via list_del_leaf_cfs_rq() in unregister_fair_sched_group(). Meanwhile CPU 2 will re-add some of these at (3), which is the cause of the UAF later on.
To prevent this additional race from happening, we need to wait until walk_tg_tree_from() has finished traversing the task groups, i.e. after the RCU read critical section ends in (4). Afterwards we're safe to call unregister_fair_sched_group(), as each new walk won't see the dying task group any more.
On top of that, we need to wait yet another RCU grace period after unregister_fair_sched_group() to ensure print_cfs_stats(), which might run concurrently, always sees valid objects, i.e. not already free'd ones.
This patch survives Michal's reproducer[2] for 8h+ now, which used to trigger within minutes before.
[1] https://lore.kernel.org/lkml/20211011172236.11223-1-mkoutny@suse.com/ [2] https://lore.kernel.org/lkml/20211102160228.GA57072@blackbody.suse.cz/
Fixes: a7b359fc6a37 ("sched/fair: Correctly insert cfs_rq's to list on unthrottle") [peterz: shuffle code around a bit] Reported-by: Kevin Tanguy kevin.tanguy@corp.ovh.com Signed-off-by: Mathias Krause minipli@grsecurity.net Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/autogroup.c | 2 +- kernel/sched/core.c | 44 ++++++++++++++++++++++++++++++++-------- kernel/sched/fair.c | 4 ++-- kernel/sched/rt.c | 12 ++++++++--- kernel/sched/sched.h | 3 ++- 5 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/kernel/sched/autogroup.c b/kernel/sched/autogroup.c index 2067080bb2358..8629b37d118e7 100644 --- a/kernel/sched/autogroup.c +++ b/kernel/sched/autogroup.c @@ -31,7 +31,7 @@ static inline void autogroup_destroy(struct kref *kref) ag->tg->rt_se = NULL; ag->tg->rt_rq = NULL; #endif - sched_offline_group(ag->tg); + sched_release_group(ag->tg); sched_destroy_group(ag->tg); }
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2c34c7bd559f2..779f27a4b46ac 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -9720,6 +9720,22 @@ static void sched_free_group(struct task_group *tg) kmem_cache_free(task_group_cache, tg); }
+static void sched_free_group_rcu(struct rcu_head *rcu) +{ + sched_free_group(container_of(rcu, struct task_group, rcu)); +} + +static void sched_unregister_group(struct task_group *tg) +{ + unregister_fair_sched_group(tg); + unregister_rt_sched_group(tg); + /* + * We have to wait for yet another RCU grace period to expire, as + * print_cfs_stats() might run concurrently. + */ + call_rcu(&tg->rcu, sched_free_group_rcu); +} + /* allocate runqueue etc for a new task group */ struct task_group *sched_create_group(struct task_group *parent) { @@ -9763,25 +9779,35 @@ void sched_online_group(struct task_group *tg, struct task_group *parent) }
/* rcu callback to free various structures associated with a task group */ -static void sched_free_group_rcu(struct rcu_head *rhp) +static void sched_unregister_group_rcu(struct rcu_head *rhp) { /* Now it should be safe to free those cfs_rqs: */ - sched_free_group(container_of(rhp, struct task_group, rcu)); + sched_unregister_group(container_of(rhp, struct task_group, rcu)); }
void sched_destroy_group(struct task_group *tg) { /* Wait for possible concurrent references to cfs_rqs complete: */ - call_rcu(&tg->rcu, sched_free_group_rcu); + call_rcu(&tg->rcu, sched_unregister_group_rcu); }
-void sched_offline_group(struct task_group *tg) +void sched_release_group(struct task_group *tg) { unsigned long flags;
- /* End participation in shares distribution: */ - unregister_fair_sched_group(tg); - + /* + * Unlink first, to avoid walk_tg_tree_from() from finding us (via + * sched_cfs_period_timer()). + * + * For this to be effective, we have to wait for all pending users of + * this task group to leave their RCU critical section to ensure no new + * user will see our dying task group any more. Specifically ensure + * that tg_unthrottle_up() won't add decayed cfs_rq's to it. + * + * We therefore defer calling unregister_fair_sched_group() to + * sched_unregister_group() which is guarantied to get called only after the + * current RCU grace period has expired. + */ spin_lock_irqsave(&task_group_lock, flags); list_del_rcu(&tg->list); list_del_rcu(&tg->siblings); @@ -9900,7 +9926,7 @@ static void cpu_cgroup_css_released(struct cgroup_subsys_state *css) { struct task_group *tg = css_tg(css);
- sched_offline_group(tg); + sched_release_group(tg); }
static void cpu_cgroup_css_free(struct cgroup_subsys_state *css) @@ -9910,7 +9936,7 @@ static void cpu_cgroup_css_free(struct cgroup_subsys_state *css) /* * Relies on the RCU grace period between css_released() and this. */ - sched_free_group(tg); + sched_unregister_group(tg); }
/* diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index f6a05d9b54436..6f16dfb742462 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -11358,8 +11358,6 @@ void free_fair_sched_group(struct task_group *tg) { int i;
- destroy_cfs_bandwidth(tg_cfs_bandwidth(tg)); - for_each_possible_cpu(i) { if (tg->cfs_rq) kfree(tg->cfs_rq[i]); @@ -11436,6 +11434,8 @@ void unregister_fair_sched_group(struct task_group *tg) struct rq *rq; int cpu;
+ destroy_cfs_bandwidth(tg_cfs_bandwidth(tg)); + for_each_possible_cpu(cpu) { if (tg->se[cpu]) remove_entity_load_avg(tg->se[cpu]); diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 3daf42a0f4623..bfef3f39b5552 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -137,13 +137,17 @@ static inline struct rq *rq_of_rt_se(struct sched_rt_entity *rt_se) return rt_rq->rq; }
-void free_rt_sched_group(struct task_group *tg) +void unregister_rt_sched_group(struct task_group *tg) { - int i; - if (tg->rt_se) destroy_rt_bandwidth(&tg->rt_bandwidth);
+} + +void free_rt_sched_group(struct task_group *tg) +{ + int i; + for_each_possible_cpu(i) { if (tg->rt_rq) kfree(tg->rt_rq[i]); @@ -250,6 +254,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se) return &rq->rt; }
+void unregister_rt_sched_group(struct task_group *tg) { } + void free_rt_sched_group(struct task_group *tg) { }
int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 3d3e5793e1172..4f432826933da 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -486,6 +486,7 @@ extern void __refill_cfs_bandwidth_runtime(struct cfs_bandwidth *cfs_b); extern void start_cfs_bandwidth(struct cfs_bandwidth *cfs_b); extern void unthrottle_cfs_rq(struct cfs_rq *cfs_rq);
+extern void unregister_rt_sched_group(struct task_group *tg); extern void free_rt_sched_group(struct task_group *tg); extern int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent); extern void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq, @@ -501,7 +502,7 @@ extern struct task_group *sched_create_group(struct task_group *parent); extern void sched_online_group(struct task_group *tg, struct task_group *parent); extern void sched_destroy_group(struct task_group *tg); -extern void sched_offline_group(struct task_group *tg); +extern void sched_release_group(struct task_group *tg);
extern void sched_move_task(struct task_struct *tsk);
From: Like Xu likexu@tencent.com
[ Upstream commit 5863702561e625903ec678551cb056a4b19e0b8a ]
Just like what we do in the x86_get_event_constraints(), the PERF_X86_EVENT_LBR_SELECT flag should also be propagated to event->hw.flags so that the host lbr driver can save/restore MSR_LBR_SELECT for the special vlbr event created by KVM or BPF.
Fixes: 097e4311cda9 ("perf/x86: Add constraint to create guest LBR event without hw counter") Reported-by: Wanpeng Li wanpengli@tencent.com Signed-off-by: Like Xu likexu@tencent.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: Wanpeng Li wanpengli@tencent.com Link: https://lore.kernel.org/r/20211103091716.59906-1-likexu@tencent.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index bc3f97f834011..c7f1cc433a6aa 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -2999,8 +2999,10 @@ intel_vlbr_constraints(struct perf_event *event) { struct event_constraint *c = &vlbr_constraint;
- if (unlikely(constraint_match(c, event->hw.config))) + if (unlikely(constraint_match(c, event->hw.config))) { + event->hw.flags |= c->flags; return c; + }
return NULL; }
From: Laibin Qiu qiulaibin@huawei.com
[ Upstream commit b781d8db580c058ecd54ed7d5dde7f8270b25f5b ]
KASAN reports a use-after-free report when doing block test:
================================================================== [10050.967049] BUG: KASAN: use-after-free in submit_bio_checks+0x1539/0x1550
[10050.977638] Call Trace: [10050.978190] dump_stack+0x9b/0xce [10050.979674] print_address_description.constprop.6+0x3e/0x60 [10050.983510] kasan_report.cold.9+0x22/0x3a [10050.986089] submit_bio_checks+0x1539/0x1550 [10050.989576] submit_bio_noacct+0x83/0xc80 [10050.993714] submit_bio+0xa7/0x330 [10050.994435] mpage_readahead+0x380/0x500 [10050.998009] read_pages+0x1c1/0xbf0 [10051.002057] page_cache_ra_unbounded+0x4c2/0x6f0 [10051.007413] do_page_cache_ra+0xda/0x110 [10051.008207] force_page_cache_ra+0x23d/0x3d0 [10051.009087] page_cache_sync_ra+0xca/0x300 [10051.009970] generic_file_buffered_read+0xbea/0x2130 [10051.012685] generic_file_read_iter+0x315/0x490 [10051.014472] blkdev_read_iter+0x113/0x1b0 [10051.015300] aio_read+0x2ad/0x450 [10051.023786] io_submit_one+0xc8e/0x1d60 [10051.029855] __se_sys_io_submit+0x125/0x350 [10051.033442] do_syscall_64+0x2d/0x40 [10051.034156] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[10051.048733] Allocated by task 18598: [10051.049482] kasan_save_stack+0x19/0x40 [10051.050263] __kasan_kmalloc.constprop.1+0xc1/0xd0 [10051.051230] kmem_cache_alloc+0x146/0x440 [10051.052060] mempool_alloc+0x125/0x2f0 [10051.052818] bio_alloc_bioset+0x353/0x590 [10051.053658] mpage_alloc+0x3b/0x240 [10051.054382] do_mpage_readpage+0xddf/0x1ef0 [10051.055250] mpage_readahead+0x264/0x500 [10051.056060] read_pages+0x1c1/0xbf0 [10051.056758] page_cache_ra_unbounded+0x4c2/0x6f0 [10051.057702] do_page_cache_ra+0xda/0x110 [10051.058511] force_page_cache_ra+0x23d/0x3d0 [10051.059373] page_cache_sync_ra+0xca/0x300 [10051.060198] generic_file_buffered_read+0xbea/0x2130 [10051.061195] generic_file_read_iter+0x315/0x490 [10051.062189] blkdev_read_iter+0x113/0x1b0 [10051.063015] aio_read+0x2ad/0x450 [10051.063686] io_submit_one+0xc8e/0x1d60 [10051.064467] __se_sys_io_submit+0x125/0x350 [10051.065318] do_syscall_64+0x2d/0x40 [10051.066082] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[10051.067455] Freed by task 13307: [10051.068136] kasan_save_stack+0x19/0x40 [10051.068931] kasan_set_track+0x1c/0x30 [10051.069726] kasan_set_free_info+0x1b/0x30 [10051.070621] __kasan_slab_free+0x111/0x160 [10051.071480] kmem_cache_free+0x94/0x460 [10051.072256] mempool_free+0xd6/0x320 [10051.072985] bio_free+0xe0/0x130 [10051.073630] bio_put+0xab/0xe0 [10051.074252] bio_endio+0x3a6/0x5d0 [10051.074984] blk_update_request+0x590/0x1370 [10051.075870] scsi_end_request+0x7d/0x400 [10051.076667] scsi_io_completion+0x1aa/0xe50 [10051.077503] scsi_softirq_done+0x11b/0x240 [10051.078344] blk_mq_complete_request+0xd4/0x120 [10051.079275] scsi_mq_done+0xf0/0x200 [10051.080036] virtscsi_vq_done+0xbc/0x150 [10051.080850] vring_interrupt+0x179/0x390 [10051.081650] __handle_irq_event_percpu+0xf7/0x490 [10051.082626] handle_irq_event_percpu+0x7b/0x160 [10051.083527] handle_irq_event+0xcc/0x170 [10051.084297] handle_edge_irq+0x215/0xb20 [10051.085122] asm_call_irq_on_stack+0xf/0x20 [10051.085986] common_interrupt+0xae/0x120 [10051.086830] asm_common_interrupt+0x1e/0x40
==================================================================
Bio will be checked at beginning of submit_bio_noacct(). 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, it will still set bio issue->value by blkcg_bio_issue_init(). This is redundant and may cause the above use-after-free.
CPU0 CPU1 submit_bio submit_bio_noacct submit_bio_checks blk_throtl_bio() <=mod_timer(&sq->pending_timer blk_throtl_dispatch_work_fn submit_bio_noacct() <= bio have throttle tag, will throw directly and bio issue->value will be set here
bio_endio() bio_put() bio_free() <= free this bio
blkcg_bio_issue_init(bio) <= bio has been freed and will lead to UAF return BLK_QC_T_NONE
Fix this by remove extra blkcg_bio_issue_init.
Fixes: e439bedf6b24 (blkcg: consolidate bio_issue_init() to be a part of core) Signed-off-by: Laibin Qiu qiulaibin@huawei.com Link: https://lore.kernel.org/r/20211112093354.3581504-1-qiulaibin@huawei.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c index 4d8f5fe915887..12aa8c1da6003 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -887,10 +887,8 @@ static noinline_for_stack bool submit_bio_checks(struct bio *bio) if (unlikely(!current->io_context)) create_task_io_context(current, GFP_ATOMIC, q->node);
- if (blk_throtl_bio(bio)) { - blkcg_bio_issue_init(bio); + if (blk_throtl_bio(bio)) return false; - }
blk_cgroup_bio_start(bio); blkcg_bio_issue_init(bio);
From: Masami Hiramatsu mhiramat@kernel.org
[ Upstream commit 63f84ae6b82bb4dff672f76f30c6fd7b9d3766bc ]
Do not copy the fixed-size char array field of the events over the field size. The histogram treats char array as a string and there are 2 types of char array in the event, fixed-size and dynamic string. The dynamic string (__data_loc) field must be null terminated, but the fixed-size char array field may not be null terminated (not a string, but just a data). In that case, histogram can copy the data after the field. This uses the original field size for fixed-size char array field to restrict the histogram not to access over the original field size.
Link: https://lkml.kernel.org/r/163673292822.195747.3696966210526410250.stgit@devn...
Fixes: 02205a6752f2 (tracing: Add support for 'field variables') Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/trace_events_hist.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index f01e442716e2f..de37664ef0476 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -1733,9 +1733,10 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, if (!hist_field->type) goto free;
- if (field->filter_type == FILTER_STATIC_STRING) + if (field->filter_type == FILTER_STATIC_STRING) { hist_field->fn = hist_field_string; - else if (field->filter_type == FILTER_DYN_STRING) + hist_field->size = field->size; + } else if (field->filter_type == FILTER_DYN_STRING) hist_field->fn = hist_field_dynstring; else hist_field->fn = hist_field_pstring; @@ -2691,7 +2692,7 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, char *str = elt_data->field_var_str[j++]; char *val_str = (char *)(uintptr_t)var_val;
- strscpy(str, val_str, STR_VAR_LEN_MAX); + strscpy(str, val_str, val->size); var_val = (u64)(uintptr_t)str; } tracing_map_set_var(elt, var_idx, var_val); @@ -4586,7 +4587,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
str = elt_data->field_var_str[idx]; val_str = (char *)(uintptr_t)hist_val; - strscpy(str, val_str, STR_VAR_LEN_MAX); + strscpy(str, val_str, hist_field->size);
hist_val = (u64)(uintptr_t)str; }
From: Ian Rogers irogers@google.com
[ Upstream commit 4924b1f7c46711762fd0e65c135ccfbcfd6ded1f ]
perf_env__insert_btf() doesn't insert if a duplicate BTF id is encountered and this causes a memory leak. Modify the function to return a success/error value and then free the memory if insertion didn't happen.
v2. Adds a return -1 when the insertion error occurs in perf_env__fetch_btf. This doesn't affect anything as the result is never checked.
Fixes: 3792cb2ff43b1b19 ("perf bpf: Save BTF in a rbtree in perf_env") Signed-off-by: Ian Rogers irogers@google.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Alexei Starovoitov ast@kernel.org Cc: Andrii Nakryiko andrii@kernel.org Cc: Daniel Borkmann daniel@iogearbox.net Cc: Jiri Olsa jolsa@redhat.com Cc: John Fastabend john.fastabend@gmail.com Cc: KP Singh kpsingh@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Martin KaFai Lau kafai@fb.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Song Liu songliubraving@fb.com Cc: Stephane Eranian eranian@google.com Cc: Tiezhu Yang yangtiezhu@loongson.cn Cc: Yonghong Song yhs@fb.com Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: http://lore.kernel.org/lkml/20211112074525.121633-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/util/bpf-event.c | 6 +++++- tools/perf/util/env.c | 5 ++++- tools/perf/util/env.h | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index a410b3968b3af..16ad0e6e9e9c5 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -120,7 +120,11 @@ static int perf_env__fetch_btf(struct perf_env *env, node->data_size = data_size; memcpy(node->data, data, data_size);
- perf_env__insert_btf(env, node); + if (!perf_env__insert_btf(env, node)) { + /* Insertion failed because of a duplicate. */ + free(node); + return -1; + } return 0; }
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index cf773f0dec384..5b24eb010336c 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -74,12 +74,13 @@ out: return node; }
-void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) +bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) { struct rb_node *parent = NULL; __u32 btf_id = btf_node->id; struct btf_node *node; struct rb_node **p; + bool ret = true;
down_write(&env->bpf_progs.lock); p = &env->bpf_progs.btfs.rb_node; @@ -93,6 +94,7 @@ void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) p = &(*p)->rb_right; } else { pr_debug("duplicated btf %u\n", btf_id); + ret = false; goto out; } } @@ -102,6 +104,7 @@ void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) env->bpf_progs.btfs_cnt++; out: up_write(&env->bpf_progs.lock); + return ret; }
struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id) diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index 1383876f72b37..163e5ec503a26 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -167,7 +167,7 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node); struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, __u32 prog_id); -void perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); +bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node); struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id);
int perf_env__numa_node(struct perf_env *env, int cpu);
From: Sohaib Mohamed sohaib.amhmd@gmail.com
[ Upstream commit 88e48238d53682281c9de2a0b65d24d3b64542a0 ]
ASan reports memory leaks while running:
$ sudo ./perf bench futex all
The leaks are caused by perf_cpu_map__new not being freed. This patch adds the missing perf_cpu_map__put since it calls cpu_map_delete implicitly.
Fixes: 9c3516d1b850ea93 ("libperf: Add perf_cpu_map__new()/perf_cpu_map__read() functions") Signed-off-by: Sohaib Mohamed sohaib.amhmd@gmail.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: André Almeida andrealmeid@collabora.com Cc: Darren Hart dvhart@infradead.org Cc: Davidlohr Bueso dave@stgolabs.net Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Sohaib Mohamed sohaib.amhmd@gmail.com Cc: Thomas Gleixner tglx@linutronix.de Link: http://lore.kernel.org/lkml/20211112201134.77892-1-sohaib.amhmd@gmail.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/bench/futex-lock-pi.c | 1 + tools/perf/bench/futex-requeue.c | 1 + tools/perf/bench/futex-wake-parallel.c | 1 + tools/perf/bench/futex-wake.c | 1 + 4 files changed, 4 insertions(+)
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c index 5d1fe9c35807a..137890f78e17a 100644 --- a/tools/perf/bench/futex-lock-pi.c +++ b/tools/perf/bench/futex-lock-pi.c @@ -233,6 +233,7 @@ int bench_futex_lock_pi(int argc, const char **argv) print_summary();
free(worker); + perf_cpu_map__put(cpu); return ret; err: usage_with_options(bench_futex_lock_pi_usage, options); diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c index 97fe31fd3a236..f7a5ffebb9408 100644 --- a/tools/perf/bench/futex-requeue.c +++ b/tools/perf/bench/futex-requeue.c @@ -294,6 +294,7 @@ int bench_futex_requeue(int argc, const char **argv) print_summary();
free(worker); + perf_cpu_map__put(cpu); return ret; err: usage_with_options(bench_futex_requeue_usage, options); diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c index e970e6b9ad535..0983f40b4b408 100644 --- a/tools/perf/bench/futex-wake-parallel.c +++ b/tools/perf/bench/futex-wake-parallel.c @@ -329,6 +329,7 @@ int bench_futex_wake_parallel(int argc, const char **argv) print_summary();
free(blocked_worker); + perf_cpu_map__put(cpu); return ret; } #endif /* HAVE_PTHREAD_BARRIER */ diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c index 77f058a477903..2226a475e782b 100644 --- a/tools/perf/bench/futex-wake.c +++ b/tools/perf/bench/futex-wake.c @@ -222,5 +222,6 @@ int bench_futex_wake(int argc, const char **argv) print_summary();
free(worker); + perf_cpu_map__put(cpu); return ret; }
From: James Clark james.clark@arm.com
[ Upstream commit a9cdc1c5e3700a5200e5ca1f90b6958b6483845b ]
Commit 463538a383a2 ("perf tests: Fix test 68 zstd compression for s390") inadvertently removed the -g flag from all platforms rather than just s390, because the [[ ]] construct fails in sh. Changing to single brackets restores testing of call graphs and removes the following error from the output:
$ ./perf test -v 85 85: Zstd perf.data compression/decompression : --- start --- test child forked, pid 50643 Collecting compressed record file: ./tests/shell/record+zstd_comp_decomp.sh: 15: [[: not found
Fixes: 463538a383a2 ("perf tests: Fix test 68 zstd compression for s390") Signed-off-by: James Clark james.clark@arm.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Florian Fainelli f.fainelli@gmail.com Cc: Ian Rogers irogers@google.com Cc: Jiri Olsa jolsa@redhat.com Cc: John Fastabend john.fastabend@gmail.com Cc: KP Singh kpsingh@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Martin KaFai Lau kafai@fb.com Cc: Namhyung Kim namhyung@kernel.org Cc: Song Liu songliubraving@fb.com Cc: Sumanth Korikkar sumanthk@linux.ibm.com Cc: Thomas Richter tmricht@linux.ibm.com Cc: Yonghong Song yhs@fb.com Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20211028134828.65774-3-james.clark@arm.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/tests/shell/record+zstd_comp_decomp.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/tests/shell/record+zstd_comp_decomp.sh b/tools/perf/tests/shell/record+zstd_comp_decomp.sh index 8a168cf8bacca..49bd875d51227 100755 --- a/tools/perf/tests/shell/record+zstd_comp_decomp.sh +++ b/tools/perf/tests/shell/record+zstd_comp_decomp.sh @@ -12,7 +12,7 @@ skip_if_no_z_record() {
collect_z_record() { echo "Collecting compressed record file:" - [[ "$(uname -m)" != s390x ]] && gflag='-g' + [ "$(uname -m)" != s390x ] && gflag='-g' $perf_tool record -o $trace_file $gflag -z -F 5000 -- \ dd count=500 if=/dev/urandom of=/dev/null }
From: Hans Verkuil hverkuil-cisco@xs4all.nl
[ Upstream commit 3cc1ae1fa70ab369e4645e38ce335a19438093ad ]
gv100_hdmi_ctrl() writes vendor_infoframe.subpack0_high to 0x6f0110, and then overwrites it with 0. Just drop the overwrite with 0, that's clearly a mistake.
Because of this issue the HDMI VIC is 0 instead of 1 in the HDMI Vendor InfoFrame when transmitting 4kp30.
Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: 290ffeafcc1a ("drm/nouveau/disp/gv100: initial support") Reviewed-by: Ben Skeggs bskeggs@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/3d3bd0f7-c150-2479-9350-35d394... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c index 6e3c450eaacef..3ff49344abc77 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c @@ -62,7 +62,6 @@ gv100_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet, nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header); nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low); nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high); - nvkm_wr32(device, 0x6f0110 + hdmi, 0x00000000); nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000); nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000); nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000);
From: Alexei Starovoitov ast@kernel.org
[ Upstream commit 34d11a440c6167133201b7374065b59f259730d7 ]
Introduction of map_uid made two lookups from outer map to be distinct. That distinction is only necessary when inner map has an embedded timer. Otherwise it will make the verifier state pruning to be conservative which will cause complex programs to hit 1M insn_processed limit. Tighten map_uid logic to apply to inner maps with timers only.
Fixes: 3e8ce29850f1 ("bpf: Prevent pointer mismatch in bpf_timer_init.") Reported-by: Lorenz Bauer lmb@cloudflare.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Tested-by: Lorenz Bauer lmb@cloudflare.com Link: https://lore.kernel.org/bpf/CACAyw99hVEJFoiBH_ZGyy=+oO-jyydoz6v1DeKPKs2HVsUH... Link: https://lore.kernel.org/bpf/20211110172556.20754-1-alexei.starovoitov@gmail.... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ddba80554fef3..cba37d83451eb 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1143,7 +1143,8 @@ static void mark_ptr_not_null_reg(struct bpf_reg_state *reg) /* transfer reg's id which is unique for every map_lookup_elem * as UID of the inner map. */ - reg->map_uid = reg->id; + if (map_value_has_timer(map->inner_map_meta)) + reg->map_uid = reg->id; } else if (map->map_type == BPF_MAP_TYPE_XSKMAP) { reg->type = PTR_TO_XDP_SOCK; } else if (map->map_type == BPF_MAP_TYPE_SOCKMAP ||
From: Alexander Lobakin alexandr.lobakin@intel.com
[ Upstream commit dc14ca4644f48b1cfa93631e35c28bdc011ad109 ]
sample_summary_print() uses accumulated period to calculate and display per-sec averages. This period gets incremented by sampling interval each time a new sample is formed, and thus equals to the number of samples collected multiplied by this interval.
However, the totals are being calculated differently, they receive current sample statistics already divided by the interval gotten as a difference between sample timestamps for better precision -- in other words, they are being incremented by the per-sec values each sample.
This leads to the excessive division of summary per-secs when interval != 1 sec. It is obvious pps couldn't become two times lower just from picking a different sampling interval value:
$ samples/bpf/xdp_redirect_cpu -p xdp_prognum_n1_inverse_qnum -c all -s -d 6 -i 1 < snip > Packets received : 2,197,230,321 Average packets/s : 22,887,816 Packets redirected : 2,197,230,472 Average redir/s : 22,887,817 $ samples/bpf/xdp_redirect_cpu -p xdp_prognum_n1_inverse_qnum -c all -s -d 6 -i 2 < snip > Packets received : 159,566,498 Average packets/s : 11,397,607 Packets redirected : 159,566,995 Average redir/s : 11,397,642
This can be easily fixed by treating the divisor not as a period, but rather as a total number of samples, and thus incrementing it by 1 instead of interval. As a nice side effect, we can now remove so-named argument from a couple of functions. Let us also create an "alias" for sample_output::rx_cnt::pps named 'num' using a union since this field is used to store this number (period previously) as well, and the resulting counter-intuitive code might've been a reason for this bug.
Fixes: 156f886cf697 ("samples: bpf: Add basic infrastructure for XDP samples") Signed-off-by: Alexander Lobakin alexandr.lobakin@intel.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Jesse Brandeburg jesse.brandeburg@intel.com Reviewed-by: Kumar Kartikeya Dwivedi memxor@gmail.com Link: https://lore.kernel.org/bpf/20211111215703.690-1-alexandr.lobakin@intel.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/xdp_sample_user.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index b32d821781990..8740838e77679 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -120,7 +120,10 @@ struct sample_output { __u64 xmit; } totals; struct { - __u64 pps; + union { + __u64 pps; + __u64 num; + }; __u64 drop; __u64 err; } rx_cnt; @@ -1322,7 +1325,7 @@ int sample_install_xdp(struct bpf_program *xdp_prog, int ifindex, bool generic,
static void sample_summary_print(void) { - double period = sample_out.rx_cnt.pps; + double num = sample_out.rx_cnt.num;
if (sample_out.totals.rx) { double pkts = sample_out.totals.rx; @@ -1330,7 +1333,7 @@ static void sample_summary_print(void) print_always(" Packets received : %'-10llu\n", sample_out.totals.rx); print_always(" Average packets/s : %'-10.0f\n", - sample_round(pkts / period)); + sample_round(pkts / num)); } if (sample_out.totals.redir) { double pkts = sample_out.totals.redir; @@ -1338,7 +1341,7 @@ static void sample_summary_print(void) print_always(" Packets redirected : %'-10llu\n", sample_out.totals.redir); print_always(" Average redir/s : %'-10.0f\n", - sample_round(pkts / period)); + sample_round(pkts / num)); } if (sample_out.totals.drop) print_always(" Rx dropped : %'-10llu\n", @@ -1355,7 +1358,7 @@ static void sample_summary_print(void) print_always(" Packets transmitted : %'-10llu\n", sample_out.totals.xmit); print_always(" Average transmit/s : %'-10.0f\n", - sample_round(pkts / period)); + sample_round(pkts / num)); } }
@@ -1422,7 +1425,7 @@ static int sample_stats_collect(struct stats_record *rec) return 0; }
-static void sample_summary_update(struct sample_output *out, int interval) +static void sample_summary_update(struct sample_output *out) { sample_out.totals.rx += out->totals.rx; sample_out.totals.redir += out->totals.redir; @@ -1430,12 +1433,11 @@ static void sample_summary_update(struct sample_output *out, int interval) sample_out.totals.drop_xmit += out->totals.drop_xmit; sample_out.totals.err += out->totals.err; sample_out.totals.xmit += out->totals.xmit; - sample_out.rx_cnt.pps += interval; + sample_out.rx_cnt.num++; }
static void sample_stats_print(int mask, struct stats_record *cur, - struct stats_record *prev, char *prog_name, - int interval) + struct stats_record *prev, char *prog_name) { struct sample_output out = {};
@@ -1452,7 +1454,7 @@ static void sample_stats_print(int mask, struct stats_record *cur, else if (mask & SAMPLE_DEVMAP_XMIT_CNT_MULTI) stats_get_devmap_xmit_multi(cur, prev, 0, &out, mask & SAMPLE_DEVMAP_XMIT_CNT); - sample_summary_update(&out, interval); + sample_summary_update(&out);
stats_print(prog_name, mask, cur, prev, &out); } @@ -1495,7 +1497,7 @@ static void swap(struct stats_record **a, struct stats_record **b) }
static int sample_timer_cb(int timerfd, struct stats_record **rec, - struct stats_record **prev, int interval) + struct stats_record **prev) { char line[64] = "Summary"; int ret; @@ -1524,7 +1526,7 @@ static int sample_timer_cb(int timerfd, struct stats_record **rec, snprintf(line, sizeof(line), "%s->%s", f ?: "?", t ?: "?"); }
- sample_stats_print(sample_mask, *rec, *prev, line, interval); + sample_stats_print(sample_mask, *rec, *prev, line); return 0; }
@@ -1579,7 +1581,7 @@ int sample_run(int interval, void (*post_cb)(void *), void *ctx) if (pfd[0].revents & POLLIN) ret = sample_signal_cb(); else if (pfd[1].revents & POLLIN) - ret = sample_timer_cb(timerfd, &rec, &prev, interval); + ret = sample_timer_cb(timerfd, &rec, &prev);
if (ret) break;
From: Kumar Kartikeya Dwivedi memxor@gmail.com
[ Upstream commit 2453afe3845523d9dfe89dbfb3d71abfa095e260 ]
Commit b599015f044d ("samples/bpf: Fix application of sizeof to pointer") tried to fix a bug where sizeof was incorrectly applied to a pointer instead of the array string was being copied to, to find the destination buffer size, but ended up using strlen, which is still incorrect. However, on closer look ifname_buf has no other use, hence directly use optarg.
Fixes: b599015f044d ("samples/bpf: Fix application of sizeof to pointer") Fixes: e531a220cc59 ("samples: bpf: Convert xdp_redirect_cpu to XDP samples helper") Signed-off-by: Kumar Kartikeya Dwivedi memxor@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Alexander Lobakin alexandr.lobakin@intel.com Tested-by: Alexander Lobakin alexandr.lobakin@intel.com Link: https://lore.kernel.org/bpf/20211112020301.528357-1-memxor@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/xdp_redirect_cpu_user.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index d84e6949007cc..a81704d3317ba 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -309,7 +309,6 @@ int main(int argc, char **argv) const char *mprog_filename = NULL, *mprog_name = NULL; struct xdp_redirect_cpu *skel; struct bpf_map_info info = {}; - char ifname_buf[IF_NAMESIZE]; struct bpf_cpumap_val value; __u32 infosz = sizeof(info); int ret = EXIT_FAIL_OPTION; @@ -390,10 +389,10 @@ int main(int argc, char **argv) case 'd': if (strlen(optarg) >= IF_NAMESIZE) { fprintf(stderr, "-d/--dev name too long\n"); + usage(argv, long_options, __doc__, mask, true, skel->obj); goto end_cpu; } - safe_strncpy(ifname_buf, optarg, strlen(ifname_buf)); - ifindex = if_nametoindex(ifname_buf); + ifindex = if_nametoindex(optarg); if (!ifindex) ifindex = strtoul(optarg, NULL, 0); if (!ifindex) {
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 0cda7d4bac5fd29dceb13df26083333fa99d6bb4 ]
Commit a985442fdecb ("selftests: net: properly support IPv6 in GSO GRE test") is not compatible with:
Ncat: Version 7.80 ( https://nmap.org/ncat )
(which is distributed with Fedora/Red Hat), tests fail with:
nc: invalid option -- 'N'
Let's switch to socat which is far more dependable.
Fixes: 025efa0a82df ("selftests: add simple GSO GRE test") Fixes: a985442fdecb ("selftests: net: properly support IPv6 in GSO GRE test") Tested-by: Andrea Righi andrea.righi@canonical.com Link: https://lore.kernel.org/r/20211111162929.530470-1-kuba@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/gre_gso.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/net/gre_gso.sh b/tools/testing/selftests/net/gre_gso.sh index fdeb44d621eb9..3224651db97b8 100755 --- a/tools/testing/selftests/net/gre_gso.sh +++ b/tools/testing/selftests/net/gre_gso.sh @@ -118,16 +118,18 @@ gre_gst_test_checks() local addr=$2 local proto=$3
- $NS_EXEC nc $proto -kl $port >/dev/null & + [ "$proto" == 6 ] && addr="[$addr]" + + $NS_EXEC socat - tcp${proto}-listen:$port,reuseaddr,fork >/dev/null & PID=$! while ! $NS_EXEC ss -ltn | grep -q $port; do ((i++)); sleep 0.01; done
- cat $TMPFILE | timeout 1 nc $proto -N $addr $port + cat $TMPFILE | timeout 1 socat -u STDIN TCP:$addr:$port log_test $? 0 "$name - copy file w/ TSO"
ethtool -K veth0 tso off
- cat $TMPFILE | timeout 1 nc $proto -N $addr $port + cat $TMPFILE | timeout 1 socat -u STDIN TCP:$addr:$port log_test $? 0 "$name - copy file w/ GSO"
ethtool -K veth0 tso on @@ -155,8 +157,8 @@ gre6_gso_test()
sleep 2
- gre_gst_test_checks GREv6/v4 172.16.2.2 - gre_gst_test_checks GREv6/v6 2001:db8:1::2 -6 + gre_gst_test_checks GREv6/v4 172.16.2.2 4 + gre_gst_test_checks GREv6/v6 2001:db8:1::2 6
cleanup } @@ -212,8 +214,8 @@ if [ ! -x "$(command -v ip)" ]; then exit $ksft_skip fi
-if [ ! -x "$(command -v nc)" ]; then - echo "SKIP: Could not run test without nc tool" +if [ ! -x "$(command -v socat)" ]; then + echo "SKIP: Could not run test without socat tool" exit $ksft_skip fi
From: Konrad Dybcio konrad.dybcio@somainline.org
[ Upstream commit 27df68d579c67ef6c39a5047559b6a7c08c96219 ]
The source group count was mistakenly assigned to both dst and src loops. Fix it to make IPA probe and work again.
Fixes: 4fd704b3608a ("net: ipa: record number of groups in data") Acked-by: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Reviewed-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Konrad Dybcio konrad.dybcio@somainline.org Reviewed-by: Alex Elder elder@linaro.org Link: https://lore.kernel.org/r/20211111183724.593478-1-konrad.dybcio@somainline.o... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ipa/ipa_resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ipa/ipa_resource.c b/drivers/net/ipa/ipa_resource.c index e3da95d694099..06cec71993823 100644 --- a/drivers/net/ipa/ipa_resource.c +++ b/drivers/net/ipa/ipa_resource.c @@ -52,7 +52,7 @@ static bool ipa_resource_limits_valid(struct ipa *ipa, return false; }
- group_count = data->rsrc_group_src_count; + group_count = data->rsrc_group_dst_count; if (!group_count || group_count > IPA_RESOURCE_GROUP_MAX) return false;
From: Arjun Roy arjunroy@google.com
[ Upstream commit 70701b83e208767f2720d8cd3e6a62cddafb3a30 ]
TCP Receive zerocopy iterates through the SKB queue via tcp_recv_skb(), acquiring a pointer to an SKB and an offset within that SKB to read from. From there, it iterates the SKB frags array to determine which offset to start remapping pages from.
However, this is built on the assumption that the offset read so far within the SKB is smaller than the SKB length. If this assumption is violated, we can attempt to read an invalid frags array element, which would cause a fault.
tcp_recv_skb() can cause such an SKB to be returned when the TCP FIN flag is set. Therefore, we must guard against this occurrence inside skb_advance_frag().
One way that we can reproduce this error follows: 1) In a receiver program, call getsockopt(TCP_ZEROCOPY_RECEIVE) with: char some_array[32 * 1024]; struct tcp_zerocopy_receive zc = { .copybuf_address = (__u64) &some_array[0], .copybuf_len = 32 * 1024, };
2) In a sender program, after a TCP handshake, send the following sequence of packets: i) Seq = [X, X+4000] ii) Seq = [X+4000, X+5000] iii) Seq = [X+4000, X+5000], Flags = FIN | URG, urgptr=1000
(This can happen without URG, if we have a signal pending, but URG is a convenient way to reproduce the behaviour).
In this case, the following event sequence will occur on the receiver:
tcp_zerocopy_receive(): -> receive_fallback_to_copy() // copybuf_len >= inq -> tcp_recvmsg_locked() // reads 5000 bytes, then breaks due to URG -> tcp_recv_skb() // yields skb with skb->len == offset -> tcp_zerocopy_set_hint_for_skb() -> skb_advance_to_frag() // will returns a frags ptr. >= nr_frags -> find_next_mappable_frag() // will dereference this bad frags ptr.
With this patch, skb_advance_to_frag() will no longer return an invalid frags pointer, and will return NULL instead, fixing the issue.
Signed-off-by: Arjun Roy arjunroy@google.com Signed-off-by: Eric Dumazet edumazet@google.com Fixes: 05255b823a61 ("tcp: add TCP_ZEROCOPY_RECEIVE support for zerocopy receive") Link: https://lore.kernel.org/r/20211111235215.2605384-1-arjunroy.kdev@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8affba5909bdf..844c6e5a82891 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1776,6 +1776,9 @@ static skb_frag_t *skb_advance_to_frag(struct sk_buff *skb, u32 offset_skb, { skb_frag_t *frag;
+ if (unlikely(offset_skb >= skb->len)) + return NULL; + offset_skb -= skb_headlen(skb); if ((int)offset_skb < 0 || skb_has_frag_list(skb)) return NULL;
From: Steven Rostedt (VMware) rostedt@goodmis.org
[ Upstream commit 938aa33f14657c9ed9deea348b7d6f14b6d69cb7 ]
The string copies to the histogram storage has a max size of 256 bytes (defined by MAX_FILTER_STR_VAL). Only the string size of the event field needs to be copied to the event storage, but no more than what is in the event storage. Although nothing should be bigger than 256 bytes, there's no protection against overwriting of the storage if one day there is.
Copy no more than the destination size, and enforce it.
Also had to turn MAX_FILTER_STR_VAL into an unsigned int, to keep the min() comparison of the string sizes of comparable types.
Link: https://lore.kernel.org/all/CAHk-=wjREUihCGrtRBwfX47y_KrLCGjiq3t6QtoNJpmVrAE... Link: https://lkml.kernel.org/r/20211114132834.183429a4@rorschach.local.home
Cc: Ingo Molnar mingo@kernel.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Tom Zanussi zanussi@kernel.org Reported-by: Linus Torvalds torvalds@linux-foundation.org Reviewed-by: Masami Hiramatsu mhiramat@kernel.org Fixes: 63f84ae6b82b ("tracing/histogram: Do not copy the fixed-size char array field over the field size") Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/trace_events.h | 2 +- kernel/trace/trace_events_hist.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 3e475eeb5a995..57113190448c6 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -673,7 +673,7 @@ struct trace_event_file {
#define PERF_MAX_TRACE_SIZE 2048
-#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ +#define MAX_FILTER_STR_VAL 256U /* Should handle KSYM_SYMBOL_LEN */
enum event_trigger_type { ETT_NONE = (0), diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index de37664ef0476..d860351b9dea6 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -2691,8 +2691,10 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, if (val->flags & HIST_FIELD_FL_STRING) { char *str = elt_data->field_var_str[j++]; char *val_str = (char *)(uintptr_t)var_val; + unsigned int size;
- strscpy(str, val_str, val->size); + size = min(val->size, STR_VAR_LEN_MAX); + strscpy(str, val_str, size); var_val = (u64)(uintptr_t)str; } tracing_map_set_var(elt, var_idx, var_val); @@ -4579,6 +4581,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data, if (hist_field->flags & HIST_FIELD_FL_STRING) { unsigned int str_start, var_str_idx, idx; char *str, *val_str; + unsigned int size;
str_start = hist_data->n_field_var_str + hist_data->n_save_var_str; @@ -4587,7 +4590,9 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
str = elt_data->field_var_str[idx]; val_str = (char *)(uintptr_t)hist_val; - strscpy(str, val_str, hist_field->size); + + size = min(hist_field->size, STR_VAR_LEN_MAX); + strscpy(str, val_str, size);
hist_val = (u64)(uintptr_t)str; }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit ce6b69749961426c6d822215ded9e67154e1ad4f ]
Even if userspace specifies the NL80211_ATTR_SURVEY_RADIO_STATS attribute, we cannot get the statistics because we're not really parsing the incoming attributes properly any more.
Fix this by passing the attrbuf to nl80211_prepare_wdev_dump() and filling it there, if given, and using a local version only if no output is desired.
Since I'm touching it anyway, make nl80211_prepare_wdev_dump() static.
Fixes: 50508d941c18 ("cfg80211: use parallel_ops for genl") Reported-by: Jan Fuchs jf@simonwunderlich.de Signed-off-by: Johannes Berg johannes.berg@intel.com Tested-by: Sven Eckelmann sven@narfation.org Link: https://lore.kernel.org/r/20211029092539.2851b4799386.If9736d4575ee79420cbec... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/nl80211.c | 34 +++++++++++++++++++--------------- net/wireless/nl80211.h | 6 +----- 2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index bf7cd47525472..16b3d0cc0bdb0 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -922,33 +922,37 @@ nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, };
-int nl80211_prepare_wdev_dump(struct netlink_callback *cb, - struct cfg80211_registered_device **rdev, - struct wireless_dev **wdev) +static int nl80211_prepare_wdev_dump(struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, + struct wireless_dev **wdev, + struct nlattr **attrbuf) { int err;
if (!cb->args[0]) { - struct nlattr **attrbuf; + struct nlattr **attrbuf_free = NULL;
- attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), - GFP_KERNEL); - if (!attrbuf) - return -ENOMEM; + if (!attrbuf) { + attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), + GFP_KERNEL); + if (!attrbuf) + return -ENOMEM; + attrbuf_free = attrbuf; + }
err = nlmsg_parse_deprecated(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, attrbuf, nl80211_fam.maxattr, nl80211_policy, NULL); if (err) { - kfree(attrbuf); + kfree(attrbuf_free); return err; }
rtnl_lock(); *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(cb->skb->sk), attrbuf); - kfree(attrbuf); + kfree(attrbuf_free); if (IS_ERR(*wdev)) { rtnl_unlock(); return PTR_ERR(*wdev); @@ -6001,7 +6005,7 @@ static int nl80211_dump_station(struct sk_buff *skb, int sta_idx = cb->args[2]; int err;
- err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev); + err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL); if (err) return err; /* nl80211_prepare_wdev_dump acquired it in the successful case */ @@ -6896,7 +6900,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb, int path_idx = cb->args[2]; int err;
- err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev); + err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL); if (err) return err; /* nl80211_prepare_wdev_dump acquired it in the successful case */ @@ -7096,7 +7100,7 @@ static int nl80211_dump_mpp(struct sk_buff *skb, int path_idx = cb->args[2]; int err;
- err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev); + err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL); if (err) return err; /* nl80211_prepare_wdev_dump acquired it in the successful case */ @@ -9518,7 +9522,7 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) int start = cb->args[2], idx = 0; int err;
- err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev); + err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL); if (err) return err; /* nl80211_prepare_wdev_dump acquired it in the successful case */ @@ -9651,7 +9655,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) if (!attrbuf) return -ENOMEM;
- res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev); + res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, attrbuf); if (res) { kfree(attrbuf); return res; diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index a3f387770f1bf..d642e3be4ee78 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Portions of this file - * Copyright (C) 2018, 2020 Intel Corporation + * Copyright (C) 2018, 2020-2021 Intel Corporation */ #ifndef __NET_WIRELESS_NL80211_H #define __NET_WIRELESS_NL80211_H @@ -22,10 +22,6 @@ static inline u64 wdev_id(struct wireless_dev *wdev) ((u64)wiphy_to_rdev(wdev->wiphy)->wiphy_idx << 32); }
-int nl80211_prepare_wdev_dump(struct netlink_callback *cb, - struct cfg80211_registered_device **rdev, - struct wireless_dev **wdev); - int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, struct genl_info *info, struct cfg80211_chan_def *chandef);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 6dd2360334f3cb3b45fc1b8194c670090474b87c ]
Since commit a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") we've not only been protecting the pointer to monitor_sdata with the RTNL, but also with the wiphy->mtx. This is relevant in a number of lockdep assertions, e.g. the one we hit in ieee80211_set_monitor_channel(). However, we're now protecting all the assignments/dereferences, even the one in interface iter, with the wiphy->mtx, so switch over the lockdep assertions to that lock.
Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20211112135143.cb8e8ceffef3.Iaa210f16f6904c8a7a249... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/cfg.c | 12 ++++++++---- net/mac80211/iface.c | 4 +++- net/mac80211/util.c | 7 ++++--- 3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d69b31c20fe28..d3f62fd12f0b5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -80,7 +80,8 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata, }
/* also validate MU-MIMO change */ - monitor_sdata = rtnl_dereference(local->monitor_sdata); + monitor_sdata = wiphy_dereference(local->hw.wiphy, + local->monitor_sdata);
if (!monitor_sdata && (params->vht_mumimo_groups || params->vht_mumimo_follow_addr)) @@ -810,7 +811,8 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
mutex_lock(&local->mtx); if (local->use_chanctx) { - sdata = rtnl_dereference(local->monitor_sdata); + sdata = wiphy_dereference(local->hw.wiphy, + local->monitor_sdata); if (sdata) { ieee80211_vif_release_channel(sdata); ret = ieee80211_vif_use_channel(sdata, chandef, @@ -2669,7 +2671,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { - sdata = rtnl_dereference(local->monitor_sdata); + sdata = wiphy_dereference(local->hw.wiphy, + local->monitor_sdata); if (!sdata) return -EOPNOTSUPP; } @@ -2729,7 +2732,8 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, mutex_unlock(&local->iflist_mtx);
if (has_monitor) { - sdata = rtnl_dereference(local->monitor_sdata); + sdata = wiphy_dereference(local->hw.wiphy, + local->monitor_sdata); if (sdata) { sdata->user_power_level = local->user_power_level; if (txp_type != sdata->vif.bss_conf.txpower_type) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 62c95597704b4..041859b5b71d0 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -588,7 +588,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do */ if (local->suspended) { WARN_ON(local->wowlan); - WARN_ON(rtnl_dereference(local->monitor_sdata)); + WARN_ON(rcu_access_pointer(local->monitor_sdata)); return; }
@@ -932,6 +932,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) return 0;
ASSERT_RTNL(); + lockdep_assert_wiphy(local->hw.wiphy);
if (local->monitor_sdata) return 0; @@ -999,6 +1000,7 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) return;
ASSERT_RTNL(); + lockdep_assert_wiphy(local->hw.wiphy);
mutex_lock(&local->iflist_mtx);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 49cb96d251695..03ea4f929b997 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -796,7 +796,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
sdata = rcu_dereference_check(local->monitor_sdata, lockdep_is_held(&local->iflist_mtx) || - lockdep_rtnl_is_held()); + lockdep_is_held(&local->hw.wiphy->mtx)); if (sdata && (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only || sdata->flags & IEEE80211_SDATA_IN_DRIVER)) @@ -2379,7 +2379,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) IEEE80211_TPT_LEDTRIG_FL_RADIO, 0);
/* add interfaces */ - sdata = rtnl_dereference(local->monitor_sdata); + sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata); if (sdata) { /* in HW restart it exists already */ WARN_ON(local->resuming); @@ -2424,7 +2424,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) WARN_ON(drv_add_chanctx(local, ctx)); mutex_unlock(&local->chanctx_mtx);
- sdata = rtnl_dereference(local->monitor_sdata); + sdata = wiphy_dereference(local->hw.wiphy, + local->monitor_sdata); if (sdata && ieee80211_sdata_running(sdata)) ieee80211_assign_chanctx(local, sdata); }
From: Alex Elder elder@linaro.org
[ Upstream commit 6e228d8cbb1cc6ba78022d406340e901e08d26e0 ]
Starting with IPA v4.5, the HOL_BLOCK_EN register must be written twice when enabling head-of-line blocking avoidance.
Fixes: 84f9bd12d46db ("soc: qcom: ipa: IPA endpoints") 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 | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index 5528d97110d56..006da4642a0ba 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -868,6 +868,9 @@ ipa_endpoint_init_hol_block_enable(struct ipa_endpoint *endpoint, bool enable) val = enable ? HOL_BLOCK_EN_FMASK : 0; offset = IPA_REG_ENDP_INIT_HOL_BLOCK_EN_N_OFFSET(endpoint_id); iowrite32(val, endpoint->ipa->reg_virt + offset); + /* When enabling, the register must be written twice for IPA v4.5+ */ + if (enable && endpoint->ipa->version >= IPA_VERSION_4_5) + iowrite32(val, endpoint->ipa->reg_virt + offset); }
void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa)
From: Alex Elder elder@linaro.org
[ Upstream commit 816316cacad2b5abd5b41423cf04e4845239abd4 ]
The head-of-line blocking timer should only be modified when head-of-line drop is disabled.
One of the steps in recovering from a modem crash is to enable dropping of packets with timeout of 0 (immediate). We don't know how the modem configured its endpoints, so before we program the timer, we need to ensure HOL_BLOCK is disabled.
Fixes: 84f9bd12d46db ("soc: qcom: ipa: IPA endpoints") 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 | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c index 006da4642a0ba..ef790fd0ab56a 100644 --- a/drivers/net/ipa/ipa_endpoint.c +++ b/drivers/net/ipa/ipa_endpoint.c @@ -853,6 +853,7 @@ static void ipa_endpoint_init_hol_block_timer(struct ipa_endpoint *endpoint, u32 offset; u32 val;
+ /* This should only be changed when HOL_BLOCK_EN is disabled */ offset = IPA_REG_ENDP_INIT_HOL_BLOCK_TIMER_N_OFFSET(endpoint_id); val = hol_block_timer_val(ipa, microseconds); iowrite32(val, ipa->reg_virt + offset); @@ -883,6 +884,7 @@ void ipa_endpoint_modem_hol_block_clear_all(struct ipa *ipa) if (endpoint->toward_ipa || endpoint->ee_id != GSI_EE_MODEM) continue;
+ ipa_endpoint_init_hol_block_enable(endpoint, false); ipa_endpoint_init_hol_block_timer(endpoint, 0); ipa_endpoint_init_hol_block_enable(endpoint, true); }
From: Li Zhijian lizhijian@cn.fujitsu.com
[ Upstream commit 92a59d7f381d2caf69385bfa00590028e32eea26 ]
The gpio selftests build against the system includes rather than the headers from the linux tree. This results in the compile failing if the system includes are outdated.
Prefer the headers from the linux tree, as per other selftests.
Fixes: 8bc395a6a2e2 ("selftests: gpio: rework and simplify test implementation") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Li Zhijian lizhijian@cn.fujitsu.com [Kent: reworded commit comment and added Fixes:] Signed-off-by: Kent Gibson warthog618@gmail.com Signed-off-by: Bartosz Golaszewski brgl@bgdev.pl Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/gpio/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/gpio/Makefile b/tools/testing/selftests/gpio/Makefile index 39f2bbe8dd3df..42ea7d2aa8440 100644 --- a/tools/testing/selftests/gpio/Makefile +++ b/tools/testing/selftests/gpio/Makefile @@ -3,5 +3,6 @@ TEST_PROGS := gpio-mockup.sh TEST_FILES := gpio-mockup-sysfs.sh TEST_GEN_PROGS_EXTENDED := gpio-mockup-cdev +CFLAGS += -I../../../../usr/include
include ../lib.mk
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit f8885ac89ce310570e5391fe0bf0ec9c7c9b4fdc ]
Smatch says: bnx2x_init_ops.h:640 bnx2x_ilt_client_mem_op() warn: variable dereferenced before check 'ilt' (see line 638)
Move ilt_cli variable initialization _after_ ilt validation, because it's unsafe to deref the pointer before validation check.
Fixes: 523224a3b3cd ("bnx2x, cnic, bnx2i: use new FW/HSI") Signed-off-by: Pavel Skripkin paskripkin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h index 1835d2e451c01..fc7fce642666c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h @@ -635,11 +635,13 @@ static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, { int i, rc; struct bnx2x_ilt *ilt = BP_ILT(bp); - struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + struct ilt_client_info *ilt_cli;
if (!ilt || !ilt->lines) return -1;
+ ilt_cli = &ilt->clients[cli_num]; + if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM)) return 0;
From: Sriharsha Basavapatna sriharsha.basavapatna@broadcom.com
[ Upstream commit b0757491a118ae5727cf9f1c3a11544397d46596 ]
The driver does not check if hw-tc-offload is enabled for the device before offloading a flow in the context of indirect block callback. Fix this by checking NETIF_F_HW_TC in the features flag and rejecting the offload request. This will avoid unnecessary dmesg error logs when hw-tc-offload is disabled, such as these:
bnxt_en 0000:19:00.1 eno2np1: dev(ifindex=294) not on same switch bnxt_en 0000:19:00.1 eno2np1: Error: bnxt_tc_add_flow: cookie=0xffff8dace1c88000 error=-22 bnxt_en 0000:19:00.0 eno1np0: dev(ifindex=294) not on same switch bnxt_en 0000:19:00.0 eno1np0: Error: bnxt_tc_add_flow: cookie=0xffff8dace1c88000 error=-22
Reported-by: Marcelo Ricardo Leitner mleitner@redhat.com Fixes: 627c89d00fb9 ("bnxt_en: flow_offload: offload tunnel decap rules via indirect callbacks") Signed-off-by: Sriharsha Basavapatna sriharsha.basavapatna@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_tc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index e6a4a768b10b2..1471b6130a2b9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c @@ -1868,7 +1868,7 @@ static int bnxt_tc_setup_indr_block_cb(enum tc_setup_type type, struct flow_cls_offload *flower = type_data; struct bnxt *bp = priv->bp;
- if (flower->common.chain_index) + if (!tc_cls_can_offload_and_chain0(bp->dev, type_data)) return -EOPNOTSUPP;
switch (type) {
From: Xin Long lucien.xin@gmail.com
[ Upstream commit 271351d255b09e39c7f6437738cba595f9b235be ]
The MSG_CRYPTO msgs are always encrypted and sent to other nodes for keys' deployment. But when receiving in peers, if those nodes do not validate it and make sure it's encrypted, one could craft a malicious MSG_CRYPTO msg to deploy its key with no need to know other nodes' keys.
This patch is to do that by checking TIPC_SKB_CB(skb)->decrypted and discard it if this packet never got decrypted.
Note that this is also a supplementary fix to CVE-2021-43267 that can be triggered by an unencrypted malicious MSG_CRYPTO msg.
Fixes: 1ef6f7c9390f ("tipc: add automatic session key exchange") Acked-by: Ying Xue ying.xue@windriver.com Acked-by: Jon Maloy jmaloy@redhat.com Signed-off-by: Xin Long lucien.xin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/link.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c index 1b7a487c88419..09ae8448f394f 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1298,8 +1298,11 @@ static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb, return false; #ifdef CONFIG_TIPC_CRYPTO case MSG_CRYPTO: - tipc_crypto_msg_rcv(l->net, skb); - return true; + if (TIPC_SKB_CB(skb)->decrypted) { + tipc_crypto_msg_rcv(l->net, skb); + return true; + } + fallthrough; #endif default: pr_warn("Dropping received illegal msg type\n");
From: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp
[ Upstream commit 938cca9e4109b30ee1d476904538225a825e54eb ]
sk_clone_lock() needs to call sock_inuse_add(1) before entering the sk_free_unlock_clone() error path, for __sk_free() from sk_free() from sk_free_unlock_clone() calls sock_inuse_add(-1).
Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Fixes: 648845ab7e200993 ("sock: Move the socket inuse to namespace.") Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/sock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c index c1601f75ec4b3..1b31e10181629 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2043,8 +2043,10 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) newsk->sk_prot_creator = prot;
/* SANITY */ - if (likely(newsk->sk_net_refcnt)) + if (likely(newsk->sk_net_refcnt)) { get_net(sock_net(newsk)); + sock_inuse_add(sock_net(newsk), 1); + } sk_node_init(&newsk->sk_node); sock_lock_init(newsk); bh_lock_sock(newsk); @@ -2115,8 +2117,6 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) newsk->sk_err_soft = 0; newsk->sk_priority = 0; newsk->sk_incoming_cpu = raw_smp_processor_id(); - if (likely(newsk->sk_net_refcnt)) - sock_inuse_add(sock_net(newsk), 1);
/* Before updating sk_refcnt, we must commit prior changes to memory * (Documentation/RCU/rculist_nulls.rst for details)
From: Wen Gu guwen@linux.alibaba.com
[ Upstream commit cf4f5530bb55ef7d5a91036b26676643b80b1616 ]
The link_id is supposed to be unique, but smcr_next_link_id() doesn't skip the used link_id as expected. So the patch fixes this.
Fixes: 026c381fb477 ("net/smc: introduce link_idx for link group array") Signed-off-by: Wen Gu guwen@linux.alibaba.com Reviewed-by: Tony Lu tonylu@linux.alibaba.com Acked-by: Karsten Graul kgraul@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/smc/smc_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index d2206743dc714..d672c0f0e247f 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -665,13 +665,14 @@ static u8 smcr_next_link_id(struct smc_link_group *lgr) int i;
while (1) { +again: link_id = ++lgr->next_link_id; if (!link_id) /* skip zero as link_id */ link_id = ++lgr->next_link_id; for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { if (smc_link_usable(&lgr->lnk[i]) && lgr->lnk[i].link_id == link_id) - continue; + goto again; } break; }
From: Chuck Lever chuck.lever@oracle.com
[ Upstream commit c0019b7db1d7ac62c711cda6b357a659d46428fe ]
rtm@csail.mit.edu reports:
nfsd4_decode_bitmap4() will write beyond bmval[bmlen-1] if the RPC directs it to do so. This can cause nfsd4_decode_state_protect4_a() to write client-supplied data beyond the end of nfsd4_exchange_id.spo_must_allow[] when called by nfsd4_decode_exchange_id().
Rewrite the loops so nfsd4_decode_bitmap() cannot iterate beyond @bmlen.
Reported by: rtm@csail.mit.edu Fixes: d1c263a031e8 ("NFSD: Replace READ* macros in nfsd4_decode_fattr()") Signed-off-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: J. Bruce Fields bfields@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfsd/nfs4xdr.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index cf030ebe28275..266d5152c3216 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -288,11 +288,8 @@ nfsd4_decode_bitmap4(struct nfsd4_compoundargs *argp, u32 *bmval, u32 bmlen) p = xdr_inline_decode(argp->xdr, count << 2); if (!p) return nfserr_bad_xdr; - i = 0; - while (i < count) - bmval[i++] = be32_to_cpup(p++); - while (i < bmlen) - bmval[i++] = 0; + for (i = 0; i < bmlen; i++) + bmval[i] = (i < count) ? be32_to_cpup(p++) : 0;
return nfs_ok; }
From: Mateusz Palczewski mateusz.palczewski@intel.com
[ Upstream commit 4e5e6b5d9d1334d3490326b6922a2daaf56a867f ]
Fixed return correct code from set the new channel count. Implemented by check if reset is done in appropriate time. This solution give a extra time to pf for reset vf in case when user want set new channel count for all vfs. Without this patch it is possible to return misleading output code to user and vf reset not to be correctly performed by pf.
Fixes: 5520deb15326 ("iavf: Enable support for up to 16 queues") Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Signed-off-by: Mateusz Palczewski mateusz.palczewski@intel.com 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/iavf/iavf_ethtool.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index 5a359a0a20ecc..136c801f5584a 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -1776,6 +1776,7 @@ static int iavf_set_channels(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev); u32 num_req = ch->combined_count; + int i;
if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && adapter->num_tc) { @@ -1798,6 +1799,20 @@ static int iavf_set_channels(struct net_device *netdev, adapter->num_req_queues = num_req; adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; iavf_schedule_reset(adapter); + + /* wait for the reset is done */ + for (i = 0; i < IAVF_RESET_WAIT_COMPLETE_COUNT; i++) { + msleep(IAVF_RESET_WAIT_MS); + if (adapter->flags & IAVF_FLAG_RESET_PENDING) + continue; + break; + } + if (i == IAVF_RESET_WAIT_COMPLETE_COUNT) { + adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; + adapter->num_active_queues = num_req; + return -EOPNOTSUPP; + } + return 0; }
From: Nicholas Nunley nicholas.d.nunley@intel.com
[ Upstream commit 8a4a126f4be88eb8b5f00a165ab58c35edf4ef76 ]
If the driver has lost contact with the PF then it enters a disabled state and frees adapter->vf_res. However, ndo_fix_features can still be called on the interface, so we need to check for this condition first. Since we have no information on the features at this time simply leave them unmodified and return.
Fixes: c4445aedfe09 ("i40evf: Fix VLAN features") Signed-off-by: Nicholas Nunley nicholas.d.nunley@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index cada4e0e40b48..12976ccca1b6e 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3442,7 +3442,8 @@ static netdev_features_t iavf_fix_features(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev);
- if (!(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) + if (adapter->vf_res && + !(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) features &= ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER);
From: Nicholas Nunley nicholas.d.nunley@intel.com
[ Upstream commit 89f22f129696ab53cfbc608e0a2184d0fea46ac1 ]
iavf_free_queues() clears adapter->num_active_queues, which iavf_free_q_vectors() relies on, so swap the order of these two function calls in iavf_disable_vf(). This resolves a panic encountered when the interface is disabled and then later brought up again after PF communication is restored.
Fixes: 65c7006f234c ("i40evf: assign num_active_queues inside i40evf_alloc_queues") Signed-off-by: Nicholas Nunley nicholas.d.nunley@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 12976ccca1b6e..5664a1905e8bb 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -2074,8 +2074,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
iavf_free_misc_irq(adapter); iavf_reset_interrupt_capability(adapter); - iavf_free_queues(adapter); iavf_free_q_vectors(adapter); + iavf_free_queues(adapter); memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); iavf_shutdown_adminq(&adapter->hw); adapter->netdev->flags &= ~IFF_UP;
From: Nicholas Nunley nicholas.d.nunley@intel.com
[ Upstream commit 2135a8d5c8186bc92901dc00f179ffd50e54c2ac ]
In iavf_configure_clsflower() the function will bail out if it is unable to obtain the crit_section lock in a reasonable time. However, it will clear the lock when exiting, so fix this.
Fixes: 640a8af5841f ("i40evf: Reorder configure_clsflower to avoid deadlock on error") Signed-off-by: Nicholas Nunley nicholas.d.nunley@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 5664a1905e8bb..f64ccf6286ec1 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3041,8 +3041,10 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, return -ENOMEM;
while (!mutex_trylock(&adapter->crit_lock)) { - if (--count == 0) - goto err; + if (--count == 0) { + kfree(filter); + return err; + } udelay(1); }
From: Piotr Marczak piotr.marczak@intel.com
[ Upstream commit 8905072a192fffe9389255489db250c73ecab008 ]
The driver could only quit allmulti when allmulti and promisc modes are turn on at the same time. If promisc had been off there was no way to turn off allmulti mode. The patch corrects this behavior. Switching allmulti does not depends on promisc state mode anymore
Fixes: f42a5c74da99 ("i40e: Add allmulti support for the VF") Signed-off-by: Piotr Marczak piotr.marczak@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index f64ccf6286ec1..44ea67cb3716b 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -1630,8 +1630,7 @@ static int iavf_process_aq_command(struct iavf_adapter *adapter) iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); return 0; } - - if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) && + if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) || (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { iavf_set_promiscuous(adapter, 0); return 0;
From: Jacob Keller jacob.e.keller@intel.com
[ Upstream commit 4f0400803818f2642f066d3eacaf013f23554cc7 ]
In iavf_config_clsflower, the filter structure could be accidentally released at the end, if iavf_parse_cls_flower or iavf_handle_tclass ever return a non-zero but positive value.
In this case, the function continues through to the end, and will call kfree() on the filter structure even though it has been added to the linked list.
This can actually happen because iavf_parse_cls_flower will return a positive IAVF_ERR_CONFIG value instead of the traditional negative error codes.
Fix this by ensuring that the kfree() check and error checks are similar. Use the more idiomatic "if (err)" to catch all non-zero error codes.
Fixes: 0075fa0fadd0 ("i40evf: Add support to apply cloud filters") Signed-off-by: Jacob Keller jacob.e.keller@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 44ea67cb3716b..43c33effd4177 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3054,11 +3054,11 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, /* start out with flow type and eth type IPv4 to begin with */ filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW; err = iavf_parse_cls_flower(adapter, cls_flower, filter); - if (err < 0) + if (err) goto err;
err = iavf_handle_tclass(adapter, tc, filter); - if (err < 0) + if (err) goto err;
/* add filter to the list */
From: Mitch Williams mitch.a.williams@intel.com
[ Upstream commit 131b0edc4028bb88bb472456b1ddba526cfb7036 ]
In some cases, the ethtool get_rxfh handler may be called with a null key or indir parameter. So check these pointers, or you will have a very bad day.
Fixes: 43a3d9ba34c9 ("i40evf: Allow PF driver to configure RSS") Signed-off-by: Mitch Williams mitch.a.williams@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index 136c801f5584a..25ee0606e625f 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -1859,14 +1859,13 @@ static int iavf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
if (hfunc) *hfunc = ETH_RSS_HASH_TOP; - if (!indir) - return 0; - - memcpy(key, adapter->rss_key, adapter->rss_key_size); + if (key) + memcpy(key, adapter->rss_key, adapter->rss_key_size);
- /* Each 32 bits pointed by 'indir' is stored with a lut entry */ - for (i = 0; i < adapter->rss_lut_size; i++) - indir[i] = (u32)adapter->rss_lut[i]; + if (indir) + /* Each 32 bits pointed by 'indir' is stored with a lut entry */ + for (i = 0; i < adapter->rss_lut_size; i++) + indir[i] = (u32)adapter->rss_lut[i];
return 0; }
From: Surabhi Boob surabhi.boob@intel.com
[ Upstream commit 321421b57a12e933f92b228e0e6d0b2c6541f41d ]
While issuing VF Reset from the guest OS, the VF driver prints logs about critical / Overflow error detection. This is not an actual error since the VF_MBX_ARQLEN register is set to all FF's for a short period of time and the VF would catch the bits set if it was reading the register during that spike of time. This patch introduces an additional check to ignore this condition since the VF is in reset.
Fixes: 19b73d8efaa4 ("i40evf: Add additional check for reset") Signed-off-by: Surabhi Boob surabhi.boob@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 43c33effd4177..d537d50525e3f 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -2355,7 +2355,7 @@ static void iavf_adminq_task(struct work_struct *work)
/* check for error indications */ val = rd32(hw, hw->aq.arq.len); - if (val == 0xdeadbeef) /* indicates device in reset */ + if (val == 0xdeadbeef || val == 0xffffffff) /* device in reset */ goto freedom; oldval = val; if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) {
From: Grzegorz Szczurek grzegorzx.szczurek@intel.com
[ Upstream commit 9a6e9e483a9684a34573fd9f9e30ecfb047cb8cb ]
Now setting combine to 0 will be rejected with the appropriate error code. This has been implemented by adding a condition that checks the value of combine equal to zero. Without this patch, when the user requested it, no error was returned and combine was set to the default value for VF.
Fixes: 5520deb15326 ("iavf: Enable support for up to 16 queues") Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf_ethtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index 25ee0606e625f..144a776793597 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -1787,7 +1787,7 @@ static int iavf_set_channels(struct net_device *netdev, /* All of these should have already been checked by ethtool before this * even gets to us, but just to be sure. */ - if (num_req > adapter->vsi_res->num_queue_pairs) + if (num_req == 0 || num_req > adapter->vsi_res->num_queue_pairs) return -EINVAL;
if (num_req == adapter->num_active_queues)
From: Akeem G Abodunrin akeem.g.abodunrin@intel.com
[ Upstream commit 4293014230b887d94b68aa460ff00153454a3709 ]
Restore VLAN filters after the link is brought down, and up - since all filters are deleted from HW during the netdev link down routine.
Fixes: ed1f5b58ea01 ("i40evf: remove VLAN filters on close") Signed-off-by: Akeem G Abodunrin akeem.g.abodunrin@intel.com Tested-by: George Kuruvinakunnel george.kuruvinakunnel@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/iavf/iavf.h | 1 + drivers/net/ethernet/intel/iavf/iavf_main.c | 35 ++++++++++++++++++--- 2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 68c80f04113c8..46312a4415baf 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -39,6 +39,7 @@ #include "iavf_txrx.h" #include "iavf_fdir.h" #include "iavf_adv_rss.h" +#include <linux/bitmap.h>
#define DEFAULT_DEBUG_LEVEL_SHIFT 3 #define PFX "iavf: " diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index d537d50525e3f..aaf8a2f396e46 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -687,6 +687,23 @@ static void iavf_del_vlan(struct iavf_adapter *adapter, u16 vlan) spin_unlock_bh(&adapter->mac_vlan_list_lock); }
+/** + * iavf_restore_filters + * @adapter: board private structure + * + * Restore existing non MAC filters when VF netdev comes back up + **/ +static void iavf_restore_filters(struct iavf_adapter *adapter) +{ + /* re-add all VLAN filters */ + if (VLAN_ALLOWED(adapter)) { + u16 vid; + + for_each_set_bit(vid, adapter->vsi.active_vlans, VLAN_N_VID) + iavf_add_vlan(adapter, vid); + } +} + /** * iavf_vlan_rx_add_vid - Add a VLAN filter to a device * @netdev: network device struct @@ -700,8 +717,11 @@ static int iavf_vlan_rx_add_vid(struct net_device *netdev,
if (!VLAN_ALLOWED(adapter)) return -EIO; + if (iavf_add_vlan(adapter, vid) == NULL) return -ENOMEM; + + set_bit(vid, adapter->vsi.active_vlans); return 0; }
@@ -716,11 +736,13 @@ static int iavf_vlan_rx_kill_vid(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev);
- if (VLAN_ALLOWED(adapter)) { - iavf_del_vlan(adapter, vid); - return 0; - } - return -EIO; + if (!VLAN_ALLOWED(adapter)) + return -EIO; + + iavf_del_vlan(adapter, vid); + clear_bit(vid, adapter->vsi.active_vlans); + + return 0; }
/** @@ -3248,6 +3270,9 @@ static int iavf_open(struct net_device *netdev)
spin_unlock_bh(&adapter->mac_vlan_list_lock);
+ /* Restore VLAN filters that were removed with IFF_DOWN */ + iavf_restore_filters(adapter); + iavf_configure(adapter);
iavf_up_complete(adapter);
From: Daniel Borkmann daniel@iogearbox.net
[ Upstream commit 353050be4c19e102178ccc05988101887c25ae53 ]
Commit a23740ec43ba ("bpf: Track contents of read-only maps as scalars") is checking whether maps are read-only both from BPF program side and user space side, and then, given their content is constant, reading out their data via map->ops->map_direct_value_addr() which is then subsequently used as known scalar value for the register, that is, it is marked as __mark_reg_known() with the read value at verification time. Before a23740ec43ba, the register content was marked as an unknown scalar so the verifier could not make any assumptions about the map content.
The current implementation however is prone to a TOCTOU race, meaning, the value read as known scalar for the register is not guaranteed to be exactly the same at a later point when the program is executed, and as such, the prior made assumptions of the verifier with regards to the program will be invalid which can cause issues such as OOB access, etc.
While the BPF_F_RDONLY_PROG map flag is always fixed and required to be specified at map creation time, the map->frozen property is initially set to false for the map given the map value needs to be populated, e.g. for global data sections. Once complete, the loader "freezes" the map from user space such that no subsequent updates/deletes are possible anymore. For the rest of the lifetime of the map, this freeze one-time trigger cannot be undone anymore after a successful BPF_MAP_FREEZE cmd return. Meaning, any new BPF_* cmd calls which would update/delete map entries will be rejected with -EPERM since map_get_sys_perms() removes the FMODE_CAN_WRITE permission. This also means that pending update/delete map entries must still complete before this guarantee is given. This corner case is not an issue for loaders since they create and prepare such program private map in successive steps.
However, a malicious user is able to trigger this TOCTOU race in two different ways: i) via userfaultfd, and ii) via batched updates. For i) userfaultfd is used to expand the competition interval, so that map_update_elem() can modify the contents of the map after map_freeze() and bpf_prog_load() were executed. This works, because userfaultfd halts the parallel thread which triggered a map_update_elem() at the time where we copy key/value from the user buffer and this already passed the FMODE_CAN_WRITE capability test given at that time the map was not "frozen". Then, the main thread performs the map_freeze() and bpf_prog_load(), and once that had completed successfully, the other thread is woken up to complete the pending map_update_elem() which then changes the map content. For ii) the idea of the batched update is similar, meaning, when there are a large number of updates to be processed, it can increase the competition interval between the two. It is therefore possible in practice to modify the contents of the map after executing map_freeze() and bpf_prog_load().
One way to fix both i) and ii) at the same time is to expand the use of the map's map->writecnt. The latter was introduced in fc9702273e2e ("bpf: Add mmap() support for BPF_MAP_TYPE_ARRAY") and further refined in 1f6cb19be2e2 ("bpf: Prevent re-mmap()'ing BPF map as writable for initially r/o mapping") with the rationale to make a writable mmap()'ing of a map mutually exclusive with read-only freezing. The counter indicates writable mmap() mappings and then prevents/fails the freeze operation. Its semantics can be expanded beyond just mmap() by generally indicating ongoing write phases. This would essentially span any parallel regular and batched flavor of update/delete operation and then also have map_freeze() fail with -EBUSY. For the check_mem_access() in the verifier we expand upon the bpf_map_is_rdonly() check ensuring that all last pending writes have completed via bpf_map_write_active() test. Once the map->frozen is set and bpf_map_write_active() indicates a map->writecnt of 0 only then we are really guaranteed to use the map's data as known constants. For map->frozen being set and pending writes in process of still being completed we fall back to marking that register as unknown scalar so we don't end up making assumptions about it. With this, both TOCTOU reproducers from i) and ii) are fixed.
Note that the map->writecnt has been converted into a atomic64 in the fix in order to avoid a double freeze_mutex mutex_{un,}lock() pair when updating map->writecnt in the various map update/delete BPF_* cmd flavors. Spanning the freeze_mutex over entire map update/delete operations in syscall side would not be possible due to then causing everything to be serialized. Similarly, something like synchronize_rcu() after setting map->frozen to wait for update/deletes to complete is not possible either since it would also have to span the user copy which can sleep. On the libbpf side, this won't break d66562fba1ce ("libbpf: Add BPF object skeleton support") as the anonymous mmap()-ed "map initialization image" is remapped as a BPF map-backed mmap()-ed memory where for .rodata it's non-writable.
Fixes: a23740ec43ba ("bpf: Track contents of read-only maps as scalars") Reported-by: w1tcher.bupt@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/bpf.h | 3 ++- kernel/bpf/syscall.c | 57 +++++++++++++++++++++++++++---------------- kernel/bpf/verifier.c | 17 ++++++++++++- 3 files changed, 54 insertions(+), 23 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 3db6f6c95489e..bca11ac818c1f 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -190,7 +190,7 @@ struct bpf_map { atomic64_t usercnt; struct work_struct work; struct mutex freeze_mutex; - u64 writecnt; /* writable mmap cnt; protected by freeze_mutex */ + atomic64_t writecnt; };
static inline bool map_value_has_spin_lock(const struct bpf_map *map) @@ -1387,6 +1387,7 @@ void bpf_map_put(struct bpf_map *map); void *bpf_map_area_alloc(u64 size, int numa_node); void *bpf_map_area_mmapable_alloc(u64 size, int numa_node); void bpf_map_area_free(void *base); +bool bpf_map_write_active(const struct bpf_map *map); void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr); int generic_map_lookup_batch(struct bpf_map *map, const union bpf_attr *attr, diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 1cad6979a0d0f..ecd51a8a8680c 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -132,6 +132,21 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) return map; }
+static void bpf_map_write_active_inc(struct bpf_map *map) +{ + atomic64_inc(&map->writecnt); +} + +static void bpf_map_write_active_dec(struct bpf_map *map) +{ + atomic64_dec(&map->writecnt); +} + +bool bpf_map_write_active(const struct bpf_map *map) +{ + return atomic64_read(&map->writecnt) != 0; +} + static u32 bpf_map_value_size(const struct bpf_map *map) { if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || @@ -596,11 +611,8 @@ static void bpf_map_mmap_open(struct vm_area_struct *vma) { struct bpf_map *map = vma->vm_file->private_data;
- if (vma->vm_flags & VM_MAYWRITE) { - mutex_lock(&map->freeze_mutex); - map->writecnt++; - mutex_unlock(&map->freeze_mutex); - } + if (vma->vm_flags & VM_MAYWRITE) + bpf_map_write_active_inc(map); }
/* called for all unmapped memory region (including initial) */ @@ -608,11 +620,8 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma) { struct bpf_map *map = vma->vm_file->private_data;
- if (vma->vm_flags & VM_MAYWRITE) { - mutex_lock(&map->freeze_mutex); - map->writecnt--; - mutex_unlock(&map->freeze_mutex); - } + if (vma->vm_flags & VM_MAYWRITE) + bpf_map_write_active_dec(map); }
static const struct vm_operations_struct bpf_map_default_vmops = { @@ -663,7 +672,7 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma) goto out;
if (vma->vm_flags & VM_MAYWRITE) - map->writecnt++; + bpf_map_write_active_inc(map); out: mutex_unlock(&map->freeze_mutex); return err; @@ -1122,6 +1131,7 @@ static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr) map = __bpf_map_get(f); if (IS_ERR(map)) return PTR_ERR(map); + bpf_map_write_active_inc(map); if (!(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) { err = -EPERM; goto err_put; @@ -1157,6 +1167,7 @@ free_value: free_key: kvfree(key); err_put: + bpf_map_write_active_dec(map); fdput(f); return err; } @@ -1179,6 +1190,7 @@ static int map_delete_elem(union bpf_attr *attr) map = __bpf_map_get(f); if (IS_ERR(map)) return PTR_ERR(map); + bpf_map_write_active_inc(map); if (!(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) { err = -EPERM; goto err_put; @@ -1209,6 +1221,7 @@ static int map_delete_elem(union bpf_attr *attr) out: kvfree(key); err_put: + bpf_map_write_active_dec(map); fdput(f); return err; } @@ -1516,6 +1529,7 @@ static int map_lookup_and_delete_elem(union bpf_attr *attr) map = __bpf_map_get(f); if (IS_ERR(map)) return PTR_ERR(map); + bpf_map_write_active_inc(map); if (!(map_get_sys_perms(map, f) & FMODE_CAN_READ) || !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) { err = -EPERM; @@ -1580,6 +1594,7 @@ free_value: free_key: kvfree(key); err_put: + bpf_map_write_active_dec(map); fdput(f); return err; } @@ -1607,8 +1622,7 @@ static int map_freeze(const union bpf_attr *attr) }
mutex_lock(&map->freeze_mutex); - - if (map->writecnt) { + if (bpf_map_write_active(map)) { err = -EBUSY; goto err_put; } @@ -4143,6 +4157,9 @@ static int bpf_map_do_batch(const union bpf_attr *attr, union bpf_attr __user *uattr, int cmd) { + bool has_read = cmd == BPF_MAP_LOOKUP_BATCH || + cmd == BPF_MAP_LOOKUP_AND_DELETE_BATCH; + bool has_write = cmd != BPF_MAP_LOOKUP_BATCH; struct bpf_map *map; int err, ufd; struct fd f; @@ -4155,16 +4172,13 @@ static int bpf_map_do_batch(const union bpf_attr *attr, map = __bpf_map_get(f); if (IS_ERR(map)) return PTR_ERR(map); - - if ((cmd == BPF_MAP_LOOKUP_BATCH || - cmd == BPF_MAP_LOOKUP_AND_DELETE_BATCH) && - !(map_get_sys_perms(map, f) & FMODE_CAN_READ)) { + if (has_write) + bpf_map_write_active_inc(map); + if (has_read && !(map_get_sys_perms(map, f) & FMODE_CAN_READ)) { err = -EPERM; goto err_put; } - - if (cmd != BPF_MAP_LOOKUP_BATCH && - !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) { + if (has_write && !(map_get_sys_perms(map, f) & FMODE_CAN_WRITE)) { err = -EPERM; goto err_put; } @@ -4177,8 +4191,9 @@ static int bpf_map_do_batch(const union bpf_attr *attr, BPF_DO_BATCH(map->ops->map_update_batch); else BPF_DO_BATCH(map->ops->map_delete_batch); - err_put: + if (has_write) + bpf_map_write_active_dec(map); fdput(f); return err; } diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index cba37d83451eb..2105b57c9c23a 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3885,7 +3885,22 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
static bool bpf_map_is_rdonly(const struct bpf_map *map) { - return (map->map_flags & BPF_F_RDONLY_PROG) && map->frozen; + /* A map is considered read-only if the following condition are true: + * + * 1) BPF program side cannot change any of the map content. The + * BPF_F_RDONLY_PROG flag is throughout the lifetime of a map + * and was set at map creation time. + * 2) The map value(s) have been initialized from user space by a + * loader and then "frozen", such that no new map update/delete + * operations from syscall side are possible for the rest of + * the map's lifetime from that point onwards. + * 3) Any parallel/pending map update/delete operations from syscall + * side have been completed. Only after that point, it's safe to + * assume that map value(s) are immutable. + */ + return (map->map_flags & BPF_F_RDONLY_PROG) && + READ_ONCE(map->frozen) && + !bpf_map_write_active(map); }
static int bpf_map_direct_read(struct bpf_map *map, int off, int size, u64 *val)
From: Colin Ian King colin.i.king@googlemail.com
[ Upstream commit 255e51da15baed47531beefd02f222e4dc01f1c1 ]
In the case where fw_getenv returns an error when fetching values for ememsizea and memsize then variable phys_memsize is not assigned a variable and will be uninitialized on a zero check of phys_memsize. Fix this by initializing phys_memsize to zero.
Cleans up cppcheck error: arch/mips/generic/yamon-dt.c:100:7: error: Uninitialized variable: phys_memsize [uninitvar]
Fixes: f41d2430bbd6 ("MIPS: generic/yamon-dt: Support > 256MB of RAM") Signed-off-by: Colin Ian King colin.i.king@gmail.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/generic/yamon-dt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/mips/generic/yamon-dt.c b/arch/mips/generic/yamon-dt.c index a3aa22c77cadc..a07a5edbcda78 100644 --- a/arch/mips/generic/yamon-dt.c +++ b/arch/mips/generic/yamon-dt.c @@ -75,7 +75,7 @@ static unsigned int __init gen_fdt_mem_array( __init int yamon_dt_append_memory(void *fdt, const struct yamon_mem_region *regions) { - unsigned long phys_memsize, memsize; + unsigned long phys_memsize = 0, memsize; __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; unsigned int mem_entries; int i, err, mem_off;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit e8f67482e5a4bc8d0b65d606d08cb60ee123b468 ]
BCM63XX selects HAVE_LEGACY_CLK but does not provide/support clk_get_parent(), so add a simple implementation of that function so that callers of it will build without errors.
Fixes these build errors:
mips-linux-ld: drivers/iio/adc/ingenic-adc.o: in function `jz4770_adc_init_clk_div': ingenic-adc.c:(.text+0xe4): undefined reference to `clk_get_parent' mips-linux-ld: drivers/iio/adc/ingenic-adc.o: in function `jz4725b_adc_init_clk_div': ingenic-adc.c:(.text+0x1b8): undefined reference to `clk_get_parent'
Fixes: e7300d04bd08 ("MIPS: BCM63xx: Add support for the Broadcom BCM63xx family of SOCs." ) Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Suggested-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Cc: Artur Rojek contact@artur-rojek.eu Cc: Paul Cercueil paul@crapouillou.net Cc: linux-mips@vger.kernel.org Cc: Jonathan Cameron jic23@kernel.org Cc: Lars-Peter Clausen lars@metafoo.de Cc: linux-iio@vger.kernel.org Cc: Florian Fainelli f.fainelli@gmail.com Cc: Andy Shevchenko andy.shevchenko@gmail.com Cc: Russell King linux@armlinux.org.uk Cc: bcm-kernel-feedback-list@broadcom.com Cc: Jonas Gorski jonas.gorski@gmail.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Acked-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Acked-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/bcm63xx/clk.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index 5a3e325275d0d..1c91064cb448b 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -381,6 +381,12 @@ void clk_disable(struct clk *clk)
EXPORT_SYMBOL(clk_disable);
+struct clk *clk_get_parent(struct clk *clk) +{ + return NULL; +} +EXPORT_SYMBOL(clk_get_parent); + unsigned long clk_get_rate(struct clk *clk) { if (!clk)
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit fc1aabb088860d6cf9dd03612b7a6f0de91ccac2 ]
Provide a simple implementation of clk_get_parent() in the lantiq subarch so that callers of it will build without errors.
Fixes this build error: ERROR: modpost: "clk_get_parent" [drivers/iio/adc/ingenic-adc.ko] undefined!
Fixes: 171bb2f19ed6 ("MIPS: Lantiq: Add initial support for Lantiq SoCs") Signed-off-by: Randy Dunlap rdunlap@infradead.org Suggested-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Cc: linux-mips@vger.kernel.org Cc: John Crispin john@phrozen.org Cc: Thomas Bogendoerfer tsbogend@alpha.franken.de Cc: Jonathan Cameron jic23@kernel.org Cc: linux-iio@vger.kernel.org Cc: Russell King linux@armlinux.org.uk Cc: Andy Shevchenko andy.shevchenko@gmail.com Acked-by: Jonathan Cameron Jonathan.Cameron@huawei.com Acked-by: John Crispin john@phrozen.org Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/lantiq/clk.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index dd819e31fcbbf..4916cccf378fd 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c @@ -158,6 +158,12 @@ void clk_deactivate(struct clk *clk) } EXPORT_SYMBOL(clk_deactivate);
+struct clk *clk_get_parent(struct clk *clk) +{ + return NULL; +} +EXPORT_SYMBOL(clk_get_parent); + static inline u32 get_counter_resolution(void) { u32 res;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit d6912b1251b47e6b04ea8c8881dfb35a6e7a3e29 ]
gpio-rockchip uses interfaces that are provided by the Kconfig symbol GENERIC_IRQ_CHIP, so the driver should select that symbol in order to prevent build errors.
Fixes these build errors (and more):
aarch64-linux-ld: drivers/gpio/gpio-rockchip.o: in function `rockchip_irq_disable': gpio-rockchip.c:(.text+0x454): undefined reference to `irq_gc_mask_set_bit' aarch64-linux-ld: drivers/gpio/gpio-rockchip.o: in function `rockchip_irq_enable': gpio-rockchip.c:(.text+0x478): undefined reference to `irq_gc_mask_clr_bit' aarch64-linux-ld: drivers/gpio/gpio-rockchip.o: in function `rockchip_interrupts_register': gpio-rockchip.c:(.text+0x518): undefined reference to `irq_generic_chip_ops' aarch64-linux-ld: gpio-rockchip.c:(.text+0x594): undefined reference to `__irq_alloc_domain_generic_chips' aarch64-linux-ld: gpio-rockchip.c:(.text+0x5cc): undefined reference to `irq_get_domain_generic_chip' aarch64-linux-ld: gpio-rockchip.c:(.text+0x5e0): undefined reference to `irq_gc_ack_set_bit' aarch64-linux-ld: gpio-rockchip.c:(.text+0x604): undefined reference to `irq_gc_set_wake'
Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Signed-off-by: Bartosz Golaszewski brgl@bgdev.pl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fae5141251e5d..947474f6abb45 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -523,6 +523,7 @@ config GPIO_REG config GPIO_ROCKCHIP tristate "Rockchip GPIO support" depends on ARCH_ROCKCHIP || COMPILE_TEST + select GENERIC_IRQ_CHIP select GPIOLIB_IRQCHIP default ARCH_ROCKCHIP help
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit c961a7d2aa23ae19e0099fbcdf1040fb760eea83 ]
If 'led_classdev_register()' fails, some additional resources should be released.
Add the missing 'i8042_remove_filter()' and 'lis3lv02d_remove_fs()' calls that are already in the remove function but are missing here.
Fixes: a4c724d0723b ("platform: hp_accel: add a i8042 filter to remove HPQ6000 data from kb bus stream") Fixes: 9e0c79782143 ("lis3lv02d: merge with leds hp disk") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/5a4f218f8f16d2e3a7906b7ca3654ffa946895f8.163631407... Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/hp_accel.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index cc53f725c0419..ef24f53753c6e 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -331,9 +331,11 @@ static int lis3lv02d_probe(struct platform_device *device) INIT_WORK(&hpled_led.work, delayed_set_status_worker); ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) { + i8042_remove_filter(hp_accel_i8042_filter); lis3lv02d_joystick_disable(&lis3_dev); lis3lv02d_poweroff(&lis3_dev); flush_work(&hpled_led.work); + lis3lv02d_remove_fs(&lis3_dev); return ret; }
From: Alex Williamson alex.williamson@redhat.com
[ Upstream commit 812fcc609502096e98cc3918a4b807722dba8fd9 ]
A Lenovo ThinkStation S20 (4157CTO BIOS 60KT41AUS) fails to boot on recent kernels including the think-lmi driver, due to the fact that errors returned by the tlmi_analyze() function are ignored by tlmi_probe(), where tlmi_sysfs_init() is called unconditionally. This results in making use of an array of already freed, non-null pointers and other uninitialized globals, causing all sorts of nasty kobject and memory faults.
Make use of the analyze function return value, free a couple leaked allocations, and remove the settings_count field, which is incremented but never consumed.
Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms") Signed-off-by: Alex Williamson alex.williamson@redhat.com Reviewed-by: Mark Gross markgross@kernel.org Reviewed-by: Mark Pearson markpearson@lenovo.com Link: https://lore.kernel.org/r/163639463588.1330483.15850167112490200219.stgit@om... 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/think-lmi.c | 13 ++++++++++--- drivers/platform/x86/think-lmi.h | 1 - 2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 9472aae72df29..c4d9c45350f7c 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -888,8 +888,10 @@ static int tlmi_analyze(void) break; if (!item) break; - if (!*item) + if (!*item) { + kfree(item); continue; + }
/* It is not allowed to have '/' for file name. Convert it into ''. */ strreplace(item, '/', '\'); @@ -902,6 +904,7 @@ static int tlmi_analyze(void) setting = kzalloc(sizeof(*setting), GFP_KERNEL); if (!setting) { ret = -ENOMEM; + kfree(item); goto fail_clear_attr; } setting->index = i; @@ -916,7 +919,6 @@ static int tlmi_analyze(void) } kobject_init(&setting->kobj, &tlmi_attr_setting_ktype); tlmi_priv.setting[i] = setting; - tlmi_priv.settings_count++; kfree(item); }
@@ -983,7 +985,12 @@ static void tlmi_remove(struct wmi_device *wdev)
static int tlmi_probe(struct wmi_device *wdev, const void *context) { - tlmi_analyze(); + int ret; + + ret = tlmi_analyze(); + if (ret) + return ret; + return tlmi_sysfs_init(); }
diff --git a/drivers/platform/x86/think-lmi.h b/drivers/platform/x86/think-lmi.h index f8e26823075fd..2ce5086a5af27 100644 --- a/drivers/platform/x86/think-lmi.h +++ b/drivers/platform/x86/think-lmi.h @@ -55,7 +55,6 @@ struct tlmi_attr_setting { struct think_lmi { struct wmi_device *wmi_device;
- int settings_count; bool can_set_bios_settings; bool can_get_bios_selections; bool can_set_bios_password;
From: Cong Wang cong.wang@bytedance.com
[ Upstream commit 099f896f498a2b26d84f4ddae039b2c542c18b48 ]
It turns out the skb's in sock receive queue could have bad checksums, as both ->poll() and ->recvmsg() validate checksums. We have to do the same for ->read_sock() path too before they are redirected in sockmap.
Fixes: d7f571188ecf ("udp: Implement ->read_sock() for sockmap") Reported-by: Daniel Borkmann daniel@iogearbox.net Signed-off-by: Cong Wang cong.wang@bytedance.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/bpf/20211115044006.26068-1-xiyou.wangcong@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/udp.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2fffcf2b54f3f..2ce3fca545d37 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1808,6 +1808,17 @@ int udp_read_sock(struct sock *sk, read_descriptor_t *desc, skb = skb_recv_udp(sk, 0, 1, &err); if (!skb) return err; + + if (udp_lib_checksum_complete(skb)) { + __UDP_INC_STATS(sock_net(sk), UDP_MIB_CSUMERRORS, + IS_UDPLITE(sk)); + __UDP_INC_STATS(sock_net(sk), UDP_MIB_INERRORS, + IS_UDPLITE(sk)); + atomic_inc(&sk->sk_drops); + kfree_skb(skb); + continue; + } + used = recv_actor(desc, skb, 0, skb->len); if (used <= 0) { if (!copied)
From: Colin Ian King colin.i.king@googlemail.com
[ Upstream commit d08e38b62327961295be1c63b562cd46ec97cd07 ]
The bitfields have_csum and io_error are currently signed which is not recommended as the representation is an implementation defined behaviour. Fix this by making the bit-fields unsigned ints.
Fixes: 2c36395430b0 ("btrfs: scrub: remove the anonymous structure from scrub_page") Reviewed-by: Josef Bacik josef@toxicpanda.com Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Colin Ian King colin.i.king@gmail.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/scrub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 088641ba7a8e6..62f4bafbe54bb 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -73,8 +73,8 @@ struct scrub_page { u64 physical_for_dev_replace; atomic_t refs; u8 mirror_num; - int have_csum:1; - int io_error:1; + unsigned int have_csum:1; + unsigned int io_error:1; u8 csum[BTRFS_CSUM_SIZE];
struct scrub_recover *recover;
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit 6cd7397d01c4a3e09757840299e4f114f0aa5fa0 ]
Preset both receive and send CQ pointers prior to call to the drivers and overwrite it later again till the mlx4 is going to be changed do not overwrite ibqp properties.
This change is needed for mlx5, because in case of QP creation failure, it will go to the path of QP destroy which relies on proper CQ pointers.
BUG: KASAN: use-after-free in create_qp.cold+0x164/0x16e [mlx5_ib] Write of size 8 at addr ffff8880064c55c0 by task a.out/246
CPU: 0 PID: 246 Comm: a.out Not tainted 5.15.0+ #291 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 Call Trace: dump_stack_lvl+0x45/0x59 print_address_description.constprop.0+0x1f/0x140 kasan_report.cold+0x83/0xdf create_qp.cold+0x164/0x16e [mlx5_ib] mlx5_ib_create_qp+0x358/0x28a0 [mlx5_ib] create_qp.part.0+0x45b/0x6a0 [ib_core] ib_create_qp_user+0x97/0x150 [ib_core] ib_uverbs_handler_UVERBS_METHOD_QP_CREATE+0x92c/0x1250 [ib_uverbs] ib_uverbs_cmd_verbs+0x1c38/0x3150 [ib_uverbs] ib_uverbs_ioctl+0x169/0x260 [ib_uverbs] __x64_sys_ioctl+0x866/0x14d0 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
Allocated by task 246: kasan_save_stack+0x1b/0x40 __kasan_kmalloc+0xa4/0xd0 create_qp.part.0+0x92/0x6a0 [ib_core] ib_create_qp_user+0x97/0x150 [ib_core] ib_uverbs_handler_UVERBS_METHOD_QP_CREATE+0x92c/0x1250 [ib_uverbs] ib_uverbs_cmd_verbs+0x1c38/0x3150 [ib_uverbs] ib_uverbs_ioctl+0x169/0x260 [ib_uverbs] __x64_sys_ioctl+0x866/0x14d0 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
Freed by task 246: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 __kasan_slab_free+0x10c/0x150 slab_free_freelist_hook+0xb4/0x1b0 kfree+0xe7/0x2a0 create_qp.part.0+0x52b/0x6a0 [ib_core] ib_create_qp_user+0x97/0x150 [ib_core] ib_uverbs_handler_UVERBS_METHOD_QP_CREATE+0x92c/0x1250 [ib_uverbs] ib_uverbs_cmd_verbs+0x1c38/0x3150 [ib_uverbs] ib_uverbs_ioctl+0x169/0x260 [ib_uverbs] __x64_sys_ioctl+0x866/0x14d0 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
Fixes: 514aee660df4 ("RDMA: Globally allocate and release QP memory") Link: https://lore.kernel.org/r/2dbb2e2cbb1efb188a500e5634be1d71956424ce.163663103... Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/verbs.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 89a2b21976d63..20a46d8731455 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1232,6 +1232,9 @@ static struct ib_qp *create_qp(struct ib_device *dev, struct ib_pd *pd, INIT_LIST_HEAD(&qp->rdma_mrs); INIT_LIST_HEAD(&qp->sig_mrs);
+ qp->send_cq = attr->send_cq; + qp->recv_cq = attr->recv_cq; + rdma_restrack_new(&qp->res, RDMA_RESTRACK_QP); WARN_ONCE(!udata && !caller, "Missing kernel QP owner"); rdma_restrack_set_name(&qp->res, udata ? NULL : caller);
From: Tariq Toukan tariqt@nvidia.com
[ Upstream commit cc4a9cc03faa6d8db1a6954bb536f2c1e63bdff6 ]
For the TLS RX resync flow, we maintain a list of TLS contexts that require some attention, to communicate their resync information to the HW. Here we fix list corruptions, by protecting the entries against movements coming from resync_handle_seq_match(), until their resync handling in napi is fully completed.
Fixes: e9ce991bce5b ("net/mlx5e: kTLS, Add resiliency to RX resync failures") Signed-off-by: Tariq Toukan tariqt@nvidia.com Reviewed-by: Maxim Mikityanskiy maximmi@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../mellanox/mlx5/core/en_accel/ktls_rx.c | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c index 62abce008c7b8..a2a9f68579dd8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c @@ -55,6 +55,7 @@ struct mlx5e_ktls_offload_context_rx { DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS);
/* resync */ + spinlock_t lock; /* protects resync fields */ struct mlx5e_ktls_rx_resync_ctx resync; struct list_head list; }; @@ -386,14 +387,18 @@ static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_r struct mlx5e_icosq *sq; bool trigger_poll;
- memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq)); - sq = &c->async_icosq; ktls_resync = sq->ktls_resync; + trigger_poll = false;
spin_lock_bh(&ktls_resync->lock); - list_add_tail(&priv_rx->list, &ktls_resync->list); - trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state); + spin_lock_bh(&priv_rx->lock); + memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq)); + if (list_empty(&priv_rx->list)) { + list_add_tail(&priv_rx->list, &ktls_resync->list); + trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state); + } + spin_unlock_bh(&priv_rx->lock); spin_unlock_bh(&ktls_resync->lock);
if (!trigger_poll) @@ -617,6 +622,8 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, if (err) goto err_create_key;
+ INIT_LIST_HEAD(&priv_rx->list); + spin_lock_init(&priv_rx->lock); priv_rx->crypto_info = *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
@@ -730,10 +737,14 @@ bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget) priv_rx = list_first_entry(&local_list, struct mlx5e_ktls_offload_context_rx, list); + spin_lock(&priv_rx->lock); cseg = post_static_params(sq, priv_rx); - if (IS_ERR(cseg)) + if (IS_ERR(cseg)) { + spin_unlock(&priv_rx->lock); break; - list_del(&priv_rx->list); + } + list_del_init(&priv_rx->list); + spin_unlock(&priv_rx->lock); db_cseg = cseg; } if (db_cseg)
From: Vlad Buslov vladbu@nvidia.com
[ Upstream commit 362980eada85b5ea691e5e0d9257a991aa7ade47 ]
Function mlx5e_take_tmp_flow() skips flows with zero reference count. This can cause syndrome 0x179e84 when the called from neigh or route update code and the skipped flow is not removed from the hardware by the time underlying encap/decap resource is deleted. Add new completion 'del_hw_done' that is completed when flow is unoffloaded. This is safe to do because flow with reference count zero needs to be detached from encap/decap entry before its memory is deallocated, which requires taking the encap_tbl_lock mutex that is held by the event handlers code.
Fixes: 8914add2c9e5 ("net/mlx5e: Handle FIB events to update tunnel endpoint device") Signed-off-by: Vlad Buslov vladbu@nvidia.com Reviewed-by: Roi Dayan roid@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h | 1 + drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 8 +++++++- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h index d1599b7b944bf..c340bf90354a0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h @@ -102,6 +102,7 @@ struct mlx5e_tc_flow { refcount_t refcnt; struct rcu_head rcu_head; struct completion init_done; + struct completion del_hw_done; int tunnel_id; /* the mapped tunnel id of this flow */ struct mlx5_flow_attr *attr; }; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c index 1c44c6c345f5d..ec0163d75dd25 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c @@ -221,8 +221,14 @@ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow, struct list_head *flow_list, int index) { - if (IS_ERR(mlx5e_flow_get(flow))) + if (IS_ERR(mlx5e_flow_get(flow))) { + /* Flow is being deleted concurrently. Wait for it to be + * unoffloaded from hardware, otherwise deleting encap will + * fail. + */ + wait_for_completion(&flow->del_hw_done); return; + } wait_for_completion(&flow->init_done);
flow->tmp_entry_index = index; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 129ff7e0d65cc..d2e7b099b83ab 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -1544,6 +1544,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, else mlx5e_tc_unoffload_fdb_rules(esw, flow, attr); } + complete_all(&flow->del_hw_done);
if (mlx5_flow_has_geneve_opt(flow)) mlx5_geneve_tlv_option_del(priv->mdev->geneve); @@ -4222,6 +4223,7 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size, INIT_LIST_HEAD(&flow->l3_to_l2_reformat); refcount_set(&flow->refcnt, 1); init_completion(&flow->init_done); + init_completion(&flow->del_hw_done);
*__flow = flow; *__parse_attr = parse_attr;
From: Paul Blakey paulb@nvidia.com
[ Upstream commit d7751d6476185ff754b9dad2cba0c0a6e43ecadc ]
E-Switch encap mode is relevant only when in switchdev mode. The RDMA driver can query the encap configuration via mlx5_eswitch_get_encap_mode(). Make sure it returns the currently used mode and not the set one.
This reverts the cited commit which reset the encap mode on entering switchdev and fixes the original issue properly.
Fixes: 9a64144d683a ("net/mlx5: E-Switch, Fix default encap mode") Signed-off-by: Paul Blakey paulb@nvidia.com Reviewed-by: Mark Bloch mbloch@nvidia.com Reviewed-by: Maor Dickman maord@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 9 +++++++-- .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 7 ------- include/linux/mlx5/eswitch.h | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index ec136b4992045..5872cc8bf9532 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1572,6 +1572,11 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) esw->enabled_vports = 0; esw->mode = MLX5_ESWITCH_NONE; esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE; + if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) && + MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)) + esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC; + else + esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
dev->priv.eswitch = esw; BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head); @@ -1934,7 +1939,7 @@ free_out: return err; }
-u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev) +u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev) { struct mlx5_eswitch *esw = dev->priv.eswitch;
@@ -1948,7 +1953,7 @@ mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev) struct mlx5_eswitch *esw;
esw = dev->priv.eswitch; - return mlx5_esw_allowed(esw) ? esw->offloads.encap : + return (mlx5_eswitch_mode(dev) == MLX5_ESWITCH_OFFLOADS) ? esw->offloads.encap : DEVLINK_ESWITCH_ENCAP_MODE_NONE; } EXPORT_SYMBOL(mlx5_eswitch_get_encap_mode); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 0d461e38add37..08534d562d5a9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -3141,12 +3141,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) u64 mapping_id; int err;
- if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, reformat) && - MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, decap)) - esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC; - else - esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; - mutex_init(&esw->offloads.termtbl_mutex); mlx5_rdma_enable_roce(esw->dev);
@@ -3244,7 +3238,6 @@ void esw_offloads_disable(struct mlx5_eswitch *esw) esw_offloads_metadata_uninit(esw); mlx5_rdma_disable_roce(esw->dev); mutex_destroy(&esw->offloads.termtbl_mutex); - esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE; }
static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) diff --git a/include/linux/mlx5/eswitch.h b/include/linux/mlx5/eswitch.h index 4ab5c1fc1270d..a09ed4c8361b6 100644 --- a/include/linux/mlx5/eswitch.h +++ b/include/linux/mlx5/eswitch.h @@ -136,13 +136,13 @@ u32 mlx5_eswitch_get_vport_metadata_for_set(struct mlx5_eswitch *esw, ESW_TUN_OPTS_SLOW_TABLE_GOTO_VPORT) #define ESW_TUN_SLOW_TABLE_GOTO_VPORT_MARK ESW_TUN_OPTS_MASK
-u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev); +u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev); u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev); struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw);
#else /* CONFIG_MLX5_ESWITCH */
-static inline u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev) +static inline u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev) { return MLX5_ESWITCH_NONE; }
From: Valentine Fatiev valentinef@nvidia.com
[ Upstream commit 76ded29d3fcda4928da8849ffc446ea46871c1c2 ]
Prior to this patch in case mlx5_core_destroy_cq() failed it proceeds to rest of destroy operations. mlx5_core_destroy_cq() could be called again by user and cause additional call of mlx5_debug_cq_remove(). cq->dbg was not nullify in previous call and cause the crash.
Fix it by nullify cq->dbg pointer after removal.
Also proceed to destroy operations only if FW return 0 for MLX5_CMD_OP_DESTROY_CQ command.
general protection fault, probably for non-canonical address 0x2000300004058: 0000 [#1] SMP PTI CPU: 5 PID: 1228 Comm: python Not tainted 5.15.0-rc5_for_upstream_min_debug_2021_10_14_11_06 #1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:lockref_get+0x1/0x60 Code: 5d e9 53 ff ff ff 48 8d 7f 70 e8 0a 2e 48 00 c7 85 d0 00 00 00 02 00 00 00 c6 45 70 00 fb 5d c3 c3 cc cc cc cc cc cc cc cc 53 <48> 8b 17 48 89 fb 85 d2 75 3d 48 89 d0 bf 64 00 00 00 48 89 c1 48 RSP: 0018:ffff888137dd7a38 EFLAGS: 00010206 RAX: 0000000000000000 RBX: ffff888107d5f458 RCX: 00000000fffffffe RDX: 000000000002c2b0 RSI: ffffffff8155e2e0 RDI: 0002000300004058 RBP: ffff888137dd7a88 R08: 0002000300004058 R09: ffff8881144a9f88 R10: 0000000000000000 R11: 0000000000000000 R12: ffff8881141d4000 R13: ffff888137dd7c68 R14: ffff888137dd7d58 R15: ffff888137dd7cc0 FS: 00007f4644f2a4c0(0000) GS:ffff8887a2d40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055b4500f4380 CR3: 0000000114f7a003 CR4: 0000000000170ea0 Call Trace: simple_recursive_removal+0x33/0x2e0 ? debugfs_remove+0x60/0x60 debugfs_remove+0x40/0x60 mlx5_debug_cq_remove+0x32/0x70 [mlx5_core] mlx5_core_destroy_cq+0x41/0x1d0 [mlx5_core] devx_obj_cleanup+0x151/0x330 [mlx5_ib] ? __pollwait+0xd0/0xd0 ? xas_load+0x5/0x70 ? xa_load+0x62/0xa0 destroy_hw_idr_uobject+0x20/0x80 [ib_uverbs] uverbs_destroy_uobject+0x3b/0x360 [ib_uverbs] uobj_destroy+0x54/0xa0 [ib_uverbs] ib_uverbs_cmd_verbs+0xaf2/0x1160 [ib_uverbs] ? uverbs_finalize_object+0xd0/0xd0 [ib_uverbs] ib_uverbs_ioctl+0xc4/0x1b0 [ib_uverbs] __x64_sys_ioctl+0x3e4/0x8e0
Fixes: 94b960b9deff ("net/mlx5e: Fix memory leak in mlx5_core_destroy_cq() error path") Signed-off-by: Valentine Fatiev valentinef@nvidia.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/cq.c | 5 +++-- drivers/net/ethernet/mellanox/mlx5/core/debugfs.c | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c index 02e77ffe5c3e4..5371ad0a12eb5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c @@ -164,13 +164,14 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) MLX5_SET(destroy_cq_in, in, cqn, cq->cqn); MLX5_SET(destroy_cq_in, in, uid, cq->uid); err = mlx5_cmd_exec_in(dev, destroy_cq, in); + if (err) + return err;
synchronize_irq(cq->irqn); - mlx5_cq_put(cq); wait_for_completion(&cq->free);
- return err; + return 0; } EXPORT_SYMBOL(mlx5_core_destroy_cq);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c index 07c8d9811bc81..10d195042ab55 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c @@ -507,6 +507,8 @@ void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) if (!mlx5_debugfs_root) return;
- if (cq->dbg) + if (cq->dbg) { rem_res_tree(cq->dbg); + cq->dbg = NULL; + } }
From: Neta Ostrovsky netao@nvidia.com
[ Upstream commit ba50cd9451f6c49cf0841c0a4a146ff6a2822699 ]
In the fast unload flow, the device state is set to internal error, which indicates that the driver started the destroy process. In this case, when a destroy command is being executed, it should return MLX5_CMD_STAT_OK. Fix MLX5_CMD_OP_DESTROY_UCTX and MLX5_CMD_OP_DESTROY_UMEM to return OK instead of EIO.
This fixes a call trace in the umem release process - [ 2633.536695] Call Trace: [ 2633.537518] ib_uverbs_remove_one+0xc3/0x140 [ib_uverbs] [ 2633.538596] remove_client_context+0x8b/0xd0 [ib_core] [ 2633.539641] disable_device+0x8c/0x130 [ib_core] [ 2633.540615] __ib_unregister_device+0x35/0xa0 [ib_core] [ 2633.541640] ib_unregister_device+0x21/0x30 [ib_core] [ 2633.542663] __mlx5_ib_remove+0x38/0x90 [mlx5_ib] [ 2633.543640] auxiliary_bus_remove+0x1e/0x30 [auxiliary] [ 2633.544661] device_release_driver_internal+0x103/0x1f0 [ 2633.545679] bus_remove_device+0xf7/0x170 [ 2633.546640] device_del+0x181/0x410 [ 2633.547606] mlx5_rescan_drivers_locked.part.10+0x63/0x160 [mlx5_core] [ 2633.548777] mlx5_unregister_device+0x27/0x40 [mlx5_core] [ 2633.549841] mlx5_uninit_one+0x21/0xc0 [mlx5_core] [ 2633.550864] remove_one+0x69/0xe0 [mlx5_core] [ 2633.551819] pci_device_remove+0x3b/0xc0 [ 2633.552731] device_release_driver_internal+0x103/0x1f0 [ 2633.553746] unbind_store+0xf6/0x130 [ 2633.554657] kernfs_fop_write+0x116/0x190 [ 2633.555567] vfs_write+0xa5/0x1a0 [ 2633.556407] ksys_write+0x4f/0xb0 [ 2633.557233] do_syscall_64+0x5b/0x1a0 [ 2633.558071] entry_SYSCALL_64_after_hwframe+0x65/0xca [ 2633.559018] RIP: 0033:0x7f9977132648 [ 2633.559821] Code: 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 55 6f 2d 00 8b 00 85 c0 75 17 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 41 54 49 89 d4 55 [ 2633.562332] RSP: 002b:00007fffb1a83888 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 2633.563472] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007f9977132648 [ 2633.564541] RDX: 000000000000000c RSI: 000055b90546e230 RDI: 0000000000000001 [ 2633.565596] RBP: 000055b90546e230 R08: 00007f9977406860 R09: 00007f9977a54740 [ 2633.566653] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f99774056e0 [ 2633.567692] R13: 000000000000000c R14: 00007f9977400880 R15: 000000000000000c [ 2633.568725] ---[ end trace 10b4fe52945e544d ]---
Fixes: 6a6fabbfa3e8 ("net/mlx5: Update pci error handler entries and command translation") Signed-off-by: Neta Ostrovsky netao@nvidia.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index db5dfff585c99..c698e4b5381d7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -334,6 +334,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, case MLX5_CMD_OP_PAGE_FAULT_RESUME: case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS: case MLX5_CMD_OP_DEALLOC_SF: + case MLX5_CMD_OP_DESTROY_UCTX: + case MLX5_CMD_OP_DESTROY_UMEM: return MLX5_CMD_STAT_OK;
case MLX5_CMD_OP_QUERY_HCA_CAP: @@ -459,9 +461,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: case MLX5_CMD_OP_CREATE_UCTX: - case MLX5_CMD_OP_DESTROY_UCTX: case MLX5_CMD_OP_CREATE_UMEM: - case MLX5_CMD_OP_DESTROY_UMEM: case MLX5_CMD_OP_ALLOC_MEMIC: case MLX5_CMD_OP_MODIFY_XRQ: case MLX5_CMD_OP_RELEASE_XRQ_ERROR:
From: Mark Bloch mbloch@nvidia.com
[ Upstream commit 2eb0cb31bc4ce2ede5460cf3ef433b40cf5f040d ]
A user can enable VFs without changing E-Switch mode, this can happen when a user moves straight to switchdev mode and only once in switchdev VFs are enabled via the sysfs interface.
The cited commit assumed this isn't possible and exposed a single API function where the E-switch calls into the lag code, breaks the lag and prevents any other lag operations to take place until the E-switch update has ended.
Breaking the hardware lag when it isn't needed can make it such that hardware lag can't be enabled again.
In the sysfs call path check if the current E-Switch mode is NONE, in the context of the function it can only mean the E-Switch is moving out of NONE mode and the hardware lag should be disabled and enabled once the mode change has ended. If the mode isn't NONE it means VFs are about to be enabled and such operation doesn't require toggling the hardware lag.
Fixes: cac1eb2cf2e3 ("net/mlx5: Lag, properly lock eswitch if needed") Signed-off-by: Mark Bloch mbloch@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 5872cc8bf9532..51a8cecc4a7ce 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1305,12 +1305,17 @@ abort: */ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { + bool toggle_lag; int ret;
if (!mlx5_esw_allowed(esw)) return 0;
- mlx5_lag_disable_change(esw->dev); + toggle_lag = esw->mode == MLX5_ESWITCH_NONE; + + if (toggle_lag) + mlx5_lag_disable_change(esw->dev); + down_write(&esw->mode_lock); if (esw->mode == MLX5_ESWITCH_NONE) { ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs); @@ -1324,7 +1329,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) esw->esw_funcs.num_vfs = num_vfs; } up_write(&esw->mode_lock); - mlx5_lag_enable_change(esw->dev); + + if (toggle_lag) + mlx5_lag_enable_change(esw->dev); + return ret; }
From: Roi Dayan roid@nvidia.com
[ Upstream commit 806401c20a0f9c51b6c8fd7035671e6ca841f6c2 ]
CT clear action offload adds additional mod hdr actions to the flow's original mod actions in order to clear the registers which hold ct_state. When such flow also includes encap action, a neigh update event can cause the driver to unoffload the flow and then reoffload it.
Each time this happens, the ct clear handling adds that same set of mod hdr actions to reset ct_state until the max of mod hdr actions is reached.
Also the driver never releases the allocated mod hdr actions and causing a memleak.
Fix above two issues by moving CT clear mod acts allocation into the parsing actions phase and only use it when offloading the rule. The release of mod acts will be done in the normal flow_put().
backtrace: [<000000007316e2f3>] krealloc+0x83/0xd0 [<00000000ef157de1>] mlx5e_mod_hdr_alloc+0x147/0x300 [mlx5_core] [<00000000970ce4ae>] mlx5e_tc_match_to_reg_set_and_get_id+0xd7/0x240 [mlx5_core] [<0000000067c5fa17>] mlx5e_tc_match_to_reg_set+0xa/0x20 [mlx5_core] [<00000000d032eb98>] mlx5_tc_ct_entry_set_registers.isra.0+0x36/0xc0 [mlx5_core] [<00000000fd23b869>] mlx5_tc_ct_flow_offload+0x272/0x1f10 [mlx5_core] [<000000004fc24acc>] mlx5e_tc_offload_fdb_rules.part.0+0x150/0x620 [mlx5_core] [<00000000dc741c17>] mlx5e_tc_encap_flows_add+0x489/0x690 [mlx5_core] [<00000000e92e49d7>] mlx5e_rep_update_flows+0x6e4/0x9b0 [mlx5_core] [<00000000f60f5602>] mlx5e_rep_neigh_update+0x39a/0x5d0 [mlx5_core]
Fixes: 1ef3018f5af3 ("net/mlx5e: CT: Support clear action") Signed-off-by: Roi Dayan roid@nvidia.com Reviewed-by: Paul Blakey paulb@nvidia.com Reviewed-by: Maor Dickman maord@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/mellanox/mlx5/core/en/tc_ct.c | 26 ++++++++++++------- .../ethernet/mellanox/mlx5/core/en/tc_ct.h | 2 ++ .../net/ethernet/mellanox/mlx5/core/en_tc.c | 8 ++++-- 3 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c index 6c949abcd2e14..bc65151321ec2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c @@ -1356,9 +1356,13 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv, int mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *attr, + struct mlx5e_tc_mod_hdr_acts *mod_acts, const struct flow_action_entry *act, struct netlink_ext_ack *extack) { + bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR; + int err; + if (!priv) { NL_SET_ERR_MSG_MOD(extack, "offload of ct action isn't available"); @@ -1369,6 +1373,17 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, attr->ct_attr.ct_action = act->ct.action; attr->ct_attr.nf_ft = act->ct.flow_table;
+ if (!clear_action) + goto out; + + err = mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0); + if (err) { + NL_SET_ERR_MSG_MOD(extack, "Failed to set registers for ct clear"); + return err; + } + attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; + +out: return 0; }
@@ -1898,23 +1913,16 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv,
memcpy(pre_ct_attr, attr, attr_sz);
- err = mlx5_tc_ct_entry_set_registers(ct_priv, mod_acts, 0, 0, 0, 0); - if (err) { - ct_dbg("Failed to set register for ct clear"); - goto err_set_registers; - } - mod_hdr = mlx5_modify_header_alloc(priv->mdev, ct_priv->ns_type, mod_acts->num_actions, mod_acts->actions); if (IS_ERR(mod_hdr)) { err = PTR_ERR(mod_hdr); ct_dbg("Failed to add create ct clear mod hdr"); - goto err_set_registers; + goto err_mod_hdr; }
pre_ct_attr->modify_hdr = mod_hdr; - pre_ct_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
rule = mlx5_tc_rule_insert(priv, orig_spec, pre_ct_attr); if (IS_ERR(rule)) { @@ -1930,7 +1938,7 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv,
err_insert: mlx5_modify_header_dealloc(priv->mdev, mod_hdr); -err_set_registers: +err_mod_hdr: netdev_warn(priv->netdev, "Failed to offload ct clear flow, err %d\n", err); kfree(pre_ct_attr); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h index 363329f4aac61..99662af1e41a7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.h @@ -110,6 +110,7 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec); int mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *attr, + struct mlx5e_tc_mod_hdr_acts *mod_acts, const struct flow_action_entry *act, struct netlink_ext_ack *extack);
@@ -172,6 +173,7 @@ mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) static inline int mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, struct mlx5_flow_attr *attr, + struct mlx5e_tc_mod_hdr_acts *mod_acts, const struct flow_action_entry *act, struct netlink_ext_ack *extack) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index d2e7b099b83ab..e3b320b6d85b9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -3458,7 +3458,9 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, attr->dest_chain = act->chain_index; break; case FLOW_ACTION_CT: - err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack); + err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, + &parse_attr->mod_hdr_acts, + act, extack); if (err) return err;
@@ -4009,7 +4011,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, NL_SET_ERR_MSG_MOD(extack, "Sample action with connection tracking is not supported"); return -EOPNOTSUPP; } - err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack); + err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, + &parse_attr->mod_hdr_acts, + act, extack); if (err) return err;
From: Maher Sanalla msanalla@nvidia.com
[ Upstream commit ae396d85c01c7bdc9eeceecde1f493d03f793465 ]
Currently, In NETDEV_CHANGELOWERSTATE/NETDEV_CHANGEUPPERSTATE events handling, tracking is not fully completed if the LAG device is not ready at the time the events occur. But, we must keep track of the upper and lower states after receiving the events because RoCE needs this info in mlx5_lag_get_roce_netdev() - in order to return the corresponding port that its running on. Returning the wrong (not most recent) port will lead to gids table being incorrect.
For example: If during the attachment of a slave to the bond, the other non-attached port performs pci_reload, then the LAG device is not ready, but that should not result in dismissing attached slave tracker update automatically (which is performed in mlx5_handle_changelowerstate()), Since these events might not come later, which can lead to both bond ports having tx_enabled=0 - which is not a valid state of LAG bond.
Fixes: 9b412cc35f00 ("net/mlx5e: Add LAG warning if bond slave is not lag master") Signed-off-by: Maher Sanalla msanalla@nvidia.com Reviewed-by: Mark Bloch mbloch@nvidia.com Reviewed-by: Jianbo Liu jianbol@nvidia.com Reviewed-by: Roi Dayan roid@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lag.c | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c index d2105c1635c34..c19d9327095b2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c @@ -565,6 +565,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, bool is_bonded, is_in_lag, mode_supported; int bond_status = 0; int num_slaves = 0; + int changed = 0; int idx;
if (!netif_is_lag_master(upper)) @@ -601,27 +602,27 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, */ is_in_lag = num_slaves == MLX5_MAX_PORTS && bond_status == 0x3;
- if (!mlx5_lag_is_ready(ldev) && is_in_lag) { - NL_SET_ERR_MSG_MOD(info->info.extack, - "Can't activate LAG offload, PF is configured with more than 64 VFs"); - return 0; - } - /* Lag mode must be activebackup or hash. */ mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP || tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH;
- if (is_in_lag && !mode_supported) - NL_SET_ERR_MSG_MOD(info->info.extack, - "Can't activate LAG offload, TX type isn't supported"); - is_bonded = is_in_lag && mode_supported; if (tracker->is_bonded != is_bonded) { tracker->is_bonded = is_bonded; - return 1; + changed = 1; }
- return 0; + if (!is_in_lag) + return changed; + + if (!mlx5_lag_is_ready(ldev)) + NL_SET_ERR_MSG_MOD(info->info.extack, + "Can't activate LAG offload, PF is configured with more than 64 VFs"); + else if (!mode_supported) + NL_SET_ERR_MSG_MOD(info->info.extack, + "Can't activate LAG offload, TX type isn't supported"); + + return changed; }
static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev, @@ -664,9 +665,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
ldev = container_of(this, struct mlx5_lag, nb);
- if (!mlx5_lag_is_ready(ldev) && event == NETDEV_CHANGELOWERSTATE) - return NOTIFY_DONE; - tracker = ldev->tracker;
switch (event) {
From: Raed Salem raeds@nvidia.com
[ Upstream commit c4c3176739dfa6efcc5b1d1de4b3fd2b51b048c7 ]
On regular ConnectX HCAs getting encap mode isn't supported when the E-Switch is in NONE mode. Current code would return no error code when trying to get encap mode in such case which is wrong.
Fix by returning error value to indicate failure to caller in such case.
Fixes: 8e0aa4bc959c ("net/mlx5: E-switch, Protect eswitch mode changes") Signed-off-by: Raed Salem raeds@nvidia.com Reviewed-by: Mark Bloch mbloch@nvidia.com Reviewed-by: Maor Dickman maord@nvidia.com Signed-off-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 08534d562d5a9..0c79e11339362 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -3581,7 +3581,7 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, *encap = esw->offloads.encap; unlock: up_write(&esw->mode_lock); - return 0; + return err; }
static bool
From: Bart Van Assche bvanassche@acm.org
[ Upstream commit 3ff1f6b6ba6f97f50862aa50e79959cc8ddc2566 ]
The following has been observed on a test setup:
WARNING: CPU: 4 PID: 250 at drivers/scsi/ufs/ufshcd.c:2737 ufshcd_queuecommand+0x468/0x65c Call trace: ufshcd_queuecommand+0x468/0x65c scsi_send_eh_cmnd+0x224/0x6a0 scsi_eh_test_devices+0x248/0x418 scsi_eh_ready_devs+0xc34/0xe58 scsi_error_handler+0x204/0x80c kthread+0x150/0x1b4 ret_from_fork+0x10/0x30
That warning is triggered by the following statement:
WARN_ON(lrbp->cmd);
Fix this warning by clearing lrbp->cmd from the abort handler.
Link: https://lore.kernel.org/r/20211104181059.4129537-1-bvanassche@acm.org Fixes: 7a3e97b0dc4b ("[SCSI] ufshcd: UFS Host controller driver") Reviewed-by: Bean Huo beanhuo@micron.com Reviewed-by: Stanley Chu stanley.chu@mediatek.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/ufshcd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 20705cec83c55..325a15186e950 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7040,6 +7040,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) goto release; }
+ lrbp->cmd = NULL; err = SUCCESS;
release:
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 4edd8cd4e86dd3047e5294bbefcc0a08f66a430f ]
This fixes a regression added with:
commit f0f82e2476f6 ("scsi: core: Fix capacity set to zero after offlinining device")
The problem is that after iSCSI recovery, iscsid will call into the kernel to set the dev's state to running, and with that patch we now call scsi_rescan_device() with the state_mutex held. If the SCSI error handler thread is just starting to test the device in scsi_send_eh_cmnd() then it's going to try to grab the state_mutex.
We are then stuck, because when scsi_rescan_device() tries to send its I/O scsi_queue_rq() calls -> scsi_host_queue_ready() -> scsi_host_in_recovery() which will return true (the host state is still in recovery) and I/O will just be requeued. scsi_send_eh_cmnd() will then never be able to grab the state_mutex to finish error handling.
To prevent the deadlock move the rescan-related code to after we drop the state_mutex.
This also adds a check for if we are already in the running state. This prevents extra scans and helps the iscsid case where if the transport class has already onlined the device during its recovery process then we don't need userspace to do it again plus possibly block that daemon.
Link: https://lore.kernel.org/r/20211105221048.6541-3-michael.christie@oracle.com Fixes: f0f82e2476f6 ("scsi: core: Fix capacity set to zero after offlinining device") Cc: Bart Van Assche bvanassche@acm.org Cc: lijinlin lijinlin3@huawei.com Cc: Wu Bo wubo40@huawei.com Reviewed-by: Lee Duncan lduncan@suse.com Reviewed-by: Wu Bo wubo40@huawei.com Signed-off-by: Mike Christie michael.christie@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_sysfs.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 8bb79ccc9a8b5..9527e734a999a 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -797,6 +797,7 @@ store_state_field(struct device *dev, struct device_attribute *attr, int i, ret; struct scsi_device *sdev = to_scsi_device(dev); enum scsi_device_state state = 0; + bool rescan_dev = false;
for (i = 0; i < ARRAY_SIZE(sdev_states); i++) { const int len = strlen(sdev_states[i].name); @@ -815,20 +816,27 @@ store_state_field(struct device *dev, struct device_attribute *attr, }
mutex_lock(&sdev->state_mutex); - ret = scsi_device_set_state(sdev, state); - /* - * If the device state changes to SDEV_RUNNING, we need to - * run the queue to avoid I/O hang, and rescan the device - * to revalidate it. Running the queue first is necessary - * because another thread may be waiting inside - * blk_mq_freeze_queue_wait() and because that call may be - * waiting for pending I/O to finish. - */ - if (ret == 0 && state == SDEV_RUNNING) { + if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) { + ret = count; + } else { + ret = scsi_device_set_state(sdev, state); + if (ret == 0 && state == SDEV_RUNNING) + rescan_dev = true; + } + mutex_unlock(&sdev->state_mutex); + + if (rescan_dev) { + /* + * If the device state changes to SDEV_RUNNING, we need to + * run the queue to avoid I/O hang, and rescan the device + * to revalidate it. Running the queue first is necessary + * because another thread may be waiting inside + * blk_mq_freeze_queue_wait() and because that call may be + * waiting for pending I/O to finish. + */ blk_mq_run_hw_queues(sdev->request_queue, true); scsi_rescan_device(dev); } - mutex_unlock(&sdev->state_mutex);
return ret == 0 ? count : -EINVAL; }
From: Adrian Hunter adrian.hunter@intel.com
[ Upstream commit 886fe2915cce6658b0fc19e64b82879325de61ea ]
__ufshcd_issue_tm_cmd() clears req->end_io_data after timing out, which races with the completion function ufshcd_tmc_handler() which expects req->end_io_data to have a value.
Note __ufshcd_issue_tm_cmd() and ufshcd_tmc_handler() are already synchronized using hba->tmf_rqs and hba->outstanding_tasks under the host_lock spinlock.
It is also not necessary (nor typical) to clear req->end_io_data because the block layer does it before allocating out requests e.g. via blk_get_request().
So fix by not clearing it.
Link: https://lore.kernel.org/r/20211108064815.569494-2-adrian.hunter@intel.com Fixes: f5ef336fd2e4 ("scsi: ufs: core: Fix task management completion") Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 325a15186e950..3d0da8b3fed8a 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6541,11 +6541,6 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, err = wait_for_completion_io_timeout(&wait, msecs_to_jiffies(TM_CMD_TIMEOUT)); if (!err) { - /* - * Make sure that ufshcd_compl_tm() does not trigger a - * use-after-free. - */ - req->end_io_data = NULL; ufshcd_add_tm_upiu_trace(hba, task_tag, UFS_TM_ERR); dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n", __func__, tm_function);
From: Adrian Hunter adrian.hunter@intel.com
[ Upstream commit 5cb37a26355d79ab290220677b1b57d28e99a895 ]
hba->outstanding_tasks, which is read under host_lock spinlock, tells the interrupt handler what task management tags are in use by the driver. The doorbell register bits indicate which tags are in use by the hardware. A doorbell bit that is 0 is because the bit has yet to be set by the driver, or because the task is complete. It is only possible to disambiguate the 2 cases, if reading/writing the doorbell register is synchronized with reading/writing hba->outstanding_tasks.
For that reason, reading REG_UTP_TASK_REQ_DOOR_BELL must be done under spinlock.
Link: https://lore.kernel.org/r/20211108064815.569494-3-adrian.hunter@intel.com Fixes: f5ef336fd2e4 ("scsi: ufs: core: Fix task management completion") Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3d0da8b3fed8a..55f2e4d6f10b7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -6382,9 +6382,8 @@ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) irqreturn_t ret = IRQ_NONE; int tag;
- pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); - spin_lock_irqsave(hba->host->host_lock, flags); + pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); issued = hba->outstanding_tasks & ~pending; for_each_set_bit(tag, &issued, hba->nutmrs) { struct request *req = hba->tmf_rqs[tag];
From: Marcin Wojtas mw@semihalf.com
[ Upstream commit 2460386bef0b9b98b71728d3c173e15558b78d82 ]
The kernel test robot reported a following issue:
drivers/net/ethernet/marvell/mvmdio.c:426:36: warning:
unused variable 'orion_mdio_acpi_match' [-Wunused-const-variable] static const struct acpi_device_id orion_mdio_acpi_match[] = { ^ 1 warning generated.
Fix that by surrounding the variable by appropriate ifdef.
Fixes: c54da4c1acb1 ("net: mvmdio: add ACPI support") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://lore.kernel.org/r/20211115153024.209083-1-mw@semihalf.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/mvmdio.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c index 62a97c46fba05..ef878973b8597 100644 --- a/drivers/net/ethernet/marvell/mvmdio.c +++ b/drivers/net/ethernet/marvell/mvmdio.c @@ -429,12 +429,14 @@ static const struct of_device_id orion_mdio_match[] = { }; MODULE_DEVICE_TABLE(of, orion_mdio_match);
+#ifdef CONFIG_ACPI static const struct acpi_device_id orion_mdio_acpi_match[] = { { "MRVL0100", BUS_TYPE_SMI }, { "MRVL0101", BUS_TYPE_XSMI }, { }, }; MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match); +#endif
static struct platform_driver orion_mdio_driver = { .probe = orion_mdio_probe,
From: Xin Long lucien.xin@gmail.com
[ Upstream commit f799ada6bf2397c351220088b9b0980125c77280 ]
Without dropping dst, the packets sent from local mirred/redirected to ingress will may still use the old dst. ip_rcv() will drop it as the old dst is for output and its .input is dst_discard.
This patch is to fix by also dropping dst for those packets that are mirred or redirected from egress to ingress in act_mirred.
Note that we don't drop it for the direction change from ingress to egress, as on which there might be a user case attaching a metadata dst by act_tunnel_key that would be used later.
Fixes: b57dc7c13ea9 ("net/sched: Introduce action ct") Signed-off-by: Xin Long lucien.xin@gmail.com Acked-by: Cong Wang cong.wang@bytedance.com Reviewed-by: Marcelo Ricardo Leitner marcelo.leitner@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/act_mirred.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index d64b0eeccbe4d..efc963ab995a3 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -19,6 +19,7 @@ #include <linux/if_arp.h> #include <net/net_namespace.h> #include <net/netlink.h> +#include <net/dst.h> #include <net/pkt_sched.h> #include <net/pkt_cls.h> #include <linux/tc_act/tc_mirred.h> @@ -228,6 +229,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, bool want_ingress; bool is_redirect; bool expects_nh; + bool at_ingress; int m_eaction; int mac_len; bool at_nh; @@ -263,7 +265,8 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, * ingress - that covers the TC S/W datapath. */ is_redirect = tcf_mirred_is_act_redirect(m_eaction); - use_reinsert = skb_at_tc_ingress(skb) && is_redirect && + at_ingress = skb_at_tc_ingress(skb); + use_reinsert = at_ingress && is_redirect && tcf_mirred_can_reinsert(retval); if (!use_reinsert) { skb2 = skb_clone(skb, GFP_ATOMIC); @@ -271,10 +274,12 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, goto out; }
+ want_ingress = tcf_mirred_act_wants_ingress(m_eaction); + /* All mirred/redirected skbs should clear previous ct info */ nf_reset_ct(skb2); - - want_ingress = tcf_mirred_act_wants_ingress(m_eaction); + if (want_ingress && !at_ingress) /* drop dst for egress -> ingress */ + skb_dst_drop(skb2);
expects_nh = want_ingress || !m_mac_header_xmit; at_nh = skb->data == skb_network_header(skb);
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit 9b5a333272a48c2f8b30add7a874e46e8b26129c ]
Access to netdev after free_netdev() will cause use-after-free bug. Move debug log before free_netdev() call to avoid it.
Fixes: 7472dd9f6499 ("staging: fsl-dpaa2/eth: Move print message") Signed-off-by: Pavel Skripkin paskripkin@gmail.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, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 7065c71ed7b86..f3e443f2d9cf9 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -4538,10 +4538,10 @@ static int dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
fsl_mc_portal_free(priv->mc_io);
- free_netdev(net_dev); - dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name);
+ free_netdev(net_dev); + return 0; }
From: Jonathan Davies jonathan.davies@nutanix.com
[ Upstream commit cf9acc90c80ecbee00334aa85d92f4e74014bcff ]
virtio_net_hdr_to_skb does not set the skb's gso_size and gso_type correctly for UFO packets received via virtio-net that are a little over the GSO size. This can lead to problems elsewhere in the networking stack, e.g. ovs_vport_send dropping over-sized packets if gso_size is not set.
This is due to the comparison
if (skb->len - p_off > gso_size)
not properly accounting for the transport layer header.
p_off includes the size of the transport layer header (thlen), so skb->len - p_off is the size of the TCP/UDP payload.
gso_size is read from the virtio-net header. For UFO, fragmentation happens at the IP level so does not need to include the UDP header.
Hence the calculation could be comparing a TCP/UDP payload length with an IP payload length, causing legitimate virtio-net packets to have lack gso_type/gso_size information.
Example: a UDP packet with payload size 1473 has IP payload size 1481. If the guest used UFO, it is not fragmented and the virtio-net header's flags indicate that it is a GSO frame (VIRTIO_NET_HDR_GSO_UDP), with gso_size = 1480 for an MTU of 1500. skb->len will be 1515 and p_off will be 42, so skb->len - p_off = 1473. Hence the comparison fails, and shinfo->gso_size and gso_type are not set as they should be.
Instead, add the UDP header length before comparing to gso_size when using UFO. In this way, it is the size of the IP payload that is compared to gso_size.
Fixes: 6dd912f82680 ("net: check untrusted gso_size at kernel entry") Signed-off-by: Jonathan Davies jonathan.davies@nutanix.com Reviewed-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/virtio_net.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index b465f8f3e554f..04e87f4b9417c 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h @@ -120,10 +120,15 @@ retry:
if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { u16 gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size); + unsigned int nh_off = p_off; struct skb_shared_info *shinfo = skb_shinfo(skb);
+ /* UFO may not include transport header in gso_size. */ + if (gso_type & SKB_GSO_UDP) + nh_off -= thlen; + /* Too small packets are not really GSO ones. */ - if (skb->len - p_off > gso_size) { + if (skb->len - nh_off > gso_size) { shinfo->gso_size = gso_size; shinfo->gso_type = gso_type;
From: Eryk Rybak eryk.roch.rybak@intel.com
[ Upstream commit 6afbd7b3c53cb7417189f476e99d431daccb85b0 ]
Setting VLAN port increasing RX queue max_pkt_size by 4 bytes to take VLAN tag into account. Trigger the VF reset when setting port VLAN for VF to renegotiate its capabilities and reinitialize.
Fixes: ba4e003d29c1 ("i40e: don't hold spinlock while resetting VF") Signed-off-by: Sylwester Dziedziuch sylwesterx.dziedziuch@intel.com Signed-off-by: Aleksandr Loktionov aleksandr.loktionov@intel.com Signed-off-by: Eryk Rybak eryk.roch.rybak@intel.com 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 --- .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 53 ++++--------------- 1 file changed, 9 insertions(+), 44 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 472f56b360b8c..815661632e7a7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -674,14 +674,13 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id, u16 vsi_queue_id, struct virtchnl_rxq_info *info) { + u16 pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); struct i40e_pf *pf = vf->pf; + struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx]; struct i40e_hw *hw = &pf->hw; struct i40e_hmc_obj_rxq rx_ctx; - u16 pf_queue_id; int ret = 0;
- pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); - /* clear the context structure first */ memset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq));
@@ -719,6 +718,10 @@ static int i40e_config_vsi_rx_queue(struct i40e_vf *vf, u16 vsi_id, } rx_ctx.rxmax = info->max_pkt_size;
+ /* if port VLAN is configured increase the max packet size */ + if (vsi->info.pvid) + rx_ctx.rxmax += VLAN_HLEN; + /* enable 32bytes desc always */ rx_ctx.dsize = 1;
@@ -4169,34 +4172,6 @@ error_param: return ret; }
-/** - * i40e_vsi_has_vlans - True if VSI has configured VLANs - * @vsi: pointer to the vsi - * - * Check if a VSI has configured any VLANs. False if we have a port VLAN or if - * we have no configured VLANs. Do not call while holding the - * mac_filter_hash_lock. - */ -static bool i40e_vsi_has_vlans(struct i40e_vsi *vsi) -{ - bool have_vlans; - - /* If we have a port VLAN, then the VSI cannot have any VLANs - * configured, as all MAC/VLAN filters will be assigned to the PVID. - */ - if (vsi->info.pvid) - return false; - - /* Since we don't have a PVID, we know that if the device is in VLAN - * mode it must be because of a VLAN filter configured on this VSI. - */ - spin_lock_bh(&vsi->mac_filter_hash_lock); - have_vlans = i40e_is_vsi_in_vlan(vsi); - spin_unlock_bh(&vsi->mac_filter_hash_lock); - - return have_vlans; -} - /** * i40e_ndo_set_vf_port_vlan * @netdev: network interface device structure @@ -4253,19 +4228,9 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, /* duplicate request, so just return success */ goto error_pvid;
- if (i40e_vsi_has_vlans(vsi)) { - dev_err(&pf->pdev->dev, - "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n", - vf_id); - /* Administrator Error - knock the VF offline until he does - * the right thing by reconfiguring his network correctly - * and then reloading the VF driver. - */ - i40e_vc_disable_vf(vf); - /* During reset the VF got a new VSI, so refresh the pointer. */ - vsi = pf->vsi[vf->lan_vsi_idx]; - } - + i40e_vc_disable_vf(vf); + /* During reset the VF got a new VSI, so refresh a pointer. */ + vsi = pf->vsi[vf->lan_vsi_idx]; /* Locked once because multiple functions below iterate list */ spin_lock_bh(&vsi->mac_filter_hash_lock);
From: Michal Maloszewski michal.maloszewski@intel.com
[ Upstream commit 37d9e304acd903a445df8208b8a13d707902dea6 ]
Remove the reason of null pointer dereference in sync VSI filters. Added new I40E_VSI_RELEASING flag to signalize deleting and releasing of VSI resources to sync this thread with sync filters subtask. Without this patch it is possible to start update the VSI filter list after VSI is removed, that's causing a kernel oops.
Fixes: 41c445ff0f48 ("i40e: main driver core") Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Signed-off-by: Michal Maloszewski michal.maloszewski@intel.com Reviewed-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Reviewed-by: Witold Fijalkowski witoldx.fijalkowski@intel.com Reviewed-by: Jaroslaw Gawin jaroslawx.gawin@intel.com Reviewed-by: Aleksandr Loktionov aleksandr.loktionov@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 39fb3d57c0574..d7db443abeafa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -161,6 +161,7 @@ enum i40e_vsi_state_t { __I40E_VSI_OVERFLOW_PROMISC, __I40E_VSI_REINIT_REQUESTED, __I40E_VSI_DOWN_REQUESTED, + __I40E_VSI_RELEASING, /* This must be last as it determines the size of the BITMAP */ __I40E_VSI_STATE_SIZE__, }; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index e04b540cedc85..9777fa3535830 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2623,7 +2623,8 @@ static void i40e_sync_filters_subtask(struct i40e_pf *pf)
for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v] && - (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED)) { + (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED) && + !test_bit(__I40E_VSI_RELEASING, pf->vsi[v]->state)) { int ret = i40e_sync_vsi_filters(pf->vsi[v]);
if (ret) { @@ -13771,7 +13772,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi) dev_info(&pf->pdev->dev, "Can't remove PF VSI\n"); return -ENODEV; } - + set_bit(__I40E_VSI_RELEASING, vsi->state); uplink_seid = vsi->uplink_seid; if (vsi->type != I40E_VSI_SRIOV) { if (vsi->netdev_registered) {
From: Eryk Rybak eryk.roch.rybak@intel.com
[ Upstream commit d2a69fefd75683004ffe87166de5635b3267ee07 ]
Currently, the i40e_vsi_setup_queue_map is basing the count of queues in TCs on a VSI's alloc_queue_pairs member which is not changed throughout any user's action (for example via ethtool's set_channels callback).
This implies that vsi->tc_config.tc_info[n].qcount value that is given to the kernel via netdev_set_tc_queue() that notifies about the count of queues per particular traffic class is constant even if user has changed the total count of queues.
This in turn caused the kernel warning after setting the queue count to the lower value than the initial one:
$ ethtool -l ens801f0 Channel parameters for ens801f0: Pre-set maximums: RX: 0 TX: 0 Other: 1 Combined: 64 Current hardware settings: RX: 0 TX: 0 Other: 1 Combined: 64
$ ethtool -L ens801f0 combined 40
[dmesg] Number of in use tx queues changed invalidating tc mappings. Priority traffic classification disabled!
Reason was that vsi->alloc_queue_pairs stayed at 64 value which was used to set the qcount on TC0 (by default only TC0 exists so all of the existing queues are assigned to TC0). we update the offset/qcount via netdev_set_tc_queue() back to the old value but then the netif_set_real_num_tx_queues() is using the vsi->num_queue_pairs as a value which got set to 40.
Fix it by using vsi->req_queue_pairs as a queue count that will be distributed across TCs. Do it only for non-zero values, which implies that user actually requested the new count of queues.
For VSIs other than main, stay with the vsi->alloc_queue_pairs as we only allow manipulating the queue count on main VSI.
Fixes: bc6d33c8d93f ("i40e: Fix the number of queues available to be mapped for use") Co-developed-by: Maciej Fijalkowski maciej.fijalkowski@intel.com Signed-off-by: Maciej Fijalkowski maciej.fijalkowski@intel.com Co-developed-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Signed-off-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Signed-off-by: Eryk Rybak eryk.roch.rybak@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e_main.c | 35 ++++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 9777fa3535830..dc78ffac10371 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1790,6 +1790,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, bool is_add) { struct i40e_pf *pf = vsi->back; + u16 num_tc_qps = 0; u16 sections = 0; u8 netdev_tc = 0; u16 numtc = 1; @@ -1797,13 +1798,29 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, u8 offset; u16 qmap; int i; - u16 num_tc_qps = 0;
sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID; offset = 0;
+ if (vsi->type == I40E_VSI_MAIN) { + /* This code helps add more queue to the VSI if we have + * more cores than RSS can support, the higher cores will + * be served by ATR or other filters. Furthermore, the + * non-zero req_queue_pairs says that user requested a new + * queue count via ethtool's set_channels, so use this + * value for queues distribution across traffic classes + */ + if (vsi->req_queue_pairs > 0) + vsi->num_queue_pairs = vsi->req_queue_pairs; + else if (pf->flags & I40E_FLAG_MSIX_ENABLED) + vsi->num_queue_pairs = pf->num_lan_msix; + } + /* Number of queues per enabled TC */ - num_tc_qps = vsi->alloc_queue_pairs; + if (vsi->type == I40E_VSI_MAIN) + num_tc_qps = vsi->num_queue_pairs; + else + num_tc_qps = vsi->alloc_queue_pairs; if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) { /* Find numtc from enabled TC bitmap */ for (i = 0, numtc = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { @@ -1881,16 +1898,10 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, } ctxt->info.tc_mapping[i] = cpu_to_le16(qmap); } - - /* Set actual Tx/Rx queue pairs */ - vsi->num_queue_pairs = offset; - if ((vsi->type == I40E_VSI_MAIN) && (numtc == 1)) { - if (vsi->req_queue_pairs > 0) - vsi->num_queue_pairs = vsi->req_queue_pairs; - else if (pf->flags & I40E_FLAG_MSIX_ENABLED) - vsi->num_queue_pairs = pf->num_lan_msix; - } - + /* Do not change previously set num_queue_pairs for PFs */ + if ((vsi->type == I40E_VSI_MAIN && numtc != 1) || + vsi->type != I40E_VSI_MAIN) + vsi->num_queue_pairs = offset; /* Scheduler section valid can only be set for ADD VSI */ if (is_add) { sections |= I40E_AQ_VSI_PROP_SCHED_VALID;
From: Eryk Rybak eryk.roch.rybak@intel.com
[ Upstream commit 9e0a603cb7dce2a19d98116d42de84b6db26d716 ]
Properly reconfigure VF VSIs after VF request ADQ. Created new function to update queue mapping and queue pairs per TC with AQ update VSI. This sets proper RSS size on NIC. VFs num_queue_pairs should not be changed during setup of queue maps. Previously, VF main VSI in ADQ had configured too many queues and had wrong RSS size, which lead to packets not being consumed and drops in connectivity.
Fixes: bc6d33c8d93f ("i40e: Fix the number of queues available to be mapped for use") Co-developed-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Signed-off-by: Przemyslaw Patynowski przemyslawx.patynowski@intel.com Signed-off-by: Eryk Rybak eryk.roch.rybak@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e.h | 1 + drivers/net/ethernet/intel/i40e/i40e_main.c | 64 ++++++++++++++++++- .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 17 +++-- 3 files changed, 74 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index d7db443abeafa..b10bc59c5700f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -1248,6 +1248,7 @@ void i40e_ptp_restore_hw_time(struct i40e_pf *pf); void i40e_ptp_init(struct i40e_pf *pf); void i40e_ptp_stop(struct i40e_pf *pf); int i40e_ptp_alloc_pins(struct i40e_pf *pf); +int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset); int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi); i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf); i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index dc78ffac10371..42e26ee5b6d5f 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1801,6 +1801,8 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID; offset = 0; + /* zero out queue mapping, it will get updated on the end of the function */ + memset(ctxt->info.queue_mapping, 0, sizeof(ctxt->info.queue_mapping));
if (vsi->type == I40E_VSI_MAIN) { /* This code helps add more queue to the VSI if we have @@ -1817,10 +1819,12 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, }
/* Number of queues per enabled TC */ - if (vsi->type == I40E_VSI_MAIN) + if (vsi->type == I40E_VSI_MAIN || + (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs != 0)) num_tc_qps = vsi->num_queue_pairs; else num_tc_qps = vsi->alloc_queue_pairs; + if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) { /* Find numtc from enabled TC bitmap */ for (i = 0, numtc = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { @@ -1898,10 +1902,12 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi, } ctxt->info.tc_mapping[i] = cpu_to_le16(qmap); } - /* Do not change previously set num_queue_pairs for PFs */ + /* Do not change previously set num_queue_pairs for PFs and VFs*/ if ((vsi->type == I40E_VSI_MAIN && numtc != 1) || - vsi->type != I40E_VSI_MAIN) + (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs == 0) || + (vsi->type != I40E_VSI_MAIN && vsi->type != I40E_VSI_SRIOV)) vsi->num_queue_pairs = offset; + /* Scheduler section valid can only be set for ADD VSI */ if (is_add) { sections |= I40E_AQ_VSI_PROP_SCHED_VALID; @@ -5438,6 +5444,58 @@ static void i40e_vsi_update_queue_map(struct i40e_vsi *vsi, sizeof(vsi->info.tc_mapping)); }
+/** + * i40e_update_adq_vsi_queues - update queue mapping for ADq VSI + * @vsi: the VSI being reconfigured + * @vsi_offset: offset from main VF VSI + */ +int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset) +{ + struct i40e_vsi_context ctxt = {}; + struct i40e_pf *pf; + struct i40e_hw *hw; + int ret; + + if (!vsi) + return I40E_ERR_PARAM; + pf = vsi->back; + hw = &pf->hw; + + ctxt.seid = vsi->seid; + ctxt.pf_num = hw->pf_id; + ctxt.vf_num = vsi->vf_id + hw->func_caps.vf_base_id + vsi_offset; + ctxt.uplink_seid = vsi->uplink_seid; + ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL; + ctxt.flags = I40E_AQ_VSI_TYPE_VF; + ctxt.info = vsi->info; + + i40e_vsi_setup_queue_map(vsi, &ctxt, vsi->tc_config.enabled_tc, + false); + if (vsi->reconfig_rss) { + vsi->rss_size = min_t(int, pf->alloc_rss_size, + vsi->num_queue_pairs); + ret = i40e_vsi_config_rss(vsi); + if (ret) { + dev_info(&pf->pdev->dev, "Failed to reconfig rss for num_queues\n"); + return ret; + } + vsi->reconfig_rss = false; + } + + ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); + if (ret) { + dev_info(&pf->pdev->dev, "Update vsi config failed, err %s aq_err %s\n", + i40e_stat_str(hw, ret), + i40e_aq_str(hw, hw->aq.asq_last_status)); + return ret; + } + /* update the local VSI info with updated queue map */ + i40e_vsi_update_queue_map(vsi, &ctxt); + vsi->info.valid_sections = 0; + + return ret; +} + /** * i40e_vsi_config_tc - Configure VSI Tx Scheduler for given TC map * @vsi: VSI to be configured diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 815661632e7a7..2102db11972a7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2220,11 +2220,12 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) struct virtchnl_vsi_queue_config_info *qci = (struct virtchnl_vsi_queue_config_info *)msg; struct virtchnl_queue_pair_info *qpi; - struct i40e_pf *pf = vf->pf; u16 vsi_id, vsi_queue_id = 0; - u16 num_qps_all = 0; + struct i40e_pf *pf = vf->pf; i40e_status aq_ret = 0; int i, j = 0, idx = 0; + struct i40e_vsi *vsi; + u16 num_qps_all = 0;
if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { aq_ret = I40E_ERR_PARAM; @@ -2313,9 +2314,15 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) pf->vsi[vf->lan_vsi_idx]->num_queue_pairs = qci->num_queue_pairs; } else { - for (i = 0; i < vf->num_tc; i++) - pf->vsi[vf->ch[i].vsi_idx]->num_queue_pairs = - vf->ch[i].num_qps; + for (i = 0; i < vf->num_tc; i++) { + vsi = pf->vsi[vf->ch[i].vsi_idx]; + vsi->num_queue_pairs = vf->ch[i].num_qps; + + if (i40e_update_adq_vsi_queues(vsi, i)) { + aq_ret = I40E_ERR_CONFIG; + goto error_param; + } + } }
error_param:
From: Jack Wang jinpu.wang@ionos.com
[ Upstream commit 378c67413de18b69fb3bb78d8c4f0f1192cfa973 ]
If the FW doesn't support MLX4_DEV_CAP_FLAG2_DIAG_PER_PORT, mlx4 driver will fail the ib_setup_port_attrs, which is called from ib_register_device()/enable_device_and_get(), in the end leads to device not detected[1][2]
To fix it, add a new mlx4_ib_hw_stats_ops1, w/o alloc_hw_port_stats if FW does not support MLX4_DEV_CAP_FLAG2_DIAG_PER_PORT.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=2014094 [2] https://lore.kernel.org/linux-rdma/CAMGffEn2wvEnmzc0xe=xYiCLqpphiHDBxCxqAELr...
Fixes: 4b5f4d3fb408 ("RDMA: Split the alloc_hw_stats() ops to port and device variants") Link: https://lore.kernel.org/r/20211115101519.27210-1-jinpu.wang@ionos.com Signed-off-by: Jack Wang jinpu.wang@ionos.com Reviewed-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx4/main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index f367f4a4abffc..aec2e1851fa70 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -2217,6 +2217,11 @@ static const struct ib_device_ops mlx4_ib_hw_stats_ops = { .get_hw_stats = mlx4_ib_get_hw_stats, };
+static const struct ib_device_ops mlx4_ib_hw_stats_ops1 = { + .alloc_hw_device_stats = mlx4_ib_alloc_hw_device_stats, + .get_hw_stats = mlx4_ib_get_hw_stats, +}; + static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev) { struct mlx4_ib_diag_counters *diag = ibdev->diag_counters; @@ -2229,9 +2234,16 @@ static int mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev) return 0;
for (i = 0; i < MLX4_DIAG_COUNTERS_TYPES; i++) { - /* i == 1 means we are building port counters */ - if (i && !per_port) - continue; + /* + * i == 1 means we are building port counters, set a different + * stats ops without port stats callback. + */ + if (i && !per_port) { + ib_set_device_ops(&ibdev->ib_dev, + &mlx4_ib_hw_stats_ops1); + + return 0; + }
ret = __mlx4_ib_alloc_diag_counters(ibdev, &diag[i].name, &diag[i].offset,
From: Karen Sornek karen.sornek@intel.com
[ Upstream commit 3a3b311e3881172fc8e019b6508f04bc40c92d9d ]
Restore part of reset functionality used when reset is called from the VF to reset itself. Without this fix warning message is displayed when VF is being removed via sysfs.
Fix the crash of the VF during reset by ensuring that the PF receives the reset message successfully. Refactor code to use one function instead of two.
Fixes: 5c3c48ac6bf5 ("i40e: implement virtual device interface") Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Signed-off-by: Karen Sornek karen.sornek@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/intel/i40e/i40e_virtchnl_pf.c | 53 ++++++++----------- 1 file changed, 21 insertions(+), 32 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 2102db11972a7..80ae264c99ba0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -183,17 +183,18 @@ void i40e_vc_notify_vf_reset(struct i40e_vf *vf) /***********************misc routines*****************************/
/** - * i40e_vc_disable_vf + * i40e_vc_reset_vf * @vf: pointer to the VF info - * - * Disable the VF through a SW reset. + * @notify_vf: notify vf about reset or not + * Reset VF handler. **/ -static inline void i40e_vc_disable_vf(struct i40e_vf *vf) +static void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf) { struct i40e_pf *pf = vf->pf; int i;
- i40e_vc_notify_vf_reset(vf); + if (notify_vf) + i40e_vc_notify_vf_reset(vf);
/* We want to ensure that an actual reset occurs initiated after this * function was called. However, we do not want to wait forever, so @@ -211,9 +212,14 @@ static inline void i40e_vc_disable_vf(struct i40e_vf *vf) usleep_range(10000, 20000); }
- dev_warn(&vf->pf->pdev->dev, - "Failed to initiate reset for VF %d after 200 milliseconds\n", - vf->vf_id); + if (notify_vf) + dev_warn(&vf->pf->pdev->dev, + "Failed to initiate reset for VF %d after 200 milliseconds\n", + vf->vf_id); + else + dev_dbg(&vf->pf->pdev->dev, + "Failed to initiate reset for VF %d after 200 milliseconds\n", + vf->vf_id); }
/** @@ -2108,20 +2114,6 @@ err: return ret; }
-/** - * i40e_vc_reset_vf_msg - * @vf: pointer to the VF info - * - * called from the VF to reset itself, - * unlike other virtchnl messages, PF driver - * doesn't send the response back to the VF - **/ -static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) -{ - if (test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) - i40e_reset_vf(vf, false); -} - /** * i40e_vc_config_promiscuous_mode_msg * @vf: pointer to the VF info @@ -2617,8 +2609,7 @@ static int i40e_vc_request_queues_msg(struct i40e_vf *vf, u8 *msg) } else { /* successful request */ vf->num_req_queues = req_pairs; - i40e_vc_notify_vf_reset(vf); - i40e_reset_vf(vf, false); + i40e_vc_reset_vf(vf, true); return 0; }
@@ -3813,8 +3804,7 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) vf->num_req_queues = 0;
/* reset the VF in order to allocate resources */ - i40e_vc_notify_vf_reset(vf); - i40e_reset_vf(vf, false); + i40e_vc_reset_vf(vf, true);
return I40E_SUCCESS;
@@ -3854,8 +3844,7 @@ static int i40e_vc_del_qch_msg(struct i40e_vf *vf, u8 *msg) }
/* reset the VF in order to allocate resources */ - i40e_vc_notify_vf_reset(vf); - i40e_reset_vf(vf, false); + i40e_vc_reset_vf(vf, true);
return I40E_SUCCESS;
@@ -3917,7 +3906,7 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode, i40e_vc_notify_vf_link_state(vf); break; case VIRTCHNL_OP_RESET_VF: - i40e_vc_reset_vf_msg(vf); + i40e_vc_reset_vf(vf, false); ret = 0; break; case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: @@ -4171,7 +4160,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) /* Force the VF interface down so it has to bring up with new MAC * address */ - i40e_vc_disable_vf(vf); + i40e_vc_reset_vf(vf, true); dev_info(&pf->pdev->dev, "Bring down and up the VF interface to make this change effective.\n");
error_param: @@ -4235,7 +4224,7 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, /* duplicate request, so just return success */ goto error_pvid;
- i40e_vc_disable_vf(vf); + i40e_vc_reset_vf(vf, true); /* During reset the VF got a new VSI, so refresh a pointer. */ vsi = pf->vsi[vf->lan_vsi_idx]; /* Locked once because multiple functions below iterate list */ @@ -4613,7 +4602,7 @@ int i40e_ndo_set_vf_trust(struct net_device *netdev, int vf_id, bool setting) goto out;
vf->trusted = setting; - i40e_vc_disable_vf(vf); + i40e_vc_reset_vf(vf, true); dev_info(&pf->pdev->dev, "VF %u is now %strusted\n", vf_id, setting ? "" : "un");
From: Jedrzej Jagielski jedrzej.jagielski@intel.com
[ Upstream commit 2e6d218c1ec6fb9cd70693b78134cbc35ae0b5a9 ]
Reject TCs creation with proper message if the first queue assignment is not equal to the power of two. The first queue number was checked too late in the second queue iteration, if second queue was configured at all. Now if first queue value is not a power of two, then trying to create qdisc will be rejected.
Fixes: 8f88b3034db3 ("i40e: Add infrastructure for queue channel support") Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Signed-off-by: Jedrzej Jagielski jedrzej.jagielski@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e_main.c | 59 +++++++-------------- 1 file changed, 19 insertions(+), 40 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 42e26ee5b6d5f..83413999902e5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -5786,24 +5786,6 @@ static void i40e_remove_queue_channels(struct i40e_vsi *vsi) INIT_LIST_HEAD(&vsi->ch_list); }
-/** - * i40e_is_any_channel - channel exist or not - * @vsi: ptr to VSI to which channels are associated with - * - * Returns true or false if channel(s) exist for associated VSI or not - **/ -static bool i40e_is_any_channel(struct i40e_vsi *vsi) -{ - struct i40e_channel *ch, *ch_tmp; - - list_for_each_entry_safe(ch, ch_tmp, &vsi->ch_list, list) { - if (ch->initialized) - return true; - } - - return false; -} - /** * i40e_get_max_queues_for_channel * @vsi: ptr to VSI to which channels are associated with @@ -6310,26 +6292,15 @@ int i40e_create_queue_channel(struct i40e_vsi *vsi, /* By default we are in VEPA mode, if this is the first VF/VMDq * VSI to be added switch to VEB mode. */ - if ((!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) || - (!i40e_is_any_channel(vsi))) { - if (!is_power_of_2(vsi->tc_config.tc_info[0].qcount)) { - dev_dbg(&pf->pdev->dev, - "Failed to create channel. Override queues (%u) not power of 2\n", - vsi->tc_config.tc_info[0].qcount); - return -EINVAL; - }
- if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { - pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; + if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { + pf->flags |= I40E_FLAG_VEB_MODE_ENABLED;
- if (vsi->type == I40E_VSI_MAIN) { - if (pf->flags & I40E_FLAG_TC_MQPRIO) - i40e_do_reset(pf, I40E_PF_RESET_FLAG, - true); - else - i40e_do_reset_safe(pf, - I40E_PF_RESET_FLAG); - } + if (vsi->type == I40E_VSI_MAIN) { + if (pf->flags & I40E_FLAG_TC_MQPRIO) + i40e_do_reset(pf, I40E_PF_RESET_FLAG, true); + else + i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); } /* now onwards for main VSI, number of queues will be value * of TC0's queue count @@ -7982,12 +7953,20 @@ config_tc: vsi->seid); need_reset = true; goto exit; - } else { - dev_info(&vsi->back->pdev->dev, - "Setup channel (id:%u) utilizing num_queues %d\n", - vsi->seid, vsi->tc_config.tc_info[0].qcount); + } else if (enabled_tc && + (!is_power_of_2(vsi->tc_config.tc_info[0].qcount))) { + netdev_info(netdev, + "Failed to create channel. Override queues (%u) not power of 2\n", + vsi->tc_config.tc_info[0].qcount); + ret = -EINVAL; + need_reset = true; + goto exit; }
+ dev_info(&vsi->back->pdev->dev, + "Setup channel (id:%u) utilizing num_queues %d\n", + vsi->seid, vsi->tc_config.tc_info[0].qcount); + if (pf->flags & I40E_FLAG_TC_MQPRIO) { if (vsi->mqprio_qopt.max_rate[0]) { u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0];
From: Grzegorz Szczurek grzegorzx.szczurek@intel.com
[ Upstream commit 5aff430d4e33a0b48a6b3d5beb06f79da23f9916 ]
Fix misleading display error in dmesg if tc filter return fail. Only i40e status error code should be converted to string, not linux error code. Otherwise, we return false information about the error.
Fixes: 2f4b411a3d67 ("i40e: Enable cloud filters via tc-flower") Signed-off-by: Grzegorz Szczurek grzegorzx.szczurek@intel.com Signed-off-by: Mateusz Palczewski mateusz.palczewski@intel.com Tested-by: Dave Switzer david.switzer@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/i40e/i40e_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 83413999902e5..76d0b809d1340 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8531,9 +8531,8 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi, err = i40e_add_del_cloud_filter(vsi, filter, true);
if (err) { - dev_err(&pf->pdev->dev, - "Failed to add cloud filter, err %s\n", - i40e_stat_str(&pf->hw, err)); + dev_err(&pf->pdev->dev, "Failed to add cloud filter, err %d\n", + err); goto err; }
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 86cdf8e38792545161dbe3350a7eced558ba4d15 ]
There is a possible data race as shown below:
thread-A in nci_request() | thread-B in nci_close_device() | mutex_lock(&ndev->req_lock); test_bit(NCI_UP, &ndev->flags); | ... | test_and_clear_bit(NCI_UP, &ndev->flags) mutex_lock(&ndev->req_lock); | |
This race will allow __nci_request() to be awaked while the device is getting removed.
Similar to commit e2cb6b891ad2 ("bluetooth: eliminate the potential race condition when removing the HCI controller"). this patch alters the function sequence in nci_request() to prevent the data races between the nci_close_device().
Signed-off-by: Lin Ma linma@zju.edu.cn Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation") Link: https://lore.kernel.org/r/20211115145600.8320-1-linma@zju.edu.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/nci/core.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 82ab39d80726e..39994dbb6a55b 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -144,12 +144,15 @@ inline int nci_request(struct nci_dev *ndev, { int rc;
- if (!test_bit(NCI_UP, &ndev->flags)) - return -ENETDOWN; - /* Serialize all requests */ mutex_lock(&ndev->req_lock); - rc = __nci_request(ndev, req, opt, timeout); + /* check the state after obtaing the lock against any races + * from nci_close_device when the device gets removed. + */ + if (test_bit(NCI_UP, &ndev->flags)) + rc = __nci_request(ndev, req, opt, timeout); + else + rc = -ENETDOWN; mutex_unlock(&ndev->req_lock);
return rc;
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 3e3b5dfcd16a3e254aab61bd1e8c417dd4503102 ]
There is a potential UAF between the unregistration routine and the NFC netlink operations.
The race that cause that UAF can be shown as below:
(FREE) | (USE) nfcmrvl_nci_unregister_dev | nfc_genl_dev_up nci_close_device | nci_unregister_device | nfc_get_device nfc_unregister_device | nfc_dev_up rfkill_destory | device_del | rfkill_blocked ... | ...
The root cause for this race is concluded below: 1. The rfkill_blocked (USE) in nfc_dev_up is supposed to be placed after the device_is_registered check. 2. Since the netlink operations are possible just after the device_add in nfc_register_device, the nfc_dev_up() can happen anywhere during the rfkill creation process, which leads to data race.
This patch reorder these actions to permit 1. Once device_del is finished, the nfc_dev_up cannot dereference the rfkill object. 2. The rfkill_register need to be placed after the device_add of nfc_dev because the parent device need to be created first. So this patch keeps the order but inject device_lock to prevent the data race.
Signed-off-by: Lin Ma linma@zju.edu.cn Fixes: be055b2f89b5 ("NFC: RFKILL support") Reviewed-by: Jakub Kicinski kuba@kernel.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Link: https://lore.kernel.org/r/20211116152652.19217-1-linma@zju.edu.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/nfc/core.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/net/nfc/core.c b/net/nfc/core.c index 3c645c1d99c9b..dc7a2404efdf9 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -94,13 +94,13 @@ int nfc_dev_up(struct nfc_dev *dev)
device_lock(&dev->dev);
- if (dev->rfkill && rfkill_blocked(dev->rfkill)) { - rc = -ERFKILL; + if (!device_is_registered(&dev->dev)) { + rc = -ENODEV; goto error; }
- if (!device_is_registered(&dev->dev)) { - rc = -ENODEV; + if (dev->rfkill && rfkill_blocked(dev->rfkill)) { + rc = -ERFKILL; goto error; }
@@ -1125,11 +1125,7 @@ int nfc_register_device(struct nfc_dev *dev) if (rc) pr_err("Could not register llcp device\n");
- rc = nfc_genl_device_added(dev); - if (rc) - pr_debug("The userspace won't be notified that the device %s was added\n", - dev_name(&dev->dev)); - + device_lock(&dev->dev); dev->rfkill = rfkill_alloc(dev_name(&dev->dev), &dev->dev, RFKILL_TYPE_NFC, &nfc_rfkill_ops, dev); if (dev->rfkill) { @@ -1138,6 +1134,12 @@ int nfc_register_device(struct nfc_dev *dev) dev->rfkill = NULL; } } + device_unlock(&dev->dev); + + rc = nfc_genl_device_added(dev); + if (rc) + pr_debug("The userspace won't be notified that the device %s was added\n", + dev_name(&dev->dev));
return 0; } @@ -1154,10 +1156,17 @@ void nfc_unregister_device(struct nfc_dev *dev)
pr_debug("dev_name=%s\n", dev_name(&dev->dev));
+ rc = nfc_genl_device_removed(dev); + if (rc) + pr_debug("The userspace won't be notified that the device %s " + "was removed\n", dev_name(&dev->dev)); + + device_lock(&dev->dev); if (dev->rfkill) { rfkill_unregister(dev->rfkill); rfkill_destroy(dev->rfkill); } + device_unlock(&dev->dev);
if (dev->ops->check_presence) { device_lock(&dev->dev); @@ -1167,11 +1176,6 @@ void nfc_unregister_device(struct nfc_dev *dev) cancel_work_sync(&dev->check_pres_work); }
- rc = nfc_genl_device_removed(dev); - if (rc) - pr_debug("The userspace won't be notified that the device %s " - "was removed\n", dev_name(&dev->dev)); - nfc_llcp_unregister_device(dev);
mutex_lock(&nfc_devlist_mutex);
From: Lin Ma linma@zju.edu.cn
[ Upstream commit 48b71a9e66c2eab60564b1b1c85f4928ed04e406 ]
There are two sites that calls queue_work() after the destroy_workqueue() and lead to possible UAF.
The first site is nci_send_cmd(), which can happen after the nci_close_device as below
nfcmrvl_nci_unregister_dev | nfc_genl_dev_up nci_close_device | flush_workqueue | del_timer_sync | nci_unregister_device | nfc_get_device destroy_workqueue | nfc_dev_up nfc_unregister_device | nci_dev_up device_del | nci_open_device | __nci_request | nci_send_cmd | queue_work !!!
Another site is nci_cmd_timer, awaked by the nci_cmd_work from the nci_send_cmd.
... | ... nci_unregister_device | queue_work destroy_workqueue | nfc_unregister_device | ... device_del | nci_cmd_work | mod_timer | ... | nci_cmd_timer | queue_work !!!
For the above two UAF, the root cause is that the nfc_dev_up can race between the nci_unregister_device routine. Therefore, this patch introduce NCI_UNREG flag to easily eliminate the possible race. In addition, the mutex_lock in nci_close_device can act as a barrier.
Signed-off-by: Lin Ma linma@zju.edu.cn Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation") Reviewed-by: Jakub Kicinski kuba@kernel.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Link: https://lore.kernel.org/r/20211116152732.19238-1-linma@zju.edu.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/nfc/nci_core.h | 1 + net/nfc/nci/core.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index a964daedc17b6..ea8595651c384 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -30,6 +30,7 @@ enum nci_flag { NCI_UP, NCI_DATA_EXCHANGE, NCI_DATA_EXCHANGE_TO, + NCI_UNREG, };
/* NCI device states */ diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 39994dbb6a55b..e41e2e9e54984 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -476,6 +476,11 @@ static int nci_open_device(struct nci_dev *ndev)
mutex_lock(&ndev->req_lock);
+ if (test_bit(NCI_UNREG, &ndev->flags)) { + rc = -ENODEV; + goto done; + } + if (test_bit(NCI_UP, &ndev->flags)) { rc = -EALREADY; goto done; @@ -548,6 +553,10 @@ done: static int nci_close_device(struct nci_dev *ndev) { nci_req_cancel(ndev, ENODEV); + + /* This mutex needs to be held as a barrier for + * caller nci_unregister_device + */ mutex_lock(&ndev->req_lock);
if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { @@ -585,8 +594,8 @@ static int nci_close_device(struct nci_dev *ndev)
del_timer_sync(&ndev->cmd_timer);
- /* Clear flags */ - ndev->flags = 0; + /* Clear flags except NCI_UNREG */ + ndev->flags &= BIT(NCI_UNREG);
mutex_unlock(&ndev->req_lock);
@@ -1273,6 +1282,12 @@ void nci_unregister_device(struct nci_dev *ndev) { struct nci_conn_info *conn_info, *n;
+ /* This set_bit is not protected with specialized barrier, + * However, it is fine because the mutex_lock(&ndev->req_lock); + * in nci_close_device() will help to emit one. + */ + set_bit(NCI_UNREG, &ndev->flags); + nci_close_device(ndev);
destroy_workqueue(ndev->cmd_wq);
From: Jesse Brandeburg jesse.brandeburg@intel.com
[ Upstream commit 5d2ca2e12dfb2aff3388ca57b06f570fa6206ced ]
As reported in [1], e100 was no longer working for suspend/resume cycles. The previous commit mentioned in the fixes appears to have broken things and this attempts to practice best known methods for device power management and keep wake-up working while allowing suspend/resume to work. To do this, I reorder a little bit of code and fix the resume path to make sure the device is enabled.
[1] https://bugzilla.kernel.org/show_bug.cgi?id=214933
Fixes: 69a74aef8a18 ("e100: use generic power management") Cc: Vaibhav Gupta vaibhavgupta40@gmail.com Reported-by: Alexey Kuznetsov axet@me.com Signed-off-by: Jesse Brandeburg jesse.brandeburg@intel.com Tested-by: Alexey Kuznetsov axet@me.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/e100.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 09ae1939e6db4..36d52246bdc66 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -3003,9 +3003,10 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev);
+ netif_device_detach(netdev); + if (netif_running(netdev)) e100_down(nic); - netif_device_detach(netdev);
if ((nic->flags & wol_magic) | e100_asf(nic)) { /* enable reverse auto-negotiation */ @@ -3022,7 +3023,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) *enable_wake = false; }
- pci_clear_master(pdev); + pci_disable_device(pdev); }
static int __e100_power_off(struct pci_dev *pdev, bool wake) @@ -3042,8 +3043,6 @@ static int __maybe_unused e100_suspend(struct device *dev_d)
__e100_shutdown(to_pci_dev(dev_d), &wake);
- device_wakeup_disable(dev_d); - return 0; }
@@ -3051,6 +3050,14 @@ static int __maybe_unused e100_resume(struct device *dev_d) { struct net_device *netdev = dev_get_drvdata(dev_d); struct nic *nic = netdev_priv(netdev); + int err; + + err = pci_enable_device(to_pci_dev(dev_d)); + if (err) { + netdev_err(netdev, "Resume cannot enable PCI device, aborting\n"); + return err; + } + pci_set_master(to_pci_dev(dev_d));
/* disable reverse auto-negotiation */ if (nic->phy == phy_82552_v) { @@ -3062,10 +3069,11 @@ static int __maybe_unused e100_resume(struct device *dev_d) smartspeed & ~(E100_82552_REV_ANEG)); }
- netif_device_attach(netdev); if (netif_running(netdev)) e100_up(nic);
+ netif_device_attach(netdev); + return 0; }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit c7521d3aa2fa7fc785682758c99b5bcae503f6be ]
The ptp_ocp_get_mem() function does not return NULL, it returns error pointers.
Fixes: 773bda964921 ("ptp: ocp: Expose various resources on the timecard.") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ptp/ptp_ocp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index caf9b37c5eb1e..e238ae8e94709 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -1049,10 +1049,11 @@ ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r) if (!ext) return -ENOMEM;
- err = -EINVAL; ext->mem = ptp_ocp_get_mem(bp, r); - if (!ext->mem) + if (IS_ERR(ext->mem)) { + err = PTR_ERR(ext->mem); goto out; + }
ext->bp = bp; ext->info = r->extra; @@ -1122,8 +1123,8 @@ ptp_ocp_register_mem(struct ptp_ocp *bp, struct ocp_resource *r) void __iomem *mem;
mem = ptp_ocp_get_mem(bp, r); - if (!mem) - return -EINVAL; + if (IS_ERR(mem)) + return PTR_ERR(mem);
bp_assign_entry(bp, r, mem);
From: Sohaib Mohamed sohaib.amhmd@gmail.com
[ Upstream commit 92723ea0f11d92496687db8c9725248e9d1e5e1d ]
ASan reports memory leaks while running:
$ perf bench sched all
Fixes: e27454cc6352c422 ("perf bench: Add sched-messaging.c: Benchmark for scheduler and IPC mechanisms based on hackbench") Signed-off-by: Sohaib Mohamed sohaib.amhmd@gmail.com Acked-by: Ian Rogers irogers@google.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Hitoshi Mitake h.mitake@gmail.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Paul Russel rusty@rustcorp.com.au Cc: Peter Zijlstra peterz@infradead.org Cc: Pierre Gondois pierre.gondois@arm.com Link: http://lore.kernel.org/lkml/20211110022012.16620-1-sohaib.amhmd@gmail.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/perf/bench/sched-messaging.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/tools/perf/bench/sched-messaging.c b/tools/perf/bench/sched-messaging.c index 488f6e6ba1a55..fa0ff4ce2b749 100644 --- a/tools/perf/bench/sched-messaging.c +++ b/tools/perf/bench/sched-messaging.c @@ -223,6 +223,8 @@ static unsigned int group(pthread_t *pth, snd_ctx->out_fds[i] = fds[1]; if (!thread_mode) close(fds[0]); + + free(ctx); }
/* Now we have all the fds, fork the senders */ @@ -239,6 +241,8 @@ static unsigned int group(pthread_t *pth, for (i = 0; i < num_fds; i++) close(snd_ctx->out_fds[i]);
+ free(snd_ctx); + /* Return number of children to reap */ return num_fds * 2; }
From: Arnaldo Carvalho de Melo acme@redhat.com
[ Upstream commit e8c04ea0fef5731dbcaabac86d65254c227aedf4 ]
The patch removing the feature-sync-compare-and-swap feature detection didn't remove the call to main_test_sync_compare_and_swap(), making the 'test-all' case fail an all the feature tests to be performed individually:
$ cat /tmp/build/perf/feature/test-all.make.output In file included from test-all.c:18: test-libpython-version.c:5:10: error: #error 5 | #error | ^~~~~ test-all.c: In function ‘main’: test-all.c:203:9: error: implicit declaration of function ‘main_test_sync_compare_and_swap’ [-Werror=implicit-function-declaration] 203 | main_test_sync_compare_and_swap(argc, argv); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors $
Fix it, now to figure out what is that test-libpython-version.c problem...
Fixes: 60fa754b2a5a4e0c ("tools: Remove feature-sync-compare-and-swap feature detection") Cc: Jiri Olsa jolsa@redhat.com Cc: Leo Yan leo.yan@linaro.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Mike Leach mike.leach@linaro.org Cc: Namhyung Kim namhyung@kernel.org Link: https://lore.kernel.org/lkml/YZU9Fe0sgkHSXeC2@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/build/feature/test-all.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c index 9204395272912..0b243ce842be3 100644 --- a/tools/build/feature/test-all.c +++ b/tools/build/feature/test-all.c @@ -200,7 +200,6 @@ int main(int argc, char *argv[]) main_test_timerfd(); main_test_stackprotector_all(); main_test_libdw_dwarf_unwind(); - main_test_sync_compare_and_swap(argc, argv); main_test_zlib(); main_test_pthread_attr_setaffinity_np(); main_test_pthread_barrier();
From: Andreas Schwab schwab@suse.de
[ Upstream commit 5a19c7e06236a9c55dfc001bb4d1a8f1950d23e7 ]
When building external modules, vdso_prepare should not be run. If the kernel sources are read-only, it will fail.
Fixes: fde9c59aebaf ("riscv: explicitly use symbol offsets for VDSO") Signed-off-by: Andreas Schwab schwab@suse.de Reviewed-by: Nathan Chancellor nathan@kernel.org Tested-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/Makefile | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 0eb4568fbd290..41f3a75fe2ec8 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -108,11 +108,13 @@ PHONY += vdso_install vdso_install: $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
+ifeq ($(KBUILD_EXTMOD),) ifeq ($(CONFIG_MMU),y) prepare: vdso_prepare vdso_prepare: prepare0 $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h endif +endif
ifneq ($(CONFIG_XIP_KERNEL),y) ifeq ($(CONFIG_RISCV_M_MODE)$(CONFIG_SOC_CANAAN),yy)
From: Michael Ellerman mpe@ellerman.id.au
[ Upstream commit dae581864609d36fb58855fd59880b4941ce9d14 ]
kvmppc_h_set_dabr(), and kvmppc_h_set_xdabr() which jumps into it, need to use _GLOBAL_TOC to setup the kernel TOC pointer, because kvmppc_h_set_dabr() uses LOAD_REG_ADDR() to load dawr_force_enable.
When called from hcall_try_real_mode() we have the kernel TOC in r2, established near the start of kvmppc_interrupt_hv(), so there is no issue.
But they can also be called from kvmppc_pseries_do_hcall() which is module code, so the access ends up happening with the kvm-hv module's r2, which will not point at dawr_force_enable and could even cause a fault.
With the current code layout and compilers we haven't observed a fault in practice, the load hits somewhere in kvm-hv.ko and silently returns some bogus value.
Note that we we expect p8/p9 guests to use the DAWR, but SLOF uses h_set_dabr() to test if sc1 works correctly, see SLOF's lib/libhvcall/brokensc1.c.
Fixes: c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option") Signed-off-by: Michael Ellerman mpe@ellerman.id.au Reviewed-by: Daniel Axtens dja@axtens.net Link: https://lore.kernel.org/r/20210923151031.72408-1-mpe@ellerman.id.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index eb776d0c5d8e9..32a4b4d412b92 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -2005,7 +2005,7 @@ hcall_real_table: .globl hcall_real_table_end hcall_real_table_end:
-_GLOBAL(kvmppc_h_set_xdabr) +_GLOBAL_TOC(kvmppc_h_set_xdabr) EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) andi. r0, r5, DABRX_USER | DABRX_KERNEL beq 6f @@ -2015,7 +2015,7 @@ EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) 6: li r3, H_PARAMETER blr
-_GLOBAL(kvmppc_h_set_dabr) +_GLOBAL_TOC(kvmppc_h_set_dabr) EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr) li r5, DABRX_USER | DABRX_KERNEL 3:
From: Masahiro Yamada masahiroy@kernel.org
[ Upstream commit 964c33cd0be621b291b5d253d8731eb2680082cb ]
Since commit bce74491c300 ("powerpc/vdso: fix unnecessary rebuilds of vgettimeofday.o"), "make ARCH=powerpc clean" does not clean up the arch/powerpc/kernel/{vdso32,vdso64} directories.
Use the subdir- trick to let "make clean" descend into them.
Fixes: bce74491c300 ("powerpc/vdso: fix unnecessary rebuilds of vgettimeofday.o") Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211109185015.615517-1-masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/Makefile | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 7be36c1e1db6d..86e40db2dec56 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -196,3 +196,6 @@ clean-files := vmlinux.lds # Force dependency (incbin is bad) $(obj)/vdso32_wrapper.o : $(obj)/vdso32/vdso32.so.dbg $(obj)/vdso64_wrapper.o : $(obj)/vdso64/vdso64.so.dbg + +# for cleaning +subdir- += vdso32 vdso64
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit 0bd81274e3f1195ee7c820ef02d62f31077c42c3 ]
The name of the local variable holding the "form2" property address conflicts with the numa_distance_table global.
This patch does 's/numa_dist_table/form2_distances/g' over the function, which also renames numa_dist_table_length to form2_distances_length.
Suggested-by: Michael Ellerman mpe@ellerman.id.au Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211109064900.2041386-1-npiggin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/numa.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 6f14c8fb6359d..53e9901409163 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -376,9 +376,9 @@ static void initialize_form2_numa_distance_lookup_table(void) { int i, j; struct device_node *root; - const __u8 *numa_dist_table; + const __u8 *form2_distances; const __be32 *numa_lookup_index; - int numa_dist_table_length; + int form2_distances_length; int max_numa_index, distance_index;
if (firmware_has_feature(FW_FEATURE_OPAL)) @@ -392,20 +392,20 @@ static void initialize_form2_numa_distance_lookup_table(void) max_numa_index = of_read_number(&numa_lookup_index[0], 1);
/* first element of the array is the size and is encode-int */ - numa_dist_table = of_get_property(root, "ibm,numa-distance-table", NULL); - numa_dist_table_length = of_read_number((const __be32 *)&numa_dist_table[0], 1); + form2_distances = of_get_property(root, "ibm,numa-distance-table", NULL); + form2_distances_length = of_read_number((const __be32 *)&form2_distances[0], 1); /* Skip the size which is encoded int */ - numa_dist_table += sizeof(__be32); + form2_distances += sizeof(__be32);
- pr_debug("numa_dist_table_len = %d, numa_dist_indexes_len = %d\n", - numa_dist_table_length, max_numa_index); + pr_debug("form2_distances_len = %d, numa_dist_indexes_len = %d\n", + form2_distances_length, max_numa_index);
for (i = 0; i < max_numa_index; i++) /* +1 skip the max_numa_index in the property */ numa_id_index_table[i] = of_read_number(&numa_lookup_index[i + 1], 1);
- if (numa_dist_table_length != max_numa_index * max_numa_index) { + if (form2_distances_length != max_numa_index * max_numa_index) { WARN(1, "Wrong NUMA distance information\n"); /* consider everybody else just remote. */ for (i = 0; i < max_numa_index; i++) { @@ -427,7 +427,7 @@ static void initialize_form2_numa_distance_lookup_table(void) int nodeA = numa_id_index_table[i]; int nodeB = numa_id_index_table[j];
- numa_distance_table[nodeA][nodeB] = numa_dist_table[distance_index++]; + numa_distance_table[nodeA][nodeB] = form2_distances[distance_index++]; pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]); } }
From: Nicholas Piggin npiggin@gmail.com
[ Upstream commit 302039466f6a3b9421ecb9a6a2c528801dc24a86 ]
In case the FORM2 distance table from firmware is not the expected size, there is fallback code that just populates the lookup table as local vs remote.
However it then continues on to use the distance table. Fix.
Fixes: 1c6b5a7e7405 ("powerpc/pseries: Add support for FORM2 associativity") Signed-off-by: Nicholas Piggin npiggin@gmail.com Reviewed-by: Aneesh Kumar K.V aneesh.kumar@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211109064900.2041386-2-npiggin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/numa.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 53e9901409163..59d3cfcd78879 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -407,30 +407,26 @@ static void initialize_form2_numa_distance_lookup_table(void)
if (form2_distances_length != max_numa_index * max_numa_index) { WARN(1, "Wrong NUMA distance information\n"); - /* consider everybody else just remote. */ - for (i = 0; i < max_numa_index; i++) { - for (j = 0; j < max_numa_index; j++) { - int nodeA = numa_id_index_table[i]; - int nodeB = numa_id_index_table[j]; - - if (nodeA == nodeB) - numa_distance_table[nodeA][nodeB] = LOCAL_DISTANCE; - else - numa_distance_table[nodeA][nodeB] = REMOTE_DISTANCE; - } - } + form2_distances = NULL; // don't use it } - distance_index = 0; for (i = 0; i < max_numa_index; i++) { for (j = 0; j < max_numa_index; j++) { int nodeA = numa_id_index_table[i]; int nodeB = numa_id_index_table[j]; - - numa_distance_table[nodeA][nodeB] = form2_distances[distance_index++]; - pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, numa_distance_table[nodeA][nodeB]); + int dist; + + if (form2_distances) + dist = form2_distances[distance_index++]; + else if (nodeA == nodeB) + dist = LOCAL_DISTANCE; + else + dist = REMOTE_DISTANCE; + numa_distance_table[nodeA][nodeB] = dist; + pr_debug("dist[%d][%d]=%d ", nodeA, nodeB, dist); } } + of_node_put(root); }
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit 3a3a100473d2f6ebf9bdfe6efedd7e18de724388 ]
It has been observed that dual edge triggered wakeirq GPIOs on SDM845 doesn't trigger interrupts on the falling edge.
Enabling wakeirq_dual_edge_errata for SDM845 indicates that the PDC in SDM845 suffers from the same problem described, and worked around, by Doug in 'c3c0c2e18d94 ("pinctrl: qcom: Handle broken/missing PDC dual edge IRQs on sc7180")', so enable the workaround for SDM845 as well.
The specific problem seen without this is that gpio-keys does not detect the falling edge of the LID gpio on the Lenovo Yoga C630 and as such consistently reports the LID as closed.
Fixes: e35a6ae0eb3a ("pinctrl/msm: Setup GPIO chip in hierarchy") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Tested-By: Steev Klimaszewski steev@kali.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/20211102034115.1946036-1-bjorn.andersson@linaro.or... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/qcom/pinctrl-sdm845.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c index c51793f6546f1..fdfd7b8f3a76d 100644 --- a/drivers/pinctrl/qcom/pinctrl-sdm845.c +++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c @@ -1310,6 +1310,7 @@ static const struct msm_pinctrl_soc_data sdm845_pinctrl = { .ngpios = 151, .wakeirq_map = sdm845_pdc_map, .nwakeirq_map = ARRAY_SIZE(sdm845_pdc_map), + .wakeirq_dual_edge_errata = true, };
static const struct msm_pinctrl_soc_data sdm845_acpi_pinctrl = {
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit 62209e805b5c68577602a5803a71d8e2e11ee0d3 ]
The downstream TLMM binding covers a group of TLMM-related hardware blocks, but the upstream binding only captures the particular block related to controlling the TLMM pins from an OS. In the translation of the driver from downstream, the offset of 0x100000 was lost for the UFS and SDC pingroups.
Fixes: d5d348a3271f ("pinctrl: qcom: Add SM8350 pinctrl driver") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Vinod Koul vkoul@kernel.org Reviewed-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Link: https://lore.kernel.org/r/20211104170835.1993686-1-bjorn.andersson@linaro.or... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/qcom/pinctrl-sm8350.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/qcom/pinctrl-sm8350.c b/drivers/pinctrl/qcom/pinctrl-sm8350.c index 4d8f8636c2b39..1c042d39380c6 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm8350.c +++ b/drivers/pinctrl/qcom/pinctrl-sm8350.c @@ -1597,10 +1597,10 @@ static const struct msm_pingroup sm8350_groups[] = { [200] = PINGROUP(200, qdss_gpio, _, _, _, _, _, _, _, _), [201] = PINGROUP(201, _, _, _, _, _, _, _, _, _), [202] = PINGROUP(202, _, _, _, _, _, _, _, _, _), - [203] = UFS_RESET(ufs_reset, 0x1d8000), - [204] = SDC_PINGROUP(sdc2_clk, 0x1cf000, 14, 6), - [205] = SDC_PINGROUP(sdc2_cmd, 0x1cf000, 11, 3), - [206] = SDC_PINGROUP(sdc2_data, 0x1cf000, 9, 0), + [203] = UFS_RESET(ufs_reset, 0xd8000), + [204] = SDC_PINGROUP(sdc2_clk, 0xcf000, 14, 6), + [205] = SDC_PINGROUP(sdc2_cmd, 0xcf000, 11, 3), + [206] = SDC_PINGROUP(sdc2_data, 0xcf000, 9, 0), };
static const struct msm_gpio_wakeirq_map sm8350_pdc_map[] = {
From: Alexander Antonov alexander.antonov@linux.intel.com
[ Upstream commit e324234e0aa881b7841c7c713306403e12b069ff ]
According Uncore Reference Manual: any of the CHA events may be filtered by Thread/Core-ID by using tid modifier in CHA Filter 0 Register. Update skx_cha_hw_config() to follow Uncore Guide.
Fixes: cd34cd97b7b4 ("perf/x86/intel/uncore: Add Skylake server uncore support") Signed-off-by: Alexander Antonov alexander.antonov@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kan Liang kan.liang@linux.intel.com Link: https://lore.kernel.org/r/20211115090334.3789-2-alexander.antonov@linux.inte... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/uncore_snbep.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index eb2c6cea9d0d5..e5ee6bb62ef50 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3608,6 +3608,9 @@ static int skx_cha_hw_config(struct intel_uncore_box *box, struct perf_event *ev struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; struct extra_reg *er; int idx = 0; + /* Any of the CHA events may be filtered by Thread/Core-ID.*/ + if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN) + idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID;
for (er = skx_uncore_cha_extra_regs; er->msr; er++) { if (er->event != (event->hw.config & er->config_mask))
From: Alexander Antonov alexander.antonov@linux.intel.com
[ Upstream commit 3866ae319c846a612109c008f43cba80b8c15e86 ]
According to the latest uncore document, COMP_BUF_OCCUPANCY (0xd5) event can be collected on 2-3 counters. Update uncore IIO event constraints for Skylake Server.
Fixes: cd34cd97b7b4 ("perf/x86/intel/uncore: Add Skylake server uncore support") Signed-off-by: Alexander Antonov alexander.antonov@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kan Liang kan.liang@linux.intel.com Link: https://lore.kernel.org/r/20211115090334.3789-3-alexander.antonov@linux.inte... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/uncore_snbep.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index e5ee6bb62ef50..9aba4ef77b13b 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3678,6 +3678,7 @@ static struct event_constraint skx_uncore_iio_constraints[] = { UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), UNCORE_EVENT_CONSTRAINT(0xd4, 0xc), + UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), EVENT_CONSTRAINT_END };
From: Alexander Antonov alexander.antonov@linux.intel.com
[ Upstream commit bdc0feee05174418dec1fa68de2af19e1750b99f ]
According to the latest uncore document, DATA_REQ_OF_CPU (0x83), DATA_REQ_BY_CPU (0xc0) and COMP_BUF_OCCUPANCY (0xd5) events have constraints. Add uncore IIO constraints for Snowridge.
Fixes: 210cc5f9db7a ("perf/x86/intel/uncore: Add uncore support for Snow Ridge server") Signed-off-by: Alexander Antonov alexander.antonov@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kan Liang kan.liang@linux.intel.com Link: https://lore.kernel.org/r/20211115090334.3789-4-alexander.antonov@linux.inte... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/uncore_snbep.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 9aba4ef77b13b..3660f698fb2aa 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -4529,6 +4529,13 @@ static void snr_iio_cleanup_mapping(struct intel_uncore_type *type) pmu_iio_cleanup_mapping(type, &snr_iio_mapping_group); }
+static struct event_constraint snr_uncore_iio_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x83, 0x3), + UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), + UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), + EVENT_CONSTRAINT_END +}; + static struct intel_uncore_type snr_uncore_iio = { .name = "iio", .num_counters = 4, @@ -4540,6 +4547,7 @@ static struct intel_uncore_type snr_uncore_iio = { .event_mask_ext = SNR_IIO_PMON_RAW_EVENT_MASK_EXT, .box_ctl = SNR_IIO_MSR_PMON_BOX_CTL, .msr_offset = SNR_IIO_MSR_OFFSET, + .constraints = snr_uncore_iio_constraints, .ops = &ivbep_uncore_msr_ops, .format_group = &snr_uncore_iio_format_group, .attr_update = snr_iio_attr_update,
From: Heiko Carstens hca@linux.ibm.com
[ Upstream commit 20c76e242e7025bd355619ba67beb243ba1a1e95 ]
kexec_file_add_ipl_report ignores that ipl_report_finish may fail and can return an error pointer instead of a valid pointer. Fix this and simplify by returning NULL in case of an error and let the only caller handle this case.
Fixes: 99feaa717e55 ("s390/kexec_file: Create ipl report and pass to next kernel") Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/ipl.c | 3 ++- arch/s390/kernel/machine_kexec_file.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index e2cc35775b996..5ad1dde23dc59 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2156,7 +2156,7 @@ void *ipl_report_finish(struct ipl_report *report)
buf = vzalloc(report->size); if (!buf) - return ERR_PTR(-ENOMEM); + goto out; ptr = buf;
memcpy(ptr, report->ipib, report->ipib->hdr.len); @@ -2195,6 +2195,7 @@ void *ipl_report_finish(struct ipl_report *report) }
BUG_ON(ptr > buf + report->size); +out: return buf; }
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index f9e4baa64b675..c1090f0b1f6a6 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -170,6 +170,7 @@ static int kexec_file_add_ipl_report(struct kimage *image, struct kexec_buf buf; unsigned long addr; void *ptr, *end; + int ret;
buf.image = image;
@@ -199,7 +200,10 @@ static int kexec_file_add_ipl_report(struct kimage *image, ptr += len; }
+ ret = -ENOMEM; buf.buffer = ipl_report_finish(data->report); + if (!buf.buffer) + goto out; buf.bufsz = data->report->size; buf.memsz = buf.bufsz;
@@ -209,7 +213,9 @@ static int kexec_file_add_ipl_report(struct kimage *image, data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr); *lc_ipl_parmblock_ptr = (__u32)buf.mem;
- return kexec_add_buffer(&buf); + ret = kexec_add_buffer(&buf); +out: + return ret; }
void *kexec_file_add_components(struct kimage *image,
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 15c30104965101b8e76b24d27035569d6613a7d6 ]
If blk_queue_enter() failed due to queue is dying, the blkdev_put_no_open() is needed because blkcg_conf_open_bdev() succeeded.
Fixes: 0c9d338c8443 ("blk-cgroup: synchronize blkg creation against policy deactivation") Signed-off-by: Yu Kuai yukuai3@huawei.com Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20211102020705.2321858-1-yukuai3@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-cgroup.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index ebff1af402e5b..0eec59e4df65c 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -639,7 +639,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, */ ret = blk_queue_enter(q, 0); if (ret) - return ret; + goto fail;
rcu_read_lock(); spin_lock_irq(&q->queue_lock); @@ -675,13 +675,13 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, new_blkg = blkg_alloc(pos, q, GFP_KERNEL); if (unlikely(!new_blkg)) { ret = -ENOMEM; - goto fail; + goto fail_exit_queue; }
if (radix_tree_preload(GFP_KERNEL)) { blkg_free(new_blkg); ret = -ENOMEM; - goto fail; + goto fail_exit_queue; }
rcu_read_lock(); @@ -721,9 +721,10 @@ fail_preloaded: fail_unlock: spin_unlock_irq(&q->queue_lock); rcu_read_unlock(); +fail_exit_queue: + blk_queue_exit(q); fail: blkdev_put_no_open(bdev); - blk_queue_exit(q); /* * If queue was bypassing, we should retry. Do so after a * short msleep(). It isn't strictly necessary but queue
From: Arnd Bergmann arnd@arndb.de
commit b3b180e735409ca0c76642014304b59482e0e653 upstream.
The ptdma driver has added debugfs support, but this fails to build when debugfs is disabled:
drivers/dma/ptdma/ptdma-debugfs.c: In function 'ptdma_debugfs_setup': drivers/dma/ptdma/ptdma-debugfs.c:93:54: error: 'struct dma_device' has no member named 'dbg_dev_root' 93 | debugfs_create_file("info", 0400, pt->dma_dev.dbg_dev_root, pt, | ^ drivers/dma/ptdma/ptdma-debugfs.c:96:55: error: 'struct dma_device' has no member named 'dbg_dev_root' 96 | debugfs_create_file("stats", 0400, pt->dma_dev.dbg_dev_root, pt, | ^ drivers/dma/ptdma/ptdma-debugfs.c:102:52: error: 'struct dma_device' has no member named 'dbg_dev_root' 102 | debugfs_create_dir("q", pt->dma_dev.dbg_dev_root); | ^
Remove the #ifdef in the header, as this only saves a few bytes, but would require ugly #ifdefs in each driver using it. Simplify the other user while we're at it.
Fixes: e2fb2e2a33fa ("dmaengine: ptdma: Add debugfs entries for PTDMA") Fixes: 26cf132de6f7 ("dmaengine: Create debug directories for DMA devices") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Link: https://lore.kernel.org/r/20210920122017.205975-1-arnd@kernel.org Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/xilinx/xilinx_dpdma.c | 15 +-------------- include/linux/dmaengine.h | 2 -- 2 files changed, 1 insertion(+), 16 deletions(-)
--- a/drivers/dma/xilinx/xilinx_dpdma.c +++ b/drivers/dma/xilinx/xilinx_dpdma.c @@ -271,9 +271,6 @@ struct xilinx_dpdma_device { /* ----------------------------------------------------------------------------- * DebugFS */ - -#ifdef CONFIG_DEBUG_FS - #define XILINX_DPDMA_DEBUGFS_READ_MAX_SIZE 32 #define XILINX_DPDMA_DEBUGFS_UINT16_MAX_STR "65535"
@@ -299,7 +296,7 @@ struct xilinx_dpdma_debugfs_request {
static void xilinx_dpdma_debugfs_desc_done_irq(struct xilinx_dpdma_chan *chan) { - if (chan->id == dpdma_debugfs.chan_id) + if (IS_ENABLED(CONFIG_DEBUG_FS) && chan->id == dpdma_debugfs.chan_id) dpdma_debugfs.xilinx_dpdma_irq_done_count++; }
@@ -462,16 +459,6 @@ static void xilinx_dpdma_debugfs_init(st dev_err(xdev->dev, "Failed to create debugfs testcase file\n"); }
-#else -static void xilinx_dpdma_debugfs_init(struct xilinx_dpdma_device *xdev) -{ -} - -static void xilinx_dpdma_debugfs_desc_done_irq(struct xilinx_dpdma_chan *chan) -{ -} -#endif /* CONFIG_DEBUG_FS */ - /* ----------------------------------------------------------------------------- * I/O Accessors */ --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -944,10 +944,8 @@ struct dma_device { void (*device_issue_pending)(struct dma_chan *chan); void (*device_release)(struct dma_device *dev); /* debugfs support */ -#ifdef CONFIG_DEBUG_FS void (*dbg_summary_show)(struct seq_file *s, struct dma_device *dev); struct dentry *dbg_dev_root; -#endif };
static inline int dmaengine_slave_config(struct dma_chan *chan,
From: Nicolas Dichtel nicolas.dichtel@6wind.com
commit a31d27fbed5d518734cb60956303eb15089a7634 upstream.
As stated in the bonding doc, trans_start must be set manually for drivers using NETIF_F_LLTX: Drivers that use NETIF_F_LLTX flag must also update netdev_queue->trans_start. If they do not, then the ARP monitor will immediately fail any slaves using that driver, and those slaves will stay down.
Link: https://www.kernel.org/doc/html/v5.15/networking/bonding.html#arp-monitor-op... Signed-off-by: Nicolas Dichtel nicolas.dichtel@6wind.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/tun.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1010,6 +1010,7 @@ static netdev_tx_t tun_net_xmit(struct s { struct tun_struct *tun = netdev_priv(dev); int txq = skb->queue_mapping; + struct netdev_queue *queue; struct tun_file *tfile; int len = skb->len;
@@ -1054,6 +1055,10 @@ static netdev_tx_t tun_net_xmit(struct s if (ptr_ring_produce(&tfile->tx_ring, skb)) goto drop;
+ /* NETIF_F_LLTX requires to do our own update of trans_start */ + queue = netdev_get_tx_queue(dev, txq); + queue->trans_start = jiffies; + /* Notify and wake up reader process */ if (tfile->flags & TUN_FASYNC) kill_fasync(&tfile->fasync, SIGIO, POLL_IN);
From: Kees Cook keescook@chromium.org
commit d1faacbf67b1944f0e0c618dc581d929263f6fe9 upstream.
This reverts commit d07f3b081ee632268786601f55e1334d1f68b997.
pstore-blk was fixed to avoid the unwanted APIs in commit 7bb9557b48fc ("pstore/blk: Use the normal block device I/O path"), which landed in the same release as the commit adding BROKEN.
Cc: Jens Axboe axboe@kernel.dk Cc: Christoph Hellwig hch@lst.de Cc: stable@vger.kernel.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20211116181559.3975566-1-keescook@chromium.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/pstore/Kconfig | 1 - 1 file changed, 1 deletion(-)
--- a/fs/pstore/Kconfig +++ b/fs/pstore/Kconfig @@ -173,7 +173,6 @@ config PSTORE_BLK tristate "Log panic/oops to a block device" depends on PSTORE depends on BLOCK - depends on BROKEN select PSTORE_ZONE default n help
From: Geert Uytterhoeven geert@linux-m68k.org
commit 61eb495c83bf6ebde490992bf888ca15b9babc39 upstream.
On 32-bit:
fs/pstore/blk.c: In function ‘__best_effort_init’: include/linux/kern_levels.h:5:18: warning: format ‘%zu’ expects argument of type ‘size_t’, but argument 3 has type ‘long unsigned int’ [-Wformat=] 5 | #define KERN_SOH "\001" /* ASCII Start Of Header */ | ^~~~~~ include/linux/kern_levels.h:14:19: note: in expansion of macro ‘KERN_SOH’ 14 | #define KERN_INFO KERN_SOH "6" /* informational */ | ^~~~~~~~ include/linux/printk.h:373:9: note: in expansion of macro ‘KERN_INFO’ 373 | printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~ fs/pstore/blk.c:314:3: note: in expansion of macro ‘pr_info’ 314 | pr_info("attached %s (%zu) (no dedicated panic_write!)\n", | ^~~~~~~
Cc: stable@vger.kernel.org Fixes: 7bb9557b48fcabaa ("pstore/blk: Use the normal block device I/O path") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20210629103700.1935012-1-geert@linux-m68k.org Cc: Jens Axboe axboe@kernel.dk Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/pstore/blk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/pstore/blk.c +++ b/fs/pstore/blk.c @@ -311,7 +311,7 @@ static int __init __best_effort_init(voi if (ret) kfree(best_effort_dev); else - pr_info("attached %s (%zu) (no dedicated panic_write!)\n", + pr_info("attached %s (%lu) (no dedicated panic_write!)\n", blkdev, best_effort_dev->zone.total_size);
return ret;
From: Nathan Chancellor nathan@kernel.org
commit ffb92ce826fd801acb0f4e15b75e4ddf0d189bde upstream.
Patch series "Fixes for ARCH=hexagon allmodconfig", v2.
This series fixes some issues noticed with ARCH=hexagon allmodconfig.
This patch (of 3):
When building ARCH=hexagon allmodconfig, the following errors occur:
ERROR: modpost: "__raw_readsl" [drivers/i3c/master/svc-i3c-master.ko] undefined! ERROR: modpost: "__raw_writesl" [drivers/i3c/master/dw-i3c-master.ko] undefined! ERROR: modpost: "__raw_readsl" [drivers/i3c/master/dw-i3c-master.ko] undefined! ERROR: modpost: "__raw_writesl" [drivers/i3c/master/i3c-master-cdns.ko] undefined! ERROR: modpost: "__raw_readsl" [drivers/i3c/master/i3c-master-cdns.ko] undefined!
Export these symbols so that modules can use them without any errors.
Link: https://lkml.kernel.org/r/20211115174250.1994179-1-nathan@kernel.org Link: https://lkml.kernel.org/r/20211115174250.1994179-2-nathan@kernel.org Fixes: 013bf24c3829 ("Hexagon: Provide basic implementation and/or stubs for I/O routines.") Signed-off-by: Nathan Chancellor nathan@kernel.org Acked-by: Brian Cain bcain@codeaurora.org Cc: Nick Desaulniers ndesaulniers@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/hexagon/lib/io.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/arch/hexagon/lib/io.c +++ b/arch/hexagon/lib/io.c @@ -27,6 +27,7 @@ void __raw_readsw(const void __iomem *ad *dst++ = *src;
} +EXPORT_SYMBOL(__raw_readsw);
/* * __raw_writesw - read words a short at a time @@ -47,6 +48,7 @@ void __raw_writesw(void __iomem *addr, c
} +EXPORT_SYMBOL(__raw_writesw);
/* Pretty sure len is pre-adjusted for the length of the access already */ void __raw_readsl(const void __iomem *addr, void *data, int len) @@ -62,6 +64,7 @@ void __raw_readsl(const void __iomem *ad
} +EXPORT_SYMBOL(__raw_readsl);
void __raw_writesl(void __iomem *addr, const void *data, int len) { @@ -76,3 +79,4 @@ void __raw_writesl(void __iomem *addr, c
} +EXPORT_SYMBOL(__raw_writesl);
From: Nathan Chancellor nathan@kernel.org
commit 51f2ec593441d3d1ebc0d478fac3ea329c7c93ac upstream.
When building allmodconfig, there is a warning about TIMER_ENABLE being redefined:
drivers/clocksource/timer-oxnas-rps.c:39:9: error: 'TIMER_ENABLE' macro redefined [-Werror,-Wmacro-redefined] #define TIMER_ENABLE BIT(7) ^ arch/hexagon/include/asm/timer-regs.h:13:9: note: previous definition is here #define TIMER_ENABLE 0 ^ 1 error generated.
The values in this header are only used in one file each, if they are used at all. Remove the header and sink all of the constants into their respective files.
TCX0_CLK_RATE is only used in arch/hexagon/include/asm/timex.h
TIMER_ENABLE, RTOS_TIMER_INT, RTOS_TIMER_REGS_ADDR are only used in arch/hexagon/kernel/time.c.
SLEEP_CLK_RATE and TIMER_CLR_ON_MATCH have both been unused since the file's introduction in commit 71e4a47f32f4 ("Hexagon: Add time and timer functions").
TIMER_ENABLE is redefined as BIT(0) so the shift is moved into the definition, rather than its use.
Link: https://lkml.kernel.org/r/20211115174250.1994179-3-nathan@kernel.org Signed-off-by: Nathan Chancellor nathan@kernel.org Acked-by: Brian Cain bcain@codeaurora.org Cc: Nick Desaulniers ndesaulniers@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/hexagon/include/asm/timer-regs.h | 26 -------------------------- arch/hexagon/include/asm/timex.h | 3 +-- arch/hexagon/kernel/time.c | 12 ++++++++++-- 3 files changed, 11 insertions(+), 30 deletions(-) delete mode 100644 arch/hexagon/include/asm/timer-regs.h
--- a/arch/hexagon/include/asm/timer-regs.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Timer support for Hexagon - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - */ - -#ifndef _ASM_TIMER_REGS_H -#define _ASM_TIMER_REGS_H - -/* This stuff should go into a platform specific file */ -#define TCX0_CLK_RATE 19200 -#define TIMER_ENABLE 0 -#define TIMER_CLR_ON_MATCH 1 - -/* - * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until - * release 1.1, and then it's "adjustable" and probably not defaulted. - */ -#define RTOS_TIMER_INT 3 -#ifdef CONFIG_HEXAGON_COMET -#define RTOS_TIMER_REGS_ADDR 0xAB000000UL -#endif -#define SLEEP_CLK_RATE 32000 - -#endif --- a/arch/hexagon/include/asm/timex.h +++ b/arch/hexagon/include/asm/timex.h @@ -7,11 +7,10 @@ #define _ASM_TIMEX_H
#include <asm-generic/timex.h> -#include <asm/timer-regs.h> #include <asm/hexagon_vm.h>
/* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */ -#define CLOCK_TICK_RATE TCX0_CLK_RATE +#define CLOCK_TICK_RATE 19200
#define ARCH_HAS_READ_CURRENT_TIMER
--- a/arch/hexagon/kernel/time.c +++ b/arch/hexagon/kernel/time.c @@ -17,9 +17,10 @@ #include <linux/of_irq.h> #include <linux/module.h>
-#include <asm/timer-regs.h> #include <asm/hexagon_vm.h>
+#define TIMER_ENABLE BIT(0) + /* * For the clocksource we need: * pcycle frequency (600MHz) @@ -33,6 +34,13 @@ cycles_t pcycle_freq_mhz; cycles_t thread_freq_mhz; cycles_t sleep_clk_freq;
+/* + * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until + * release 1.1, and then it's "adjustable" and probably not defaulted. + */ +#define RTOS_TIMER_INT 3 +#define RTOS_TIMER_REGS_ADDR 0xAB000000UL + static struct resource rtos_timer_resources[] = { { .start = RTOS_TIMER_REGS_ADDR, @@ -80,7 +88,7 @@ static int set_next_event(unsigned long iowrite32(0, &rtos_timer->clear);
iowrite32(delta, &rtos_timer->match); - iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable); + iowrite32(TIMER_ENABLE, &rtos_timer->enable); return 0; }
From: Tadeusz Struk tadeusz.struk@linaro.org
commit 3e6db079751afd527bf3db32314ae938dc571916 upstream.
kmemdup can return a null pointer so need to check for it, otherwise the null key will be dereferenced later in tipc_crypto_key_xmit as can be seen in the trace [1].
Cc: tipc-discussion@lists.sourceforge.net Cc: stable@vger.kernel.org # 5.15, 5.14, 5.10
[1] https://syzkaller.appspot.com/bug?id=bca180abb29567b189efdbdb34cbf7ba851c2a5...
Reported-by: Dmitry Vyukov dvyukov@google.com Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org Acked-by: Ying Xue ying.xue@windriver.com Acked-by: Jon Maloy jmaloy@redhat.com Link: https://lore.kernel.org/r/20211115160143.5099-1-tadeusz.struk@linaro.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/tipc/crypto.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -597,6 +597,10 @@ static int tipc_aead_init(struct tipc_ae tmp->cloned = NULL; tmp->authsize = TIPC_AES_GCM_TAG_SIZE; tmp->key = kmemdup(ukey, tipc_aead_key_size(ukey), GFP_KERNEL); + if (!tmp->key) { + tipc_aead_free(&tmp->rcu); + return -ENOMEM; + } memcpy(&tmp->salt, ukey->key + keylen, TIPC_AES_GCM_SALT_SIZE); atomic_set(&tmp->users, 0); atomic64_set(&tmp->seqno, 0);
From: Alexander Mikhalitsyn alexander.mikhalitsyn@virtuozzo.com
commit 126e8bee943e9926238c891e2df5b5573aee76bc upstream.
Patch series "shm: shm_rmid_forced feature fixes".
Some time ago I met kernel crash after CRIU restore procedure, fortunately, it was CRIU restore, so, I had dump files and could do restore many times and crash reproduced easily. After some investigation I've constructed the minimal reproducer. It was found that it's use-after-free and it happens only if sysctl kernel.shm_rmid_forced = 1.
The key of the problem is that the exit_shm() function not handles shp's object destroy when task->sysvshm.shm_clist contains items from different IPC namespaces. In most cases this list will contain only items from one IPC namespace.
How can this list contain object from different namespaces? The exit_shm() function is designed to clean up this list always when process leaves IPC namespace. But we made a mistake a long time ago and did not add a exit_shm() call into the setns() syscall procedures.
The first idea was just to add this call to setns() syscall but it obviously changes semantics of setns() syscall and that's userspace-visible change. So, I gave up on this idea.
The first real attempt to address the issue was just to omit forced destroy if we meet shp object not from current task IPC namespace [1]. But that was not the best idea because task->sysvshm.shm_clist was protected by rwsem which belongs to current task IPC namespace. It means that list corruption may occur.
Second approach is just extend exit_shm() to properly handle shp's from different IPC namespaces [2]. This is really non-trivial thing, I've put a lot of effort into that but not believed that it's possible to make it fully safe, clean and clear.
Thanks to the efforts of Manfred Spraul working an elegant solution was designed. Thanks a lot, Manfred!
Eric also suggested the way to address the issue in ("[RFC][PATCH] shm: In shm_exit destroy all created and never attached segments") Eric's idea was to maintain a list of shm_clists one per IPC namespace, use lock-less lists. But there is some extra memory consumption-related concerns.
An alternative solution which was suggested by me was implemented in ("shm: reset shm_clist on setns but omit forced shm destroy"). The idea is pretty simple, we add exit_shm() syscall to setns() but DO NOT destroy shm segments even if sysctl kernel.shm_rmid_forced = 1, we just clean up the task->sysvshm.shm_clist list.
This chages semantics of setns() syscall a little bit but in comparision to the "naive" solution when we just add exit_shm() without any special exclusions this looks like a safer option.
[1] https://lkml.org/lkml/2021/7/6/1108 [2] https://lkml.org/lkml/2021/7/14/736
This patch (of 2):
Let's produce a warning if we trying to remove non-existing IPC object from IPC namespace kht/idr structures.
This allows us to catch possible bugs when the ipc_rmid() function was called with inconsistent struct ipc_ids*, struct kern_ipc_perm* arguments.
Link: https://lkml.kernel.org/r/20211027224348.611025-1-alexander.mikhalitsyn@virt... Link: https://lkml.kernel.org/r/20211027224348.611025-2-alexander.mikhalitsyn@virt... Co-developed-by: Manfred Spraul manfred@colorfullife.com Signed-off-by: Manfred Spraul manfred@colorfullife.com Signed-off-by: Alexander Mikhalitsyn alexander.mikhalitsyn@virtuozzo.com Cc: "Eric W. Biederman" ebiederm@xmission.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: Greg KH gregkh@linuxfoundation.org Cc: Andrei Vagin avagin@gmail.com Cc: Pavel Tikhomirov ptikhomirov@virtuozzo.com Cc: Vasily Averin vvs@virtuozzo.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- ipc/util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/ipc/util.c +++ b/ipc/util.c @@ -447,8 +447,8 @@ static int ipcget_public(struct ipc_name static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) { if (ipcp->key != IPC_PRIVATE) - rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, - ipc_kht_params); + WARN_ON_ONCE(rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, + ipc_kht_params)); }
/** @@ -498,7 +498,7 @@ void ipc_rmid(struct ipc_ids *ids, struc { int idx = ipcid_to_idx(ipcp->id);
- idr_remove(&ids->ipcs_idr, idx); + WARN_ON_ONCE(idr_remove(&ids->ipcs_idr, idx) != ipcp); ipc_kht_remove(ids, ipcp); ids->in_use--; ipcp->deleted = true;
From: Alexander Mikhalitsyn alexander.mikhalitsyn@virtuozzo.com
commit 85b6d24646e4125c591639841169baa98a2da503 upstream.
Currently, the exit_shm() function not designed to work properly when task->sysvshm.shm_clist holds shm objects from different IPC namespaces.
This is a real pain when sysctl kernel.shm_rmid_forced = 1, because it leads to use-after-free (reproducer exists).
This is an attempt to fix the problem by extending exit_shm mechanism to handle shm's destroy from several IPC ns'es.
To achieve that we do several things:
1. add a namespace (non-refcounted) pointer to the struct shmid_kernel
2. during new shm object creation (newseg()/shmget syscall) we initialize this pointer by current task IPC ns
3. exit_shm() fully reworked such that it traverses over all shp's in task->sysvshm.shm_clist and gets IPC namespace not from current task as it was before but from shp's object itself, then call shm_destroy(shp, ns).
Note: We need to be really careful here, because as it was said before (1), our pointer to IPC ns non-refcnt'ed. To be on the safe side we using special helper get_ipc_ns_not_zero() which allows to get IPC ns refcounter only if IPC ns not in the "state of destruction".
Q/A
Q: Why can we access shp->ns memory using non-refcounted pointer? A: Because shp object lifetime is always shorther than IPC namespace lifetime, so, if we get shp object from the task->sysvshm.shm_clist while holding task_lock(task) nobody can steal our namespace.
Q: Does this patch change semantics of unshare/setns/clone syscalls? A: No. It's just fixes non-covered case when process may leave IPC namespace without getting task->sysvshm.shm_clist list cleaned up.
Link: https://lkml.kernel.org/r/67bb03e5-f79c-1815-e2bf-949c67047418@colorfullife.... Link: https://lkml.kernel.org/r/20211109151501.4921-1-manfred@colorfullife.com Fixes: ab602f79915 ("shm: make exit_shm work proportional to task activity") Co-developed-by: Manfred Spraul manfred@colorfullife.com Signed-off-by: Manfred Spraul manfred@colorfullife.com Signed-off-by: Alexander Mikhalitsyn alexander.mikhalitsyn@virtuozzo.com Cc: "Eric W. Biederman" ebiederm@xmission.com Cc: Davidlohr Bueso dave@stgolabs.net Cc: Greg KH gregkh@linuxfoundation.org Cc: Andrei Vagin avagin@gmail.com Cc: Pavel Tikhomirov ptikhomirov@virtuozzo.com Cc: Vasily Averin vvs@virtuozzo.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/ipc_namespace.h | 15 +++ include/linux/sched/task.h | 2 ipc/shm.c | 189 +++++++++++++++++++++++++++++++----------- 3 files changed, 159 insertions(+), 47 deletions(-)
--- a/include/linux/ipc_namespace.h +++ b/include/linux/ipc_namespace.h @@ -131,6 +131,16 @@ static inline struct ipc_namespace *get_ return ns; }
+static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns) +{ + if (ns) { + if (refcount_inc_not_zero(&ns->ns.count)) + return ns; + } + + return NULL; +} + extern void put_ipc_ns(struct ipc_namespace *ns); #else static inline struct ipc_namespace *copy_ipcs(unsigned long flags, @@ -146,6 +156,11 @@ static inline struct ipc_namespace *get_ { return ns; } + +static inline struct ipc_namespace *get_ipc_ns_not_zero(struct ipc_namespace *ns) +{ + return ns; +}
static inline void put_ipc_ns(struct ipc_namespace *ns) { --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -158,7 +158,7 @@ static inline struct vm_struct *task_sta * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also * pins the final release of task.io_context. Also protects ->cpuset and - * ->cgroup.subsys[]. And ->vfork_done. + * ->cgroup.subsys[]. And ->vfork_done. And ->sysvshm.shm_clist. * * Nests both inside and outside of read_lock(&tasklist_lock). * It must not be nested with write_lock_irq(&tasklist_lock), --- a/ipc/shm.c +++ b/ipc/shm.c @@ -62,9 +62,18 @@ struct shmid_kernel /* private to the ke struct pid *shm_lprid; struct ucounts *mlock_ucounts;
- /* The task created the shm object. NULL if the task is dead. */ + /* + * The task created the shm object, for + * task_lock(shp->shm_creator) + */ struct task_struct *shm_creator; - struct list_head shm_clist; /* list by creator */ + + /* + * List by creator. task_lock(->shm_creator) required for read/write. + * If list_empty(), then the creator is dead already. + */ + struct list_head shm_clist; + struct ipc_namespace *ns; } __randomize_layout;
/* shm_mode upper byte flags */ @@ -115,6 +124,7 @@ static void do_shm_rmid(struct ipc_names struct shmid_kernel *shp;
shp = container_of(ipcp, struct shmid_kernel, shm_perm); + WARN_ON(ns != shp->ns);
if (shp->shm_nattch) { shp->shm_perm.mode |= SHM_DEST; @@ -225,10 +235,43 @@ static void shm_rcu_free(struct rcu_head kfree(shp); }
-static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) +/* + * It has to be called with shp locked. + * It must be called before ipc_rmid() + */ +static inline void shm_clist_rm(struct shmid_kernel *shp) +{ + struct task_struct *creator; + + /* ensure that shm_creator does not disappear */ + rcu_read_lock(); + + /* + * A concurrent exit_shm may do a list_del_init() as well. + * Just do nothing if exit_shm already did the work + */ + if (!list_empty(&shp->shm_clist)) { + /* + * shp->shm_creator is guaranteed to be valid *only* + * if shp->shm_clist is not empty. + */ + creator = shp->shm_creator; + + task_lock(creator); + /* + * list_del_init() is a nop if the entry was already removed + * from the list. + */ + list_del_init(&shp->shm_clist); + task_unlock(creator); + } + rcu_read_unlock(); +} + +static inline void shm_rmid(struct shmid_kernel *s) { - list_del(&s->shm_clist); - ipc_rmid(&shm_ids(ns), &s->shm_perm); + shm_clist_rm(s); + ipc_rmid(&shm_ids(s->ns), &s->shm_perm); }
@@ -283,7 +326,7 @@ static void shm_destroy(struct ipc_names shm_file = shp->shm_file; shp->shm_file = NULL; ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; - shm_rmid(ns, shp); + shm_rmid(shp); shm_unlock(shp); if (!is_file_hugepages(shm_file)) shmem_lock(shm_file, 0, shp->mlock_ucounts); @@ -306,10 +349,10 @@ static void shm_destroy(struct ipc_names * * 2) sysctl kernel.shm_rmid_forced is set to 1. */ -static bool shm_may_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) +static bool shm_may_destroy(struct shmid_kernel *shp) { return (shp->shm_nattch == 0) && - (ns->shm_rmid_forced || + (shp->ns->shm_rmid_forced || (shp->shm_perm.mode & SHM_DEST)); }
@@ -340,7 +383,7 @@ static void shm_close(struct vm_area_str ipc_update_pid(&shp->shm_lprid, task_tgid(current)); shp->shm_dtim = ktime_get_real_seconds(); shp->shm_nattch--; - if (shm_may_destroy(ns, shp)) + if (shm_may_destroy(shp)) shm_destroy(ns, shp); else shm_unlock(shp); @@ -361,10 +404,10 @@ static int shm_try_destroy_orphaned(int * * As shp->* are changed under rwsem, it's safe to skip shp locking. */ - if (shp->shm_creator != NULL) + if (!list_empty(&shp->shm_clist)) return 0;
- if (shm_may_destroy(ns, shp)) { + if (shm_may_destroy(shp)) { shm_lock_by_ptr(shp); shm_destroy(ns, shp); } @@ -382,48 +425,97 @@ void shm_destroy_orphaned(struct ipc_nam /* Locking assumes this will only be called with task == current */ void exit_shm(struct task_struct *task) { - struct ipc_namespace *ns = task->nsproxy->ipc_ns; - struct shmid_kernel *shp, *n; + for (;;) { + struct shmid_kernel *shp; + struct ipc_namespace *ns;
- if (list_empty(&task->sysvshm.shm_clist)) - return; + task_lock(task); + + if (list_empty(&task->sysvshm.shm_clist)) { + task_unlock(task); + break; + } + + shp = list_first_entry(&task->sysvshm.shm_clist, struct shmid_kernel, + shm_clist);
- /* - * If kernel.shm_rmid_forced is not set then only keep track of - * which shmids are orphaned, so that a later set of the sysctl - * can clean them up. - */ - if (!ns->shm_rmid_forced) { - down_read(&shm_ids(ns).rwsem); - list_for_each_entry(shp, &task->sysvshm.shm_clist, shm_clist) - shp->shm_creator = NULL; /* - * Only under read lock but we are only called on current - * so no entry on the list will be shared. + * 1) Get pointer to the ipc namespace. It is worth to say + * that this pointer is guaranteed to be valid because + * shp lifetime is always shorter than namespace lifetime + * in which shp lives. + * We taken task_lock it means that shp won't be freed. */ - list_del(&task->sysvshm.shm_clist); - up_read(&shm_ids(ns).rwsem); - return; - } + ns = shp->ns;
- /* - * Destroy all already created segments, that were not yet mapped, - * and mark any mapped as orphan to cover the sysctl toggling. - * Destroy is skipped if shm_may_destroy() returns false. - */ - down_write(&shm_ids(ns).rwsem); - list_for_each_entry_safe(shp, n, &task->sysvshm.shm_clist, shm_clist) { - shp->shm_creator = NULL; + /* + * 2) If kernel.shm_rmid_forced is not set then only keep track of + * which shmids are orphaned, so that a later set of the sysctl + * can clean them up. + */ + if (!ns->shm_rmid_forced) + goto unlink_continue;
- if (shm_may_destroy(ns, shp)) { - shm_lock_by_ptr(shp); - shm_destroy(ns, shp); + /* + * 3) get a reference to the namespace. + * The refcount could be already 0. If it is 0, then + * the shm objects will be free by free_ipc_work(). + */ + ns = get_ipc_ns_not_zero(ns); + if (!ns) { +unlink_continue: + list_del_init(&shp->shm_clist); + task_unlock(task); + continue; } - }
- /* Remove the list head from any segments still attached. */ - list_del(&task->sysvshm.shm_clist); - up_write(&shm_ids(ns).rwsem); + /* + * 4) get a reference to shp. + * This cannot fail: shm_clist_rm() is called before + * ipc_rmid(), thus the refcount cannot be 0. + */ + WARN_ON(!ipc_rcu_getref(&shp->shm_perm)); + + /* + * 5) unlink the shm segment from the list of segments + * created by current. + * This must be done last. After unlinking, + * only the refcounts obtained above prevent IPC_RMID + * from destroying the segment or the namespace. + */ + list_del_init(&shp->shm_clist); + + task_unlock(task); + + /* + * 6) we have all references + * Thus lock & if needed destroy shp. + */ + down_write(&shm_ids(ns).rwsem); + shm_lock_by_ptr(shp); + /* + * rcu_read_lock was implicitly taken in shm_lock_by_ptr, it's + * safe to call ipc_rcu_putref here + */ + ipc_rcu_putref(&shp->shm_perm, shm_rcu_free); + + if (ipc_valid_object(&shp->shm_perm)) { + if (shm_may_destroy(shp)) + shm_destroy(ns, shp); + else + shm_unlock(shp); + } else { + /* + * Someone else deleted the shp from namespace + * idr/kht while we have waited. + * Just unlock and continue. + */ + shm_unlock(shp); + } + + up_write(&shm_ids(ns).rwsem); + put_ipc_ns(ns); /* paired with get_ipc_ns_not_zero */ + } }
static vm_fault_t shm_fault(struct vm_fault *vmf) @@ -680,7 +772,11 @@ static int newseg(struct ipc_namespace * if (error < 0) goto no_id;
+ shp->ns = ns; + + task_lock(current); list_add(&shp->shm_clist, ¤t->sysvshm.shm_clist); + task_unlock(current);
/* * shmid gets reported as "inode#" in /proc/pid/maps. @@ -1573,7 +1669,8 @@ out_nattch: down_write(&shm_ids(ns).rwsem); shp = shm_lock(ns, shmid); shp->shm_nattch--; - if (shm_may_destroy(ns, shp)) + + if (shm_may_destroy(shp)) shm_destroy(ns, shp); else shm_unlock(shp);
From: Rustam Kovhaev rkovhaev@gmail.com
commit 34dbc3aaf5d9e89ba6cc5e24add9458c21ab1950 upstream.
When kmemleak is enabled for SLOB, system does not boot and does not print anything to the console. At the very early stage in the boot process we hit infinite recursion from kmemleak_init() and eventually kernel crashes.
kmemleak_init() specifies SLAB_NOLEAKTRACE for KMEM_CACHE(), but kmem_cache_create_usercopy() removes it because CACHE_CREATE_MASK is not valid for SLOB.
Let's fix CACHE_CREATE_MASK and make kmemleak work with SLOB
Link: https://lkml.kernel.org/r/20211115020850.3154366-1-rkovhaev@gmail.com Fixes: d8843922fba4 ("slab: Ignore internal flags in cache creation") Signed-off-by: Rustam Kovhaev rkovhaev@gmail.com Acked-by: Vlastimil Babka vbabka@suse.cz Reviewed-by: Muchun Song songmuchun@bytedance.com Cc: Christoph Lameter cl@linux.com Cc: Pekka Enberg penberg@kernel.org Cc: David Rientjes rientjes@google.com Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Glauber Costa glommer@parallels.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/slab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/mm/slab.h +++ b/mm/slab.h @@ -147,7 +147,7 @@ static inline slab_flags_t kmem_cache_fl #define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE | SLAB_RECLAIM_ACCOUNT | \ SLAB_TEMPORARY | SLAB_ACCOUNT) #else -#define SLAB_CACHE_FLAGS (0) +#define SLAB_CACHE_FLAGS (SLAB_NOLEAKTRACE) #endif
/* Common flags available with current configuration */
From: Mina Almasry almasrymina@google.com
commit cc30042df6fcc82ea18acf0dace831503e60a0b7 upstream.
Currently in the is_continue case in hugetlb_mcopy_atomic_pte(), if we bail out using "goto out_release_unlock;" in the cases where idx >= size, or !huge_pte_none(), the code will detect that new_pagecache_page == false, and so call restore_reserve_on_error(). In this case I see restore_reserve_on_error() delete the reservation, and the following call to remove_inode_hugepages() will increment h->resv_hugepages causing a 100% reproducible leak.
We should treat the is_continue case similar to adding a page into the pagecache and set new_pagecache_page to true, to indicate that there is no reservation to restore on the error path, and we need not call restore_reserve_on_error(). Rename new_pagecache_page to page_in_pagecache to make that clear.
Link: https://lkml.kernel.org/r/20211117193825.378528-1-almasrymina@google.com Fixes: c7b1850dfb41 ("hugetlb: don't pass page cache pages to restore_reserve_on_error") Signed-off-by: Mina Almasry almasrymina@google.com Reported-by: James Houghton jthoughton@google.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Cc: Wei Xu weixugc@google.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/hugetlb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -5236,13 +5236,14 @@ int hugetlb_mcopy_atomic_pte(struct mm_s int ret = -ENOMEM; struct page *page; int writable; - bool new_pagecache_page = false; + bool page_in_pagecache = false;
if (is_continue) { ret = -EFAULT; page = find_lock_page(mapping, idx); if (!page) goto out; + page_in_pagecache = true; } else if (!*pagep) { /* If a page already exists, then it's UFFDIO_COPY for * a non-missing case. Return -EEXIST. @@ -5330,7 +5331,7 @@ int hugetlb_mcopy_atomic_pte(struct mm_s ret = huge_add_to_page_cache(page, mapping, idx); if (ret) goto out_release_nounlock; - new_pagecache_page = true; + page_in_pagecache = true; }
ptl = huge_pte_lockptr(h, dst_mm, dst_pte); @@ -5394,7 +5395,7 @@ out_release_unlock: if (vm_shared || is_continue) unlock_page(page); out_release_nounlock: - if (!new_pagecache_page) + if (!page_in_pagecache) restore_reserve_on_error(h, dst_vma, dst_addr, page); put_page(page); goto out;
From: Ard Biesheuvel ardb@kernel.org
commit 825c43f50e3aa811a291ffcb40e02fbf6d91ba86 upstream.
The kmap_local conversion broke the ARM architecture, because the new code assumes that all PTEs used for creating kmaps form a linear array in memory, and uses array indexing to look up the kmap PTE belonging to a certain kmap index.
On ARM, this cannot work, not only because the PTE pages may be non-adjacent in memory, but also because ARM/!LPAE interleaves hardware entries and extended entries (carrying software-only bits) in a way that is not compatible with array indexing.
Fortunately, this only seems to affect configurations with more than 8 CPUs, due to the way the per-CPU kmap slots are organized in memory.
Work around this by permitting an architecture to set a Kconfig symbol that signifies that the kmap PTEs do not form a lineary array in memory, and so the only way to locate the appropriate one is to walk the page tables.
Link: https://lore.kernel.org/linux-arm-kernel/20211026131249.3731275-1-ardb@kerne... Link: https://lkml.kernel.org/r/20211116094737.7391-1-ardb@kernel.org Fixes: 2a15ba82fa6c ("ARM: highmem: Switch to generic kmap atomic") Signed-off-by: Ard Biesheuvel ardb@kernel.org Reported-by: Quanyang Wang quanyang.wang@windriver.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Acked-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Cc: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/Kconfig | 1 + mm/Kconfig | 3 +++ mm/highmem.c | 32 +++++++++++++++++++++----------- 3 files changed, 25 insertions(+), 11 deletions(-)
--- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1455,6 +1455,7 @@ config HIGHMEM bool "High Memory Support" depends on MMU select KMAP_LOCAL + select KMAP_LOCAL_NON_LINEAR_PTE_ARRAY help The address space of ARM processors is only 4 Gigabytes large and it has to accommodate user address space, kernel address --- a/mm/Kconfig +++ b/mm/Kconfig @@ -887,6 +887,9 @@ config MAPPING_DIRTY_HELPERS config KMAP_LOCAL bool
+config KMAP_LOCAL_NON_LINEAR_PTE_ARRAY + bool + # struct io_mapping based helper. Selected by drivers that need them config IO_MAPPING bool --- a/mm/highmem.c +++ b/mm/highmem.c @@ -504,16 +504,22 @@ static inline int kmap_local_calc_idx(in
static pte_t *__kmap_pte;
-static pte_t *kmap_get_pte(void) +static pte_t *kmap_get_pte(unsigned long vaddr, int idx) { + if (IS_ENABLED(CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY)) + /* + * Set by the arch if __kmap_pte[-idx] does not produce + * the correct entry. + */ + return virt_to_kpte(vaddr); if (!__kmap_pte) __kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN)); - return __kmap_pte; + return &__kmap_pte[-idx]; }
void *__kmap_local_pfn_prot(unsigned long pfn, pgprot_t prot) { - pte_t pteval, *kmap_pte = kmap_get_pte(); + pte_t pteval, *kmap_pte; unsigned long vaddr; int idx;
@@ -525,9 +531,10 @@ void *__kmap_local_pfn_prot(unsigned lon preempt_disable(); idx = arch_kmap_local_map_idx(kmap_local_idx_push(), pfn); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - BUG_ON(!pte_none(*(kmap_pte - idx))); + kmap_pte = kmap_get_pte(vaddr, idx); + BUG_ON(!pte_none(*kmap_pte)); pteval = pfn_pte(pfn, prot); - arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte - idx, pteval); + arch_kmap_local_set_pte(&init_mm, vaddr, kmap_pte, pteval); arch_kmap_local_post_map(vaddr, pteval); current->kmap_ctrl.pteval[kmap_local_idx()] = pteval; preempt_enable(); @@ -560,7 +567,7 @@ EXPORT_SYMBOL(__kmap_local_page_prot); void kunmap_local_indexed(void *vaddr) { unsigned long addr = (unsigned long) vaddr & PAGE_MASK; - pte_t *kmap_pte = kmap_get_pte(); + pte_t *kmap_pte; int idx;
if (addr < __fix_to_virt(FIX_KMAP_END) || @@ -585,8 +592,9 @@ void kunmap_local_indexed(void *vaddr) idx = arch_kmap_local_unmap_idx(kmap_local_idx(), addr); WARN_ON_ONCE(addr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ kmap_pte = kmap_get_pte(addr, idx); arch_kmap_local_pre_unmap(addr); - pte_clear(&init_mm, addr, kmap_pte - idx); + pte_clear(&init_mm, addr, kmap_pte); arch_kmap_local_post_unmap(addr); current->kmap_ctrl.pteval[kmap_local_idx()] = __pte(0); kmap_local_idx_pop(); @@ -608,7 +616,7 @@ EXPORT_SYMBOL(kunmap_local_indexed); void __kmap_local_sched_out(void) { struct task_struct *tsk = current; - pte_t *kmap_pte = kmap_get_pte(); + pte_t *kmap_pte; int i;
/* Clear kmaps */ @@ -635,8 +643,9 @@ void __kmap_local_sched_out(void) idx = arch_kmap_local_map_idx(i, pte_pfn(pteval));
addr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + kmap_pte = kmap_get_pte(addr, idx); arch_kmap_local_pre_unmap(addr); - pte_clear(&init_mm, addr, kmap_pte - idx); + pte_clear(&init_mm, addr, kmap_pte); arch_kmap_local_post_unmap(addr); } } @@ -644,7 +653,7 @@ void __kmap_local_sched_out(void) void __kmap_local_sched_in(void) { struct task_struct *tsk = current; - pte_t *kmap_pte = kmap_get_pte(); + pte_t *kmap_pte; int i;
/* Restore kmaps */ @@ -664,7 +673,8 @@ void __kmap_local_sched_in(void) /* See comment in __kmap_local_sched_out() */ idx = arch_kmap_local_map_idx(i, pte_pfn(pteval)); addr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte_at(&init_mm, addr, kmap_pte - idx, pteval); + kmap_pte = kmap_get_pte(addr, idx); + set_pte_at(&init_mm, addr, kmap_pte, pteval); arch_kmap_local_post_map(addr, pteval); } }
From: SeongJae Park sj@kernel.org
commit db7a347b26fe05d2e8c115bb24dfd908d0252bc3 upstream.
Patch series "DAMON fixes".
This patch (of 2):
DAMON users can trigger below warning in '__alloc_pages()' by invoking write() to some DAMON debugfs files with arbitrarily high count argument, because DAMON debugfs interface allocates some buffers based on the user-specified 'count'.
if (unlikely(order >= MAX_ORDER)) { WARN_ON_ONCE(!(gfp & __GFP_NOWARN)); return NULL; }
Because the DAMON debugfs interface code checks failure of the 'kmalloc()', this commit simply suppresses the warnings by adding '__GFP_NOWARN' flag.
Link: https://lkml.kernel.org/r/20211110145758.16558-1-sj@kernel.org Link: https://lkml.kernel.org/r/20211110145758.16558-2-sj@kernel.org Fixes: 4bc05954d007 ("mm/damon: implement a debugfs-based user space interface") Signed-off-by: SeongJae Park sj@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
--- mm/damon/dbgfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/mm/damon/dbgfs.c +++ b/mm/damon/dbgfs.c @@ -32,7 +32,7 @@ static char *user_input_str(const char _ if (*ppos) return ERR_PTR(-EINVAL);
- kbuf = kmalloc(count + 1, GFP_KERNEL); + kbuf = kmalloc(count + 1, GFP_KERNEL | __GFP_NOWARN); if (!kbuf) return ERR_PTR(-ENOMEM);
@@ -247,7 +247,7 @@ static ssize_t dbgfs_kdamond_pid_read(st char *kbuf; ssize_t len;
- kbuf = kmalloc(count, GFP_KERNEL); + kbuf = kmalloc(count, GFP_KERNEL | __GFP_NOWARN); if (!kbuf) return -ENOMEM;
From: SeongJae Park sj@kernel.org
commit d78f3853f831eee46c6dbe726debf3be9e9c0d05 upstream.
DAMON debugfs is supposed to protect dbgfs_ctxs, dbgfs_nr_ctxs, and dbgfs_dirs using damon_dbgfs_lock. However, some of the code is accessing the variables without the protection. This fixes it by protecting all such accesses.
Link: https://lkml.kernel.org/r/20211110145758.16558-3-sj@kernel.org Fixes: 75c1c2b53c78 ("mm/damon/dbgfs: support multiple contexts") Signed-off-by: SeongJae Park sj@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/damon/dbgfs.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
--- a/mm/damon/dbgfs.c +++ b/mm/damon/dbgfs.c @@ -538,12 +538,14 @@ static ssize_t dbgfs_monitor_on_write(st return -EINVAL; }
+ mutex_lock(&damon_dbgfs_lock); if (!strncmp(kbuf, "on", count)) err = damon_start(dbgfs_ctxs, dbgfs_nr_ctxs); else if (!strncmp(kbuf, "off", count)) err = damon_stop(dbgfs_ctxs, dbgfs_nr_ctxs); else err = -EINVAL; + mutex_unlock(&damon_dbgfs_lock);
if (err) ret = err; @@ -596,15 +598,16 @@ static int __init __damon_dbgfs_init(voi
static int __init damon_dbgfs_init(void) { - int rc; + int rc = -ENOMEM;
+ mutex_lock(&damon_dbgfs_lock); dbgfs_ctxs = kmalloc(sizeof(*dbgfs_ctxs), GFP_KERNEL); if (!dbgfs_ctxs) - return -ENOMEM; + goto out; dbgfs_ctxs[0] = dbgfs_new_ctx(); if (!dbgfs_ctxs[0]) { kfree(dbgfs_ctxs); - return -ENOMEM; + goto out; } dbgfs_nr_ctxs = 1;
@@ -615,6 +618,8 @@ static int __init damon_dbgfs_init(void) pr_err("%s: dbgfs init failed\n", __func__); }
+out: + mutex_unlock(&damon_dbgfs_lock); return rc; }
From: Borislav Petkov bp@suse.de
commit 8d48bf8206f77aa8687f0e241e901e5197e52423 upstream.
Dan reports that Anjaneya Chagam can no longer use the efi=nosoftreserve kernel command line parameter to suppress "soft reservation" behavior.
This is due to the fact that the following call-chain happens at boot:
early_reserve_memory |-> efi_memblock_x86_reserve_range |-> efi_fake_memmap_early
which does
if (!efi_soft_reserve_enabled()) return;
and that would have set EFI_MEM_NO_SOFT_RESERVE after having parsed "nosoftreserve".
However, parse_early_param() gets called *after* it, leading to the boot cmdline not being taken into account.
Therefore, carve out the command line preparation into a separate function which does the early param parsing too. So that it all goes together.
And then call that function before early_reserve_memory() so that the params would have been parsed by then.
Fixes: 8aa83e6395ce ("x86/setup: Call early_reserve_memory() earlier") Reported-by: Dan Williams dan.j.williams@intel.com Reviewed-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Borislav Petkov bp@suse.de Tested-by: Anjaneya Chagam anjaneya.chagam@intel.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/e8dd8993c38702ee6dd73b3c11f158617e665607.camel@int... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/setup.c | 66 ++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 27 deletions(-)
--- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -742,6 +742,28 @@ dump_kernel_offset(struct notifier_block return 0; }
+static char *prepare_command_line(void) +{ +#ifdef CONFIG_CMDLINE_BOOL +#ifdef CONFIG_CMDLINE_OVERRIDE + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); +#else + if (builtin_cmdline[0]) { + /* append boot loader cmdline to builtin */ + strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); + strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); + } +#endif +#endif + + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); + + parse_early_param(); + + return command_line; +} + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -831,6 +853,23 @@ void __init setup_arch(char **cmdline_p) x86_init.oem.arch_setup();
/* + * x86_configure_nx() is called before parse_early_param() (called by + * prepare_command_line()) to detect whether hardware doesn't support + * NX (so that the early EHCI debug console setup can safely call + * set_fixmap()). It may then be called again from within noexec_setup() + * during parsing early parameters to honor the respective command line + * option. + */ + x86_configure_nx(); + + /* + * This parses early params and it needs to run before + * early_reserve_memory() because latter relies on such settings + * supplied as early params. + */ + *cmdline_p = prepare_command_line(); + + /* * Do some memory reservations *before* memory is added to memblock, so * memblock allocations won't overwrite it. * @@ -863,33 +902,6 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = __pa_symbol(__bss_start); bss_resource.end = __pa_symbol(__bss_stop)-1;
-#ifdef CONFIG_CMDLINE_BOOL -#ifdef CONFIG_CMDLINE_OVERRIDE - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -#else - if (builtin_cmdline[0]) { - /* append boot loader cmdline to builtin */ - strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); - strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); - } -#endif -#endif - - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - - /* - * x86_configure_nx() is called before parse_early_param() to detect - * whether hardware doesn't support NX (so that the early EHCI debug - * console setup can safely call set_fixmap()). It may then be called - * again from within noexec_setup() during parsing early parameters - * to honor the respective command line option. - */ - x86_configure_nx(); - - parse_early_param(); - #ifdef CONFIG_MEMORY_HOTPLUG /* * Memory used by the kernel cannot be hot-removed because Linux
From: Reinette Chatre reinette.chatre@intel.com
commit ac5d272a0ad0419f52e08c91953356e32b075af7 upstream.
The SGX driver maintains a single global free page counter, sgx_nr_free_pages, that reflects the number of free pages available across all NUMA nodes. Correspondingly, a list of free pages is associated with each NUMA node and sgx_nr_free_pages is updated every time a page is added or removed from any of the free page lists. The main usage of sgx_nr_free_pages is by the reclaimer that runs when it (sgx_nr_free_pages) goes below a watermark to ensure that there are always some free pages available to, for example, support efficient page faults.
With sgx_nr_free_pages accessed and modified from a few places it is essential to ensure that these accesses are done safely but this is not the case. sgx_nr_free_pages is read without any protection and updated with inconsistent protection by any one of the spin locks associated with the individual NUMA nodes. For example:
CPU_A CPU_B ----- ----- spin_lock(&nodeA->lock); spin_lock(&nodeB->lock); ... ... sgx_nr_free_pages--; /* NOT SAFE */ sgx_nr_free_pages--;
spin_unlock(&nodeA->lock); spin_unlock(&nodeB->lock);
Since sgx_nr_free_pages may be protected by different spin locks while being modified from different CPUs, the following scenario is possible:
CPU_A CPU_B ----- ----- {sgx_nr_free_pages = 100} spin_lock(&nodeA->lock); spin_lock(&nodeB->lock); sgx_nr_free_pages--; sgx_nr_free_pages--; /* LOAD sgx_nr_free_pages = 100 */ /* LOAD sgx_nr_free_pages = 100 */ /* sgx_nr_free_pages-- */ /* sgx_nr_free_pages-- */ /* STORE sgx_nr_free_pages = 99 */ /* STORE sgx_nr_free_pages = 99 */ spin_unlock(&nodeA->lock); spin_unlock(&nodeB->lock);
In the above scenario, sgx_nr_free_pages is decremented from two CPUs but instead of sgx_nr_free_pages ending with a value that is two less than it started with, it was only decremented by one while the number of free pages were actually reduced by two. The consequence of sgx_nr_free_pages not being protected is that its value may not accurately reflect the actual number of free pages on the system, impacting the availability of free pages in support of many flows.
The problematic scenario is when the reclaimer does not run because it believes there to be sufficient free pages while any attempt to allocate a page fails because there are no free pages available. In the SGX driver the reclaimer's watermark is only 32 pages so after encountering the above example scenario 32 times a user space hang is possible when there are no more free pages because of repeated page faults caused by no free pages made available.
The following flow was encountered: asm_exc_page_fault ... sgx_vma_fault() sgx_encl_load_page() sgx_encl_eldu() // Encrypted page needs to be loaded from backing // storage into newly allocated SGX memory page sgx_alloc_epc_page() // Allocate a page of SGX memory __sgx_alloc_epc_page() // Fails, no free SGX memory ... if (sgx_should_reclaim(SGX_NR_LOW_PAGES)) // Wake reclaimer wake_up(&ksgxd_waitq); return -EBUSY; // Return -EBUSY giving reclaimer time to run return -EBUSY; return -EBUSY; return VM_FAULT_NOPAGE;
The reclaimer is triggered in above flow with the following code:
static bool sgx_should_reclaim(unsigned long watermark) { return sgx_nr_free_pages < watermark && !list_empty(&sgx_active_page_list); }
In the problematic scenario there were no free pages available yet the value of sgx_nr_free_pages was above the watermark. The allocation of SGX memory thus always failed because of a lack of free pages while no free pages were made available because the reclaimer is never started because of sgx_nr_free_pages' incorrect value. The consequence was that user space kept encountering VM_FAULT_NOPAGE that caused the same address to be accessed repeatedly with the same result.
Change the global free page counter to an atomic type that ensures simultaneous updates are done safely. While doing so, move the updating of the variable outside of the spin lock critical section to which it does not belong.
Cc: stable@vger.kernel.org Fixes: 901ddbb9ecf5 ("x86/sgx: Add a basic NUMA allocation scheme to sgx_alloc_epc_page()") Suggested-by: Dave Hansen dave.hansen@linux.intel.com Signed-off-by: Reinette Chatre reinette.chatre@intel.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Tony Luck tony.luck@intel.com Acked-by: Jarkko Sakkinen jarkko@kernel.org Link: https://lkml.kernel.org/r/a95a40743bbd3f795b465f30922dde7f1ea9e0eb.163700409... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/cpu/sgx/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -28,8 +28,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ksgxd_wai static LIST_HEAD(sgx_active_page_list); static DEFINE_SPINLOCK(sgx_reclaimer_lock);
-/* The free page list lock protected variables prepend the lock. */ -static unsigned long sgx_nr_free_pages; +static atomic_long_t sgx_nr_free_pages = ATOMIC_LONG_INIT(0);
/* Nodes with one or more EPC sections. */ static nodemask_t sgx_numa_mask; @@ -403,14 +402,15 @@ skip:
spin_lock(&node->lock); list_add_tail(&epc_page->list, &node->free_page_list); - sgx_nr_free_pages++; spin_unlock(&node->lock); + atomic_long_inc(&sgx_nr_free_pages); } }
static bool sgx_should_reclaim(unsigned long watermark) { - return sgx_nr_free_pages < watermark && !list_empty(&sgx_active_page_list); + return atomic_long_read(&sgx_nr_free_pages) < watermark && + !list_empty(&sgx_active_page_list); }
static int ksgxd(void *p) @@ -471,9 +471,9 @@ static struct sgx_epc_page *__sgx_alloc_
page = list_first_entry(&node->free_page_list, struct sgx_epc_page, list); list_del_init(&page->list); - sgx_nr_free_pages--;
spin_unlock(&node->lock); + atomic_long_dec(&sgx_nr_free_pages);
return page; } @@ -625,9 +625,9 @@ void sgx_free_epc_page(struct sgx_epc_pa spin_lock(&node->lock);
list_add_tail(&page->list, &node->free_page_list); - sgx_nr_free_pages++;
spin_unlock(&node->lock); + atomic_long_inc(&sgx_nr_free_pages); }
static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
From: Sean Christopherson seanjc@google.com
commit daf972118c517b91f74ff1731417feb4270625a4 upstream.
Check for a valid hv_vp_index array prior to derefencing hv_vp_index when setting Hyper-V's TSC change callback. If Hyper-V setup failed in hyperv_init(), the kernel will still report that it's running under Hyper-V, but will have silently disabled nearly all functionality.
BUG: kernel NULL pointer dereference, address: 0000000000000010 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.15.0-rc2+ #75 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:set_hv_tscchange_cb+0x15/0xa0 Code: <8b> 04 82 8b 15 12 17 85 01 48 c1 e0 20 48 0d ee 00 01 00 f6 c6 08 ... Call Trace: kvm_arch_init+0x17c/0x280 kvm_init+0x31/0x330 vmx_init+0xba/0x13a do_one_initcall+0x41/0x1c0 kernel_init_freeable+0x1f2/0x23b kernel_init+0x16/0x120 ret_from_fork+0x22/0x30
Fixes: 93286261de1b ("x86/hyperv: Reenlightenment notifications support") Cc: stable@vger.kernel.org Cc: Vitaly Kuznetsov vkuznets@redhat.com Signed-off-by: Sean Christopherson seanjc@google.com Reviewed-by: Vitaly Kuznetsov vkuznets@redhat.com Link: https://lore.kernel.org/r/20211104182239.1302956-2-seanjc@google.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/hyperv/hv_init.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -147,6 +147,9 @@ void set_hv_tscchange_cb(void (*cb)(void return; }
+ if (!hv_vp_index) + return; + hv_reenlightenment_cb = cb;
/* Make sure callback is registered before we write to MSRs */
From: Tom Lendacky thomas.lendacky@amd.com
commit b5aead0064f33ae5e693a364e3204fe1c0ac9af2 upstream.
When processing a hypercall for a guest with protected state, currently SEV-ES guests, the guest CS segment register can't be checked to determine if the guest is in 64-bit mode. For an SEV-ES guest, it is expected that communication between the guest and the hypervisor is performed to shared memory using the GHCB. In order to use the GHCB, the guest must have been in long mode, otherwise writes by the guest to the GHCB would be encrypted and not be able to be comprehended by the hypervisor.
Create a new helper function, is_64_bit_hypercall(), that assumes the guest is in 64-bit mode when the guest has protected state, and returns true, otherwise invoking is_64_bit_mode() to determine the mode. Update the hypercall related routines to use is_64_bit_hypercall() instead of is_64_bit_mode().
Add a WARN_ON_ONCE() to is_64_bit_mode() to catch occurences of calls to this helper function for a guest running with protected state.
Fixes: f1c6366e3043 ("KVM: SVM: Add required changes to support intercepts under SEV-ES") Reported-by: Sean Christopherson seanjc@google.com Signed-off-by: Tom Lendacky thomas.lendacky@amd.com Message-Id: e0b20c770c9d0d1403f23d83e785385104211f74.1621878537.git.thomas.lendacky@amd.com Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/hyperv.c | 4 ++-- arch/x86/kvm/x86.c | 2 +- arch/x86/kvm/x86.h | 12 ++++++++++++ arch/x86/kvm/xen.c | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-)
--- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -2022,7 +2022,7 @@ static void kvm_hv_hypercall_set_result( { bool longmode;
- longmode = is_64_bit_mode(vcpu); + longmode = is_64_bit_hypercall(vcpu); if (longmode) kvm_rax_write(vcpu, result); else { @@ -2171,7 +2171,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vc }
#ifdef CONFIG_X86_64 - if (is_64_bit_mode(vcpu)) { + if (is_64_bit_hypercall(vcpu)) { hc.param = kvm_rcx_read(vcpu); hc.ingpa = kvm_rdx_read(vcpu); hc.outgpa = kvm_r8_read(vcpu); --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8737,7 +8737,7 @@ int kvm_emulate_hypercall(struct kvm_vcp
trace_kvm_hypercall(nr, a0, a1, a2, a3);
- op_64_bit = is_64_bit_mode(vcpu); + op_64_bit = is_64_bit_hypercall(vcpu); if (!op_64_bit) { nr &= 0xFFFFFFFF; a0 &= 0xFFFFFFFF; --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -153,12 +153,24 @@ static inline bool is_64_bit_mode(struct { int cs_db, cs_l;
+ WARN_ON_ONCE(vcpu->arch.guest_state_protected); + if (!is_long_mode(vcpu)) return false; static_call(kvm_x86_get_cs_db_l_bits)(vcpu, &cs_db, &cs_l); return cs_l; }
+static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu) +{ + /* + * If running with protected guest state, the CS register is not + * accessible. The hypercall register values will have had to been + * provided in 64-bit mode, so assume the guest is in 64-bit. + */ + return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu); +} + static inline bool x86_exception_has_error_code(unsigned int vector) { static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) | --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -698,7 +698,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *v kvm_hv_hypercall_enabled(vcpu)) return kvm_hv_hypercall(vcpu);
- longmode = is_64_bit_mode(vcpu); + longmode = is_64_bit_hypercall(vcpu); if (!longmode) { params[0] = (u32)kvm_rbx_read(vcpu); params[1] = (u32)kvm_rcx_read(vcpu);
From: 黄乐 huangle1@jd.com
commit c5adbb3af051079f35abfa26551107e2c653087f upstream.
In vcpu_load_eoi_exitmap(), currently the eoi_exit_bitmap[4] array is initialized only when Hyper-V context is available, in other path it is just passed to kvm_x86_ops.load_eoi_exitmap() directly from on the stack, which would cause unexpected interrupt delivery/handling issues, e.g. an *old* linux kernel that relies on PIT to do clock calibration on KVM might randomly fail to boot.
Fix it by passing ioapic_handled_vectors to load_eoi_exitmap() when Hyper-V context is not available.
Fixes: f2bc14b69c38 ("KVM: x86: hyper-v: Prepare to meet unallocated Hyper-V context") Cc: stable@vger.kernel.org Reviewed-by: Vitaly Kuznetsov vkuznets@redhat.com Signed-off-by: Huang Le huangle1@jd.com Message-Id: 62115b277dab49ea97da5633f8522daf@jd.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9429,12 +9429,16 @@ static void vcpu_load_eoi_exitmap(struct if (!kvm_apic_hw_enabled(vcpu->arch.apic)) return;
- if (to_hv_vcpu(vcpu)) + if (to_hv_vcpu(vcpu)) { bitmap_or((ulong *)eoi_exit_bitmap, vcpu->arch.ioapic_handled_vectors, to_hv_synic(vcpu)->vec_bitmap, 256); + static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap); + return; + }
- static_call(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap); + static_call(kvm_x86_load_eoi_exitmap)( + vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors); }
void kvm_arch_mmu_notifier_invalidate_range(struct kvm *kvm,
From: Maxim Levitsky mlevitsk@redhat.com
commit b8453cdcf26020030da182f0156d7bf59ae5719f upstream.
Incorporate EFER.LMA into kvm_mmu_extended_role, as it used to compute the guest root level and is not reflected in kvm_mmu_page_role.level when TDP is in use. When simply running the guest, it is impossible for EFER.LMA and kvm_mmu.root_level to get out of sync, as the guest cannot transition from PAE paging to 64-bit paging without toggling CR0.PG, i.e. without first bouncing through a different MMU context. And stuffing guest state via KVM_SET_SREGS{,2} also ensures a full MMU context reset.
However, if KVM_SET_SREGS{,2} is followed by KVM_SET_NESTED_STATE, e.g. to set guest state when migrating the VM while L2 is active, the vCPU state will reflect L2, not L1. If L1 is using TDP for L2, then root_mmu will have been configured using L2's state, despite not being used for L2. If L2.EFER.LMA != L1.EFER.LMA, and L2 is using PAE paging, then root_mmu will be configured for guest PAE paging, but will match the mmu_role for 64-bit paging and cause KVM to not reconfigure root_mmu on the next nested VM-Exit.
Alternatively, the root_mmu's role could be invalidated after a successful KVM_SET_NESTED_STATE that yields vcpu->arch.mmu != vcpu->arch.root_mmu, i.e. that switches the active mmu to guest_mmu, but doing so is unnecessarily tricky, and not even needed if L1 and L2 do have the same role (e.g., they are both 64-bit guests and run with the same CR4).
Suggested-by: Sean Christopherson seanjc@google.com Signed-off-by: Maxim Levitsky mlevitsk@redhat.com Message-Id: 20211115131837.195527-3-mlevitsk@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu/mmu.c | 1 + 2 files changed, 2 insertions(+)
--- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -364,6 +364,7 @@ union kvm_mmu_extended_role { unsigned int cr4_smap:1; unsigned int cr4_smep:1; unsigned int cr4_la57:1; + unsigned int efer_lma:1; }; };
--- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4679,6 +4679,7 @@ static union kvm_mmu_extended_role kvm_c /* PKEY and LA57 are active iff long mode is active. */ ext.cr4_pke = ____is_efer_lma(regs) && ____is_cr4_pke(regs); ext.cr4_la57 = ____is_efer_lma(regs) && ____is_cr4_la57(regs); + ext.efer_lma = ____is_efer_lma(regs); }
ext.valid = 1;
From: David Woodhouse dwmw@amazon.co.uk
commit 4e8436479ad3be76a3823e6ce466ae464ce71300 upstream.
In commit 319afe68567b ("KVM: xen: do not use struct gfn_to_hva_cache") we stopped storing this in-kernel as a GPA, and started storing it as a GFN. Which means we probably should have stopped calling gpa_to_gfn() on it when userspace asks for it back.
Cc: stable@vger.kernel.org Fixes: 319afe68567b ("KVM: xen: do not use struct gfn_to_hva_cache") Signed-off-by: David Woodhouse dwmw@amazon.co.uk Message-Id: 20211115165030.7422-2-dwmw2@infradead.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/xen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -299,7 +299,7 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm break;
case KVM_XEN_ATTR_TYPE_SHARED_INFO: - data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_gfn); + data->u.shared_info.gfn = kvm->arch.xen.shinfo_gfn; r = 0; break;
From: Christophe Leroy christophe.leroy@csgroup.eu
commit 5499802b2284331788a440585869590f1bd63f7f upstream.
The conversion from __copy_from_user() to __get_user() by commit d3ccc9781560 ("powerpc/signal: Use __get_user() to copy sigset_t") introduced a regression in __get_user_sigset() for powerpc/32. The bug was subsequently moved into unsafe_get_user_sigset().
The bug is due to the copied 64 bit value being truncated to 32 bits while being assigned to dst->sig[0]
The regression was reported by users of the Xorg packages distributed in Debian/powerpc --
"The symptoms are that the fb screen goes blank, with the backlight remaining on and no errors logged in /var/log; wdm (or startx) run with no effect (I tried logging in in the blind, with no effect). And they are hard to kill, requiring 'kill -KILL ...'"
Fix the regression by copying each word of the sigset, not only the first one.
__get_user_sigset() was tentatively optimised to copy 64 bits at once in order to minimise KUAP unlock/lock impact, but the unsafe variant doesn't suffer that, so it can just copy words.
Fixes: 887f3ceb51cd ("powerpc/signal32: Convert do_setcontext[_tm]() to user access block") Cc: stable@vger.kernel.org # v5.13+ Reported-by: Finn Thain fthain@linux-m68k.org Reported-and-tested-by: Stan Johnson userm57@yahoo.com Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/99ef38d61c0eb3f79c68942deb0c35995a93a777.163696635... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/signal.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -25,8 +25,14 @@ static inline int __get_user_sigset(sigs
return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]); } -#define unsafe_get_user_sigset(dst, src, label) \ - unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label) +#define unsafe_get_user_sigset(dst, src, label) do { \ + sigset_t *__dst = dst; \ + const sigset_t __user *__src = src; \ + int i; \ + \ + for (i = 0; i < _NSIG_WORDS; i++) \ + unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \ +} while (0)
#ifdef CONFIG_VSX extern unsigned long copy_vsx_to_user(void __user *to,
From: Cédric Le Goater clg@kaod.org
commit 8e80a73fa9a7747e3e8255cb149c543aabf65a24 upstream.
Commit 4f86a06e2d6e ("irqdomain: Make normal and nomap irqdomains exclusive") introduced an IRQ_DOMAIN_FLAG_NO_MAP flag to isolate the 'nomap' domains still in use under the powerpc arch. With this new flag, the revmap_tree of the IRQ domain is not used anymore. This change broke the support of shared LSIs [1] in the XIVE driver because it was relying on a lookup in the revmap_tree to query previously mapped interrupts. Linux now creates two distinct IRQ mappings on the same HW IRQ which can lead to unexpected behavior in the drivers.
The XIVE IRQ domain is not a direct mapping domain and its HW IRQ interrupt number space is rather large : 1M/socket on POWER9 and POWER10, change the XIVE driver to use a 'tree' domain type instead.
[1] For instance, a linux KVM guest with virtio-rng and virtio-balloon devices.
Fixes: 4f86a06e2d6e ("irqdomain: Make normal and nomap irqdomains exclusive") Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Cédric Le Goater clg@kaod.org Tested-by: Greg Kurz groug@kaod.org Acked-by: Marc Zyngier maz@kernel.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211116134022.420412-1-clg@kaod.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/sysdev/xive/Kconfig | 1 - arch/powerpc/sysdev/xive/common.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-)
--- a/arch/powerpc/sysdev/xive/Kconfig +++ b/arch/powerpc/sysdev/xive/Kconfig @@ -3,7 +3,6 @@ config PPC_XIVE bool select PPC_SMP_MUXED_IPI select HARDIRQS_SW_RESEND - select IRQ_DOMAIN_NOMAP
config PPC_XIVE_NATIVE bool --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1443,8 +1443,7 @@ static const struct irq_domain_ops xive_
static void __init xive_init_host(struct device_node *np) { - xive_irq_domain = irq_domain_add_nomap(np, XIVE_MAX_IRQ, - &xive_irq_domain_ops, NULL); + xive_irq_domain = irq_domain_add_tree(np, &xive_irq_domain_ops, NULL); if (WARN_ON(xive_irq_domain == NULL)) return; irq_set_default_host(xive_irq_domain);
From: Christophe Leroy christophe.leroy@csgroup.eu
commit 1e35eba4055149c578baf0318d2f2f89ea3c44a0 upstream.
As spotted and explained in commit c12ab8dbc492 ("powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST"), the selection of STRICT_KERNEL_RWX without selecting DEBUG_RODATA_TEST has spotted the lack of the DIRTY bit in the pinned kernel data TLBs.
This problem should have been detected a lot earlier if things had been working as expected. But due to an incredible level of chance or mishap, this went undetected because of a set of bugs: In fact the DTLBs were not pinned, because instead of setting the reserve bit in MD_CTR, it was set in MI_CTR that is the register for ITLBs.
But then, another huge bug was there: the physical address was reset to 0 at the boundary between RO and RW areas, leading to the same physical space being mapped at both 0xc0000000 and 0xc8000000. This had by miracle no consequence until now because the entry was not really pinned so it was overwritten soon enough to go undetected.
Of course, now that we really pin the DTLBs, it must be fixed as well.
Fixes: f76c8f6d257c ("powerpc/8xx: Add function to set pinned TLBs") Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Depends-on: c12ab8dbc492 ("powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST") Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/a21e9a057fe2d247a535aff0d157a54eefee017a.163696368... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/head_8xx.S | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -733,6 +733,7 @@ _GLOBAL(mmu_pin_tlb) #ifdef CONFIG_PIN_TLB_DATA LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET) LOAD_REG_IMMEDIATE(r7, MI_SVALID | MI_PS8MEG | _PMD_ACCESSED) + li r8, 0 #ifdef CONFIG_PIN_TLB_IMMR li r0, 3 #else @@ -741,26 +742,26 @@ _GLOBAL(mmu_pin_tlb) mtctr r0 cmpwi r4, 0 beq 4f - LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) LOAD_REG_ADDR(r9, _sinittext)
2: ori r0, r6, MD_EVALID + ori r12, r8, 0xf0 | _PAGE_RO | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT mtspr SPRN_MD_CTR, r5 mtspr SPRN_MD_EPN, r0 mtspr SPRN_MD_TWC, r7 - mtspr SPRN_MD_RPN, r8 + mtspr SPRN_MD_RPN, r12 addi r5, r5, 0x100 addis r6, r6, SZ_8M@h addis r8, r8, SZ_8M@h cmplw r6, r9 bdnzt lt, 2b - -4: LOAD_REG_IMMEDIATE(r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT) +4: 2: ori r0, r6, MD_EVALID + ori r12, r8, 0xf0 | _PAGE_DIRTY | _PAGE_SPS | _PAGE_SH | _PAGE_PRESENT mtspr SPRN_MD_CTR, r5 mtspr SPRN_MD_EPN, r0 mtspr SPRN_MD_TWC, r7 - mtspr SPRN_MD_RPN, r8 + mtspr SPRN_MD_RPN, r12 addi r5, r5, 0x100 addis r6, r6, SZ_8M@h addis r8, r8, SZ_8M@h @@ -781,7 +782,7 @@ _GLOBAL(mmu_pin_tlb) #endif #if defined(CONFIG_PIN_TLB_IMMR) || defined(CONFIG_PIN_TLB_DATA) lis r0, (MD_RSV4I | MD_TWAM)@h - mtspr SPRN_MI_CTR, r0 + mtspr SPRN_MD_CTR, r0 #endif mtspr SPRN_SRR1, r10 mtspr SPRN_SRR0, r11
From: Vandita Kulkarni vandita.kulkarni@intel.com
commit f15863b27752682bb700c21de5f83f613a0fb77e upstream.
This reverts commit 991d9557b0c4 ("drm/i915/tgl/dsi: Gate the ddi clocks after pll mapping"). The Bspec was updated recently with the pll ungate sequence similar to that of icl dsi enable sequence. Hence reverting.
Bspec: 49187 Fixes: 991d9557b0c4 ("drm/i915/tgl/dsi: Gate the ddi clocks after pll mapping") Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Vandita Kulkarni vandita.kulkarni@intel.com Signed-off-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20211109120428.15211-1-vandita... (cherry picked from commit 4579509ef181480f4e4510d436c691519167c5c2) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/icl_dsi.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -711,10 +711,7 @@ static void gen11_dsi_map_pll(struct int intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
for_each_dsi_phy(phy, intel_dsi->phys) { - if (DISPLAY_VER(dev_priv) >= 12) - val |= ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); - else - val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); + val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy); } intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
@@ -1150,8 +1147,6 @@ static void gen11_dsi_enable_port_and_phy(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - /* step 4a: power up all lanes of the DDI used by DSI */ gen11_dsi_power_up_lanes(encoder);
@@ -1177,8 +1172,7 @@ gen11_dsi_enable_port_and_phy(struct int gen11_dsi_configure_transcoder(encoder, crtc_state);
/* Step 4l: Gate DDI clocks */ - if (DISPLAY_VER(dev_priv) == 11) - gen11_dsi_gate_clocks(encoder); + gen11_dsi_gate_clocks(encoder); }
static void gen11_dsi_powerup_panel(struct intel_encoder *encoder)
From: Helge Deller deller@gmx.de
commit 79df39d535c7a3770856fe9f5aba8c0ad1eebdb6 upstream.
This reverts commit e4f2006f1287e7ea17660490569cff323772dac4.
This patch shows problems with signal handling. Revert it for now.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@vger.kernel.org # v5.15 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/include/asm/rt_sigframe.h | 2 +- arch/parisc/kernel/signal.c | 13 +++++++------ arch/parisc/kernel/signal32.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-)
--- a/arch/parisc/include/asm/rt_sigframe.h +++ b/arch/parisc/include/asm/rt_sigframe.h @@ -2,7 +2,7 @@ #ifndef _ASM_PARISC_RT_SIGFRAME_H #define _ASM_PARISC_RT_SIGFRAME_H
-#define SIGRETURN_TRAMP 3 +#define SIGRETURN_TRAMP 4 #define SIGRESTARTBLOCK_TRAMP 5 #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP)
--- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -288,21 +288,22 @@ setup_rt_frame(struct ksignal *ksig, sig already in userspace. The first words of tramp are used to save the previous sigrestartblock trampoline that might be on the stack. We start the sigreturn trampoline at - SIGRESTARTBLOCK_TRAMP. */ + SIGRESTARTBLOCK_TRAMP+X. */ err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0, &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]); - err |= __put_user(INSN_BLE_SR2_R0, + err |= __put_user(INSN_LDI_R20, &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]); - err |= __put_user(INSN_LDI_R20, + err |= __put_user(INSN_BLE_SR2_R0, &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]); + err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
- start = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]; - end = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]; + start = (unsigned long) &frame->tramp[0]; + end = (unsigned long) &frame->tramp[TRAMP_SIZE]; flush_user_dcache_range_asm(start, end); flush_user_icache_range_asm(start, end);
/* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP - * TRAMP Words 5-7, Length 3 = SIGRETURN_TRAMP + * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP */ rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP]; --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h @@ -36,7 +36,7 @@ struct compat_regfile { compat_int_t rf_sar; };
-#define COMPAT_SIGRETURN_TRAMP 3 +#define COMPAT_SIGRETURN_TRAMP 4 #define COMPAT_SIGRESTARTBLOCK_TRAMP 5 #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ COMPAT_SIGRESTARTBLOCK_TRAMP)
From: Damien Le Moal damien.lemoal@opensource.wdc.com
commit 23ef63d5e14f916c5bba39128ebef395859d7c0f upstream.
If ata_read_log_page() fails to read a log page, the ata_dev_err() error message only print the page number, omitting the log number. In case of error, facilitate debugging by also printing the log number.
Cc: stable@kernel.org # 5.15 Signed-off-by: Damien Le Moal damien.lemoal@opensource.wdc.com Tested-by: Matthew Perkowski mgperkow@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2031,8 +2031,9 @@ retry: dev->horkage |= ATA_HORKAGE_NO_DMA_LOG; goto retry; } - ata_dev_err(dev, "Read log page 0x%02x failed, Emask 0x%x\n", - (unsigned int)page, err_mask); + ata_dev_err(dev, + "Read log 0x%02x page 0x%02x failed, Emask 0x%x\n", + (unsigned int)log, (unsigned int)page, err_mask); }
return err_mask;
From: Damien Le Moal damien.lemoal@opensource.wdc.com
commit 06f6c4c6c3e8354dceddd77bd58f9a7a84c67246 upstream.
ata_dev_config_ncq_prio() and ata_dev_config_devslp() both access pages of the IDENTIFY DEVICE data log. Before calling ata_read_log_page(), make sure to check for the existence of the IDENTIFY DEVICE data log and of the log page accessed using ata_identify_page_supported(). This avoids useless error messages from ata_read_log_page() and failures with some LLDD scsi drivers using libsas.
Reported-by: Nikolay knv418@gmail.com Cc: stable@kernel.org # 5.15 Signed-off-by: Damien Le Moal damien.lemoal@opensource.wdc.com Tested-by: Matthew Perkowski mgperkow@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2167,6 +2167,9 @@ static void ata_dev_config_ncq_prio(stru struct ata_port *ap = dev->link->ap; unsigned int err_mask;
+ if (!ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) + return; + err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SATA_SETTINGS, @@ -2443,7 +2446,8 @@ static void ata_dev_config_devslp(struct * Check device sleep capability. Get DevSlp timing variables * from SATA Settings page of Identify Device Data Log. */ - if (!ata_id_has_devslp(dev->id)) + if (!ata_id_has_devslp(dev->id) || + !ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) return;
err_mask = ata_read_log_page(dev,
From: Ewan D. Milne emilne@redhat.com
commit 392006871bb26166bcfafa56faf49431c2cfaaa8 upstream.
The SCM changes set the flags in mcp->out_mb instead of mcp->in_mb so the data was not actually being read into the mcp->mb[] array from the adapter.
Link: https://lore.kernel.org/r/20211108183012.13895-1-emilne@redhat.com Fixes: 9f2475fe7406 ("scsi: qla2xxx: SAN congestion management implementation") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Reviewed-by: Arun Easi aeasi@marvell.com Signed-off-by: Ewan D. Milne emilne@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_mbx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1695,10 +1695,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t * mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10; if (IS_FWI2_CAPABLE(vha->hw)) mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16; - if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) { - mcp->in_mb |= MBX_15; - mcp->out_mb |= MBX_7|MBX_21|MBX_22|MBX_23; - } + if (IS_QLA27XX(vha->hw) || IS_QLA28XX(vha->hw)) + mcp->in_mb |= MBX_15|MBX_21|MBX_22|MBX_23;
mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0;
From: Sergio Paracuellos sergio.paracuellos@gmail.com
commit a5b9703fe11cd1d6d7a60102aa2abe686dc1867f upstream.
mt7620.h, included by pinctrl-mt7620.c, mentions MT762X_SOC_MT7628AN declared in ralink_regs.h.
Fixes: 745ec436de72 ("pinctrl: ralink: move MT7620 SoC pinmux config into a new 'pinctrl-mt7620.c' file") Cc: stable@vger.kernel.org Signed-off-by: Luiz Angelo Daros de Luca luizluca@gmail.com Signed-off-by: Sergio Paracuellos sergio.paracuellos@gmail.com Link: https://lore.kernel.org/r/20211031064046.13533-1-sergio.paracuellos@gmail.co... Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/ralink/pinctrl-mt7620.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/pinctrl/ralink/pinctrl-mt7620.c +++ b/drivers/pinctrl/ralink/pinctrl-mt7620.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only
+#include <asm/mach-ralink/ralink_regs.h> #include <asm/mach-ralink/mt7620.h> #include <linux/module.h> #include <linux/platform_device.h>
From: Vasily Gorbik gor@linux.ibm.com
commit 420f48f636b98fd685f44a3acc4c0a7c0840910d upstream.
Such reserved memory region, if not cleaned up later causes problems when memblock_free_all() is called to release free pages to the buddy allocator and those reserved regions are carried over to reserve_bootmem_region() which marks the pages as PageReserved.
Instead use memblock_set_current_limit() to make sure memblock allocations do not go over identity mapping (which could happen when "mem=" option is used or during kdump).
Cc: stable@vger.kernel.org Fixes: 73045a08cf55 ("s390: unify identity mapping limits handling") Reported-by: Gerald Schaefer gerald.schaefer@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kernel/setup.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
--- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -634,14 +634,6 @@ static struct notifier_block kdump_mem_n #endif
/* - * Make sure that the area above identity mapping is protected - */ -static void __init reserve_above_ident_map(void) -{ - memblock_reserve(ident_map_size, ULONG_MAX); -} - -/* * Reserve memory for kdump kernel to be loaded with kexec */ static void __init reserve_crashkernel(void) @@ -1005,11 +997,11 @@ void __init setup_arch(char **cmdline_p) setup_control_program_code();
/* Do some memory reservations *before* memory is added to memblock */ - reserve_above_ident_map(); reserve_kernel(); reserve_initrd(); reserve_certificate_list(); reserve_mem_detect_info(); + memblock_set_current_limit(ident_map_size); memblock_allow_resize();
/* Get information about *all* installed memory */
From: Vasily Gorbik gor@linux.ibm.com
commit 9a39abb7c9aab50eec4ac4421e9ee7f3de013d24 upstream.
Initial KASAN shadow memory range was picked to preserve original kernel modules area position. With protected execution support, which might impose addressing limitation on vmalloc area and hence affect modules area position, current fixed KASAN shadow memory range is only making kernel memory layout setup more complex. So move it to the very end of available virtual space and simplify calculations.
At the same time return to previous kernel address space split. In particular commit 0c4f2623b957 ("s390: setup kernel memory layout early") introduced precise identity map size calculation and keeping vmemmap left most starting from a fresh region table entry. This didn't take into account additional mapping region requirement for potential DCSS mapping above available physical memory. So go back to virtual space split between 1:1 mapping & vmemmap array once vmalloc area size is subtracted.
Cc: stable@vger.kernel.org Fixes: 0c4f2623b957 ("s390: setup kernel memory layout early") Reported-by: Gerald Schaefer gerald.schaefer@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Reviewed-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/Kconfig | 2 - arch/s390/boot/startup.c | 88 ++++++++++++++++------------------------------- 2 files changed, 32 insertions(+), 58 deletions(-)
--- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -47,7 +47,7 @@ config ARCH_SUPPORTS_UPROBES config KASAN_SHADOW_OFFSET hex depends on KASAN - default 0x18000000000000 + default 0x1C000000000000
config S390 def_bool y --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -148,82 +148,56 @@ static void setup_ident_map_size(unsigne
static void setup_kernel_memory_layout(void) { - bool vmalloc_size_verified = false; - unsigned long vmemmap_off; - unsigned long vspace_left; + unsigned long vmemmap_start; unsigned long rte_size; unsigned long pages; - unsigned long vmax;
pages = ident_map_size / PAGE_SIZE; /* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */ vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page);
/* choose kernel address space layout: 4 or 3 levels. */ - vmemmap_off = round_up(ident_map_size, _REGION3_SIZE); + vmemmap_start = round_up(ident_map_size, _REGION3_SIZE); if (IS_ENABLED(CONFIG_KASAN) || vmalloc_size > _REGION2_SIZE || - vmemmap_off + vmemmap_size + vmalloc_size + MODULES_LEN > _REGION2_SIZE) - vmax = _REGION1_SIZE; - else - vmax = _REGION2_SIZE; - - /* keep vmemmap_off aligned to a top level region table entry */ - rte_size = vmax == _REGION1_SIZE ? _REGION2_SIZE : _REGION3_SIZE; - MODULES_END = vmax; - if (is_prot_virt_host()) { - /* - * forcing modules and vmalloc area under the ultravisor - * secure storage limit, so that any vmalloc allocation - * we do could be used to back secure guest storage. - */ - adjust_to_uv_max(&MODULES_END); - } - -#ifdef CONFIG_KASAN - if (MODULES_END < vmax) { - /* force vmalloc and modules below kasan shadow */ - MODULES_END = min(MODULES_END, KASAN_SHADOW_START); + vmemmap_start + vmemmap_size + vmalloc_size + MODULES_LEN > + _REGION2_SIZE) { + MODULES_END = _REGION1_SIZE; + rte_size = _REGION2_SIZE; } else { - /* - * leave vmalloc and modules above kasan shadow but make - * sure they don't overlap with it - */ - vmalloc_size = min(vmalloc_size, vmax - KASAN_SHADOW_END - MODULES_LEN); - vmalloc_size_verified = true; - vspace_left = KASAN_SHADOW_START; + MODULES_END = _REGION2_SIZE; + rte_size = _REGION3_SIZE; } + /* + * forcing modules and vmalloc area under the ultravisor + * secure storage limit, so that any vmalloc allocation + * we do could be used to back secure guest storage. + */ + adjust_to_uv_max(&MODULES_END); +#ifdef CONFIG_KASAN + /* force vmalloc and modules below kasan shadow */ + MODULES_END = min(MODULES_END, KASAN_SHADOW_START); #endif MODULES_VADDR = MODULES_END - MODULES_LEN; VMALLOC_END = MODULES_VADDR;
- if (vmalloc_size_verified) { - VMALLOC_START = VMALLOC_END - vmalloc_size; - } else { - vmemmap_off = round_up(ident_map_size, rte_size); - - if (vmemmap_off + vmemmap_size > VMALLOC_END || - vmalloc_size > VMALLOC_END - vmemmap_off - vmemmap_size) { - /* - * allow vmalloc area to occupy up to 1/2 of - * the rest virtual space left. - */ - vmalloc_size = min(vmalloc_size, VMALLOC_END / 2); - } - VMALLOC_START = VMALLOC_END - vmalloc_size; - vspace_left = VMALLOC_START; - } + /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */ + vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE)); + VMALLOC_START = VMALLOC_END - vmalloc_size;
- pages = vspace_left / (PAGE_SIZE + sizeof(struct page)); + /* split remaining virtual space between 1:1 mapping & vmemmap array */ + pages = VMALLOC_START / (PAGE_SIZE + sizeof(struct page)); pages = SECTION_ALIGN_UP(pages); - vmemmap_off = round_up(vspace_left - pages * sizeof(struct page), rte_size); - /* keep vmemmap left most starting from a fresh region table entry */ - vmemmap_off = min(vmemmap_off, round_up(ident_map_size, rte_size)); - /* take care that identity map is lower then vmemmap */ - ident_map_size = min(ident_map_size, vmemmap_off); + /* keep vmemmap_start aligned to a top level region table entry */ + vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size); + /* vmemmap_start is the future VMEM_MAX_PHYS, make sure it is within MAX_PHYSMEM */ + vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS); + /* make sure identity map doesn't overlay with vmemmap */ + ident_map_size = min(ident_map_size, vmemmap_start); vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page); - VMALLOC_START = max(vmemmap_off + vmemmap_size, VMALLOC_START); - vmemmap = (struct page *)vmemmap_off; + /* make sure vmemmap doesn't overlay with vmalloc area */ + VMALLOC_START = max(vmemmap_start + vmemmap_size, VMALLOC_START); + vmemmap = (struct page *)vmemmap_start; }
/*
From: Sven Schnelle svens@linux.ibm.com
commit 00b55eaf45549ce26424224d069a091c7e5d8bac upstream.
When CONFIG_VMAP_STACK is disabled, the user can enable CONFIG_STACK_CHECK, which adds a stack overflow check to each C function in the kernel. This is also done for functions in the vdso page. These functions are run in user context and user stack sizes are usually different to what the kernel uses. This might trigger the stack check although the stack size is valid. Therefore filter the -mstack-guard and -mstack-size flags when compiling vdso C files.
Cc: stable@kernel.org # 5.10+ Fixes: 4bff8cb54502 ("s390: convert to GENERIC_VDSO") Reported-by: Janosch Frank frankja@linux.ibm.com 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/Makefile | 10 ++++++---- arch/s390/kernel/vdso64/Makefile | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-)
--- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -79,10 +79,12 @@ KBUILD_AFLAGS_DECOMPRESSOR += $(aflags-y KBUILD_CFLAGS_DECOMPRESSOR += $(cflags-y)
ifneq ($(call cc-option,-mstack-size=8192 -mstack-guard=128),) -cflags-$(CONFIG_CHECK_STACK) += -mstack-size=$(STACK_SIZE) -ifeq ($(call cc-option,-mstack-size=8192),) -cflags-$(CONFIG_CHECK_STACK) += -mstack-guard=$(CONFIG_STACK_GUARD) -endif + CC_FLAGS_CHECK_STACK := -mstack-size=$(STACK_SIZE) + ifeq ($(call cc-option,-mstack-size=8192),) + CC_FLAGS_CHECK_STACK += -mstack-guard=$(CONFIG_STACK_GUARD) + endif + export CC_FLAGS_CHECK_STACK + cflags-$(CONFIG_CHECK_STACK) += $(CC_FLAGS_CHECK_STACK) endif
ifdef CONFIG_EXPOLINE --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile @@ -8,8 +8,9 @@ ARCH_REL_TYPE_ABS += R_390_GOT|R_390_PLT include $(srctree)/lib/vdso/Makefile obj-vdso64 = vdso_user_wrapper.o note.o obj-cvdso64 = vdso64_generic.o getcpu.o -CFLAGS_REMOVE_getcpu.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) -CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) +VDSO_CFLAGS_REMOVE := -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE) $(CC_FLAGS_CHECK_STACK) +CFLAGS_REMOVE_getcpu.o = $(VDSO_CFLAGS_REMOVE) +CFLAGS_REMOVE_vdso64_generic.o = $(VDSO_CFLAGS_REMOVE)
# Build rules
From: Baoquan He bhe@redhat.com
commit 4aa9340584e37debef06fa99b56d064beb723891 upstream.
unreferenced object 0x38000195000 (size 4096): comm "kexec", pid 8548, jiffies 4294953647 (age 32443.270s) hex dump (first 32 bytes): 00 00 00 c8 20 00 00 00 00 00 00 c0 02 80 00 00 .... ........... 40 40 40 40 40 40 40 40 00 00 00 00 00 00 00 00 @@@@@@@@........ backtrace: [<0000000011a2f199>] __vmalloc_node_range+0xc0/0x140 [<0000000081fa2752>] vzalloc+0x5a/0x70 [<0000000063a4c92d>] ipl_report_finish+0x2c/0x180 [<00000000553304da>] kexec_file_add_ipl_report+0xf4/0x150 [<00000000862d033f>] kexec_file_add_components+0x124/0x160 [<000000000d2717bb>] arch_kexec_kernel_image_load+0x62/0x90 [<000000002e0373b6>] kimage_file_alloc_init+0x1aa/0x2e0 [<0000000060f2d14f>] __do_sys_kexec_file_load+0x17c/0x2c0 [<000000008c86fe5a>] __s390x_sys_kexec_file_load+0x40/0x50 [<000000001fdb9dac>] __do_syscall+0x1bc/0x1f0 [<000000003ee4258d>] system_call+0x78/0xa0
Signed-off-by: Baoquan He bhe@redhat.com Reviewed-by: Philipp Rudo prudo@redhat.com Fixes: 99feaa717e55 ("s390/kexec_file: Create ipl report and pass to next kernel") Cc: stable@vger.kernel.org # v5.2: 20c76e242e70: s390/kexec: fix return code handling Cc: stable@vger.kernel.org # v5.2 Link: https://lore.kernel.org/r/20211116033101.GD21646@MiWiFi-R3L-srv Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/include/asm/kexec.h | 6 ++++++ arch/s390/kernel/machine_kexec_file.c | 10 ++++++++++ 2 files changed, 16 insertions(+)
--- a/arch/s390/include/asm/kexec.h +++ b/arch/s390/include/asm/kexec.h @@ -74,6 +74,12 @@ void *kexec_file_add_components(struct k int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, unsigned long addr);
+#define ARCH_HAS_KIMAGE_ARCH + +struct kimage_arch { + void *ipl_buf; +}; + extern const struct kexec_file_ops s390_kexec_image_ops; extern const struct kexec_file_ops s390_kexec_elf_ops;
--- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -12,6 +12,7 @@ #include <linux/kexec.h> #include <linux/module_signature.h> #include <linux/verification.h> +#include <linux/vmalloc.h> #include <asm/boot_data.h> #include <asm/ipl.h> #include <asm/setup.h> @@ -206,6 +207,7 @@ static int kexec_file_add_ipl_report(str goto out; buf.bufsz = data->report->size; buf.memsz = buf.bufsz; + image->arch.ipl_buf = buf.buffer;
data->memsz += buf.memsz;
@@ -327,3 +329,11 @@ int arch_kexec_kernel_image_probe(struct
return kexec_image_probe_default(image, buf, buf_len); } + +int arch_kimage_file_post_load_cleanup(struct kimage *image) +{ + vfree(image->arch.ipl_buf); + image->arch.ipl_buf = NULL; + + return kexec_image_post_load_cleanup_default(image); +}
From: Alexander Egorenkov egorenar@linux.ibm.com
commit 3b90954419d4c05651de9cce6d7632bcf6977678 upstream.
This commit fixes a bug introduced by commit e9e7870f90e3 ("s390/dump: introduce boot data 'oldmem_data'"). OLDMEM_BASE was mistakenly replaced by oldmem_data.size instead of oldmem_data.start.
This bug caused the following error during kdump: kdump.sh[878]: No program header covering vaddr 0x3434f5245found kexec bug?
Fixes: e9e7870f90e3 ("s390/dump: introduce boot data 'oldmem_data'") Cc: stable@vger.kernel.org # 5.15+ Signed-off-by: Alexander Egorenkov egorenar@linux.ibm.com Reviewed-by: Marc Hartmayer mhartmay@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/kernel/crash_dump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -191,8 +191,8 @@ static int copy_oldmem_user(void __user return rc; } else { /* Check for swapped kdump oldmem areas */ - if (oldmem_data.start && from - oldmem_data.size < oldmem_data.size) { - from -= oldmem_data.size; + if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) { + from -= oldmem_data.start; len = min(count, oldmem_data.size - from); } else if (oldmem_data.start && from < oldmem_data.size) { len = min(count, oldmem_data.size - from);
From: Alistair Delva adelva@google.com
commit 94c4b4fd25e6c3763941bdec3ad54f2204afa992 upstream.
Booting to Android userspace on 5.14 or newer triggers the following SELinux denial:
avc: denied { sys_nice } for comm="init" capability=23 scontext=u:r:init:s0 tcontext=u:r:init:s0 tclass=capability permissive=0
Init is PID 0 running as root, so it already has CAP_SYS_ADMIN. For better compatibility with older SEPolicy, check ADMIN before NICE.
Fixes: 9d3a39a5f1e4 ("block: grant IOPRIO_CLASS_RT to CAP_SYS_NICE") Signed-off-by: Alistair Delva adelva@google.com Cc: Khazhismel Kumykov khazhy@google.com Cc: Bart Van Assche bvanassche@acm.org Cc: Serge Hallyn serge@hallyn.com Cc: Jens Axboe axboe@kernel.dk Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Paul Moore paul@paul-moore.com Cc: selinux@vger.kernel.org Cc: linux-security-module@vger.kernel.org Cc: kernel-team@android.com Cc: stable@vger.kernel.org # v5.14+ Reviewed-by: Bart Van Assche bvanassche@acm.org Acked-by: Serge Hallyn serge@hallyn.com Link: https://lore.kernel.org/r/20211115181655.3608659-1-adelva@google.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/ioprio.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/block/ioprio.c +++ b/block/ioprio.c @@ -69,7 +69,14 @@ int ioprio_check_cap(int ioprio)
switch (class) { case IOPRIO_CLASS_RT: - if (!capable(CAP_SYS_NICE) && !capable(CAP_SYS_ADMIN)) + /* + * Originally this only checked for CAP_SYS_ADMIN, + * which was implicitly allowed for pid 0 by security + * modules such as SELinux. Make sure we check + * CAP_SYS_ADMIN first to avoid a denial/avc for + * possibly missing CAP_SYS_NICE permission. + */ + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE)) return -EPERM; fallthrough; /* rt has prio field too */
From: Javier Martinez Canillas javierm@redhat.com
commit fb561bf9abde49f7e00fdbf9ed2ccf2d86cac8ee upstream.
The efifb and simplefb drivers just render to a pre-allocated frame buffer and rely on the display hardware being initialized before the kernel boots.
But if another driver already probed correctly and registered a fbdev, the generic drivers shouldn't be probed since an actual driver for the display hardware is already present.
This is more likely to occur after commit d391c5827107 ("drivers/firmware: move x86 Generic System Framebuffers support") since the "efi-framebuffer" and "simple-framebuffer" platform devices are registered at a later time.
Link: https://lore.kernel.org/r/20211110200253.rfudkt3edbd3nsyj@lahvuun/ Fixes: d391c5827107 ("drivers/firmware: move x86 Generic System Framebuffers support") Reported-by: Ilya Trukhanov lahvuun@gmail.com Cc: stable@vger.kernel.org # 5.15.x Signed-off-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Tested-by: Ilya Trukhanov lahvuun@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20211111115757.1351045-1-javie... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/fbdev/efifb.c | 11 +++++++++++ drivers/video/fbdev/simplefb.c | 11 +++++++++++ 2 files changed, 22 insertions(+)
--- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -351,6 +351,17 @@ static int efifb_probe(struct platform_d char *option = NULL; efi_memory_desc_t md;
+ /* + * Generic drivers must not be registered if a framebuffer exists. + * If a native driver was probed, the display hardware was already + * taken and attempting to use the system framebuffer is dangerous. + */ + if (num_registered_fb > 0) { + dev_err(&dev->dev, + "efifb: a framebuffer is already registered\n"); + return -EINVAL; + } + if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled) return -ENODEV;
--- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -407,6 +407,17 @@ static int simplefb_probe(struct platfor struct simplefb_par *par; struct resource *mem;
+ /* + * Generic drivers must not be registered if a framebuffer exists. + * If a native driver was probed, the display hardware was already + * taken and attempting to use the system framebuffer is dangerous. + */ + if (num_registered_fb > 0) { + dev_err(&pdev->dev, + "simplefb: a framebuffer is already registered\n"); + return -EINVAL; + } + if (fb_get_options("simplefb", NULL)) return -ENODEV;
From: Sean Christopherson seanjc@google.com
commit 79b11142763791bdead8b6460052cbdde8e08e2f upstream.
Reject COPY_ENC_CONTEXT_FROM if the destination VM has created vCPUs. KVM relies on SEV activation to occur before vCPUs are created, e.g. to set VMCB flags and intercepts correctly.
Fixes: 54526d1fd593 ("KVM: x86: Support KVM VMs sharing SEV context") Cc: stable@vger.kernel.org Cc: Peter Gonda pgonda@google.com Cc: Marc Orr marcorr@google.com Cc: Sean Christopherson seanjc@google.com Cc: Nathan Tempelman natet@google.com Cc: Brijesh Singh brijesh.singh@amd.com Cc: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211109215101.2211373-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/svm/sev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -1787,7 +1787,12 @@ int svm_vm_copy_asid_from(struct kvm *kv mutex_unlock(&source_kvm->lock); mutex_lock(&kvm->lock);
- if (sev_guest(kvm)) { + /* + * Disallow out-of-band SEV/SEV-ES init if the target is already an + * SEV guest, or if vCPUs have been created. KVM relies on vCPUs being + * created after SEV/SEV-ES initialization, e.g. to init intercepts. + */ + if (sev_guest(kvm) || kvm->created_vcpus) { ret = -EINVAL; goto e_mirror_unlock; }
From: Maxim Levitsky mlevitsk@redhat.com
commit af957eebfcc17433ee83ab85b1195a933ab5049c upstream.
When loading nested state, don't use check vcpu->arch.efer to get the L1 host's 64-bit vs. 32-bit state and don't check it for consistency with respect to VM_EXIT_HOST_ADDR_SPACE_SIZE, as register state in vCPU may be stale when KVM_SET_NESTED_STATE is called---and architecturally does not exist. When restoring L2 state in KVM, the CPU is placed in non-root where nested VMX code has no snapshot of L1 host state: VMX (conditionally) loads host state fields loaded on VM-exit, but they need not correspond to the state before entry. A simple case occurs in KVM itself, where the host RIP field points to vmx_vmexit rather than the instruction following vmlaunch/vmresume.
However, for the particular case of L1 being in 32- or 64-bit mode on entry, the exit controls can be treated instead as the source of truth regarding the state of L1 on entry, and can be used to check that vmcs12.VM_EXIT_HOST_ADDR_SPACE_SIZE matches vmcs12.HOST_EFER if vmcs12.VM_EXIT_LOAD_IA32_EFER is set. The consistency check on CPU EFER vs. vmcs12.VM_EXIT_HOST_ADDR_SPACE_SIZE, instead, happens only on VM-Enter. That's because, again, there's conceptually no "current" L1 EFER to check on KVM_SET_NESTED_STATE.
Suggested-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Maxim Levitsky mlevitsk@redhat.com Message-Id: 20211115131837.195527-2-mlevitsk@redhat.com Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
--- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2854,6 +2854,17 @@ static int nested_vmx_check_controls(str return 0; }
+static int nested_vmx_check_address_space_size(struct kvm_vcpu *vcpu, + struct vmcs12 *vmcs12) +{ +#ifdef CONFIG_X86_64 + if (CC(!!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) != + !!(vcpu->arch.efer & EFER_LMA))) + return -EINVAL; +#endif + return 0; +} + static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) { @@ -2878,18 +2889,16 @@ static int nested_vmx_check_host_state(s return -EINVAL;
#ifdef CONFIG_X86_64 - ia32e = !!(vcpu->arch.efer & EFER_LMA); + ia32e = !!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE); #else ia32e = false; #endif
if (ia32e) { - if (CC(!(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE)) || - CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) + if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE))) return -EINVAL; } else { - if (CC(vmcs12->vm_exit_controls & VM_EXIT_HOST_ADDR_SPACE_SIZE) || - CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || + if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) || CC(vmcs12->host_cr4 & X86_CR4_PCIDE) || CC((vmcs12->host_rip) >> 32)) return -EINVAL; @@ -3559,6 +3568,9 @@ static int nested_vmx_run(struct kvm_vcp if (nested_vmx_check_controls(vcpu, vmcs12)) return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
+ if (nested_vmx_check_address_space_size(vcpu, vmcs12)) + return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD); + if (nested_vmx_check_host_state(vcpu, vmcs12)) return nested_vmx_fail(vcpu, VMXERR_ENTRY_INVALID_HOST_STATE_FIELD);
From: Thomas Zimmermann tzimmermann@suse.de
commit 995f54ea962e03ec08b8bc6a4fe11a32b420edd3 upstream.
The GEM CMA helpers allocate non-coherent (i.e., cached) backing storage with dma_alloc_noncoherent(), but release it with dma_free_wc(). Fix this with a call to dma_free_noncoherent(). Writecombining storage is still released with dma_free_wc().
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: cf8ccbc72d61 ("drm: Add support for GEM buffers backed by non-coherent memory") Acked-by: Paul Cercueil paul@crapouillou.net Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Maxime Ripard mripard@kernel.org Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v5.14+ Link: https://patchwork.freedesktop.org/patch/msgid/20210708175146.10618-1-tzimmer... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_gem_cma_helper.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -210,8 +210,13 @@ void drm_gem_cma_free_object(struct drm_ dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map); drm_prime_gem_destroy(gem_obj, cma_obj->sgt); } else if (cma_obj->vaddr) { - dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, - cma_obj->vaddr, cma_obj->paddr); + if (cma_obj->map_noncoherent) + dma_free_noncoherent(gem_obj->dev->dev, cma_obj->base.size, + cma_obj->vaddr, cma_obj->paddr, + DMA_TO_DEVICE); + else + dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, + cma_obj->vaddr, cma_obj->paddr); }
drm_gem_object_release(gem_obj);
From: Nicholas Piggin npiggin@gmail.com
commit 5d5e4522a7f404d1a96fd6c703989d32a9c9568d upstream.
printk from NMI context relies on irq work being raised on the local CPU to print to console. This can be a problem if the NMI was raised by a lockup detector to print lockup stack and regs, because the CPU may not enable irqs (because it is locked up).
Introduce printk_trigger_flush() that can be called another CPU to try to get those messages to the console, call that where printk_safe_flush was previously called.
Fixes: 93d102f094be ("printk: remove safe buffers") Cc: stable@vger.kernel.org # 5.15 Signed-off-by: Nicholas Piggin npiggin@gmail.com Reviewed-by: Petr Mladek pmladek@suse.com Reviewed-by: John Ogness john.ogness@linutronix.de Signed-off-by: Petr Mladek pmladek@suse.com Link: https://lore.kernel.org/r/20211107045116.1754411-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/watchdog.c | 6 ++++++ include/linux/printk.h | 4 ++++ kernel/printk/printk.c | 5 +++++ lib/nmi_backtrace.c | 6 ++++++ 4 files changed, 21 insertions(+)
--- a/arch/powerpc/kernel/watchdog.c +++ b/arch/powerpc/kernel/watchdog.c @@ -187,6 +187,12 @@ static void watchdog_smp_panic(int cpu, if (sysctl_hardlockup_all_cpu_backtrace) trigger_allbutself_cpu_backtrace();
+ /* + * Force flush any remote buffers that might be stuck in IRQ context + * and therefore could not run their irq_work. + */ + printk_trigger_flush(); + if (hardlockup_panic) nmi_panic(NULL, "Hard LOCKUP");
--- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -198,6 +198,7 @@ void dump_stack_print_info(const char *l void show_regs_print_info(const char *log_lvl); extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; extern asmlinkage void dump_stack(void) __cold; +void printk_trigger_flush(void); #else static inline __printf(1, 0) int vprintk(const char *s, va_list args) @@ -274,6 +275,9 @@ static inline void dump_stack_lvl(const static inline void dump_stack(void) { } +static inline void printk_trigger_flush(void) +{ +} #endif
#ifdef CONFIG_SMP --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3252,6 +3252,11 @@ void defer_console_output(void) preempt_enable(); }
+void printk_trigger_flush(void) +{ + defer_console_output(); +} + int vprintk_deferred(const char *fmt, va_list args) { int r; --- a/lib/nmi_backtrace.c +++ b/lib/nmi_backtrace.c @@ -75,6 +75,12 @@ void nmi_trigger_cpumask_backtrace(const touch_softlockup_watchdog(); }
+ /* + * Force flush any remote buffers that might be stuck in IRQ context + * and therefore could not run their irq_work. + */ + printk_trigger_flush(); + clear_bit_unlock(0, &backtrace_flag); put_cpu(); }
From: Jan Kara jack@suse.cz
commit a48fc69fe6588b48d878d69de223b91a386a7cb4 upstream.
udf_readdir() didn't validate the directory position it should start reading from. Thus when user uses lseek(2) on directory file descriptor it can trick udf_readdir() into reading from a position in the middle of directory entry which then upsets directory parsing code resulting in errors or even possible kernel crashes. Similarly when the directory is modified between two readdir calls, the directory position need not be valid anymore.
Add code to validate current offset in the directory. This is actually rather expensive for UDF as we need to read from the beginning of the directory and parse all directory entries. This is because in UDF a directory is just a stream of data containing directory entries and since file names are fully under user's control we cannot depend on detecting magic numbers and checksums in the header of directory entry as a malicious attacker could fake them. We skip this step if we detect that nothing changed since the last readdir call.
Reported-by: Nathan Wilson nate@chickenbrittle.com CC: stable@vger.kernel.org Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/udf/dir.c | 32 ++++++++++++++++++++++++++++++-- fs/udf/namei.c | 3 +++ fs/udf/super.c | 2 ++ 3 files changed, 35 insertions(+), 2 deletions(-)
--- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -31,6 +31,7 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/bio.h> +#include <linux/iversion.h>
#include "udf_i.h" #include "udf_sb.h" @@ -43,7 +44,7 @@ static int udf_readdir(struct file *file struct fileIdentDesc *fi = NULL; struct fileIdentDesc cfi; udf_pblk_t block, iblock; - loff_t nf_pos; + loff_t nf_pos, emit_pos = 0; int flen; unsigned char *fname = NULL, *copy_name = NULL; unsigned char *nameptr; @@ -57,6 +58,7 @@ static int udf_readdir(struct file *file int i, num, ret = 0; struct extent_position epos = { NULL, 0, {0, 0} }; struct super_block *sb = dir->i_sb; + bool pos_valid = false;
if (ctx->pos == 0) { if (!dir_emit_dot(file, ctx)) @@ -67,6 +69,21 @@ static int udf_readdir(struct file *file if (nf_pos >= size) goto out;
+ /* + * Something changed since last readdir (either lseek was called or dir + * changed)? We need to verify the position correctly points at the + * beginning of some dir entry so that the directory parsing code does + * not get confused. Since UDF does not have any reliable way of + * identifying beginning of dir entry (names are under user control), + * we need to scan the directory from the beginning. + */ + if (!inode_eq_iversion(dir, file->f_version)) { + emit_pos = nf_pos; + nf_pos = 0; + } else { + pos_valid = true; + } + fname = kmalloc(UDF_NAME_LEN, GFP_NOFS); if (!fname) { ret = -ENOMEM; @@ -122,13 +139,21 @@ static int udf_readdir(struct file *file
while (nf_pos < size) { struct kernel_lb_addr tloc; + loff_t cur_pos = nf_pos;
- ctx->pos = (nf_pos >> 2) + 1; + /* Update file position only if we got past the current one */ + if (nf_pos >= emit_pos) { + ctx->pos = (nf_pos >> 2) + 1; + pos_valid = true; + }
fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset); if (!fi) goto out; + /* Still not at offset where user asked us to read from? */ + if (cur_pos < emit_pos) + continue;
liu = le16_to_cpu(cfi.lengthOfImpUse); lfi = cfi.lengthFileIdent; @@ -186,8 +211,11 @@ static int udf_readdir(struct file *file } /* end while */
ctx->pos = (nf_pos >> 2) + 1; + pos_valid = true;
out: + if (pos_valid) + file->f_version = inode_query_iversion(dir); if (fibh.sbh != fibh.ebh) brelse(fibh.ebh); brelse(fibh.sbh); --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -30,6 +30,7 @@ #include <linux/sched.h> #include <linux/crc-itu-t.h> #include <linux/exportfs.h> +#include <linux/iversion.h>
static inline int udf_match(int len1, const unsigned char *name1, int len2, const unsigned char *name2) @@ -134,6 +135,8 @@ int udf_write_fi(struct inode *inode, st mark_buffer_dirty_inode(fibh->ebh, inode); mark_buffer_dirty_inode(fibh->sbh, inode); } + inode_inc_iversion(inode); + return 0; }
--- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -57,6 +57,7 @@ #include <linux/crc-itu-t.h> #include <linux/log2.h> #include <asm/byteorder.h> +#include <linux/iversion.h>
#include "udf_sb.h" #include "udf_i.h" @@ -149,6 +150,7 @@ static struct inode *udf_alloc_inode(str init_rwsem(&ei->i_data_sem); ei->cached_extent.lstart = -1; spin_lock_init(&ei->i_extent_cache_lock); + inode_set_iversion(&ei->vfs_inode, 1);
return &ei->vfs_inode; }
From: Michael Walle michael@walle.cc
commit 6c53b45c71b4920b5e62f0ea8079a1da382b9434 upstream.
Commit 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses") introduced a per-controller mutex. But mutex_unlock() of said lock is called after the controller is already freed:
spi_unregister_controller(ctlr) -> put_device(&ctlr->dev) -> spi_controller_release(dev) -> mutex_unlock(&ctrl->add_lock)
Move the put_device() after the mutex_unlock().
Fixes: 6098475d4cb4 ("spi: Fix deadlock when adding SPI controllers on SPI buses") Signed-off-by: Michael Walle michael@walle.cc Reviewed-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Reviewed-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v5.15 Link: https://lore.kernel.org/r/20211111083713.3335171-1-michael@walle.cc Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/spi/spi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3020,12 +3020,6 @@ void spi_unregister_controller(struct sp
device_del(&ctlr->dev);
- /* Release the last reference on the controller if its driver - * has not yet been converted to devm_spi_alloc_master/slave(). - */ - if (!ctlr->devm_allocated) - put_device(&ctlr->dev); - /* free bus id */ mutex_lock(&board_lock); if (found == ctlr) @@ -3034,6 +3028,12 @@ void spi_unregister_controller(struct sp
if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) mutex_unlock(&ctlr->add_lock); + + /* Release the last reference on the controller if its driver + * has not yet been converted to devm_spi_alloc_master/slave(). + */ + if (!ctlr->devm_allocated) + put_device(&ctlr->dev); } EXPORT_SYMBOL_GPL(spi_unregister_controller);
From: Meng Li meng.li@windriver.com
commit 9119570039481d56350af1c636f040fb300b8cf3 upstream.
According to upstream commit 5ec55823438e("net: stmmac: add clocks management for gmac driver"), it improve clocks management for stmmac driver. So, it is necessary to implement the runtime callback in dwmac-socfpga driver because it doesn't use the common stmmac_pltfr_pm_ops instance. Otherwise, clocks are not disabled when system enters suspend status.
Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver") Cc: stable@vger.kernel.org Signed-off-by: Meng Li Meng.Li@windriver.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -485,8 +485,28 @@ static int socfpga_dwmac_resume(struct d } #endif /* CONFIG_PM_SLEEP */
-static SIMPLE_DEV_PM_OPS(socfpga_dwmac_pm_ops, stmmac_suspend, - socfpga_dwmac_resume); +static int __maybe_unused socfpga_dwmac_runtime_suspend(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); + + stmmac_bus_clks_config(priv, false); + + return 0; +} + +static int __maybe_unused socfpga_dwmac_runtime_resume(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); + + return stmmac_bus_clks_config(priv, true); +} + +static const struct dev_pm_ops socfpga_dwmac_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(stmmac_suspend, socfpga_dwmac_resume) + SET_RUNTIME_PM_OPS(socfpga_dwmac_runtime_suspend, socfpga_dwmac_runtime_resume, NULL) +};
static const struct socfpga_dwmac_ops socfpga_gen5_ops = { .set_phy_mode = socfpga_gen5_set_phy_mode,
From: Boqun Feng boqun.feng@gmail.com
commit 8a7eb2d476c6823cd44d8c25a6230a52417d7ef8 upstream.
Baihua reported an error when boot an ARM64 guest with PAGE_SIZE=64k and BALLOON is enabled:
hv_vmbus: registering driver hv_balloon hv_vmbus: probe failed for device 1eccfd72-4b41-45ef-b73a-4a6e44c12924 (-22)
The cause of this is that the ringbuffer size for hv_balloon is not adjusted with VMBUS_RING_SIZE(), which makes the size not large enough for ringbuffers on guest with PAGE_SIZE=64k. Therefore use VMBUS_RING_SIZE() to calculate the ringbuffer size. Note that the old size (20 * 1024) counts a 4k header in the total size, while VMBUS_RING_SIZE() expects the parameter as the payload size, so use 16 * 1024.
Cc: stable@vger.kernel.org # 5.15.x Reported-by: Baihua Lu baihua.lu@microsoft.com Signed-off-by: Boqun Feng boqun.feng@gmail.com Tested-by: Vitaly Kuznetsov vkuznets@redhat.com Link: https://lore.kernel.org/r/20211101150026.736124-1-boqun.feng@gmail.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hv/hv_balloon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -480,7 +480,7 @@ module_param(pressure_report_delay, uint MODULE_PARM_DESC(pressure_report_delay, "Delay in secs in reporting pressure"); static atomic_t trans_id = ATOMIC_INIT(0);
-static int dm_ring_size = 20 * 1024; +static int dm_ring_size = VMBUS_RING_SIZE(16 * 1024);
/* * Driver specific state.
From: Nikolay Borisov nborisov@suse.com
commit 45da9c1767ac31857df572f0a909fbe88fd5a7e9 upstream.
Ordered work functions aren't guaranteed to be handled by the same thread which executed the normal work functions. The only way execution between normal/ordered functions is synchronized is via the WORK_DONE_BIT, unfortunately the used bitops don't guarantee any ordering whatsoever.
This manifested as seemingly inexplicable crashes on ARM64, where async_chunk::inode is seen as non-null in async_cow_submit which causes submit_compressed_extents to be called and crash occurs because async_chunk::inode suddenly became NULL. The call trace was similar to:
pc : submit_compressed_extents+0x38/0x3d0 lr : async_cow_submit+0x50/0xd0 sp : ffff800015d4bc20
<registers omitted for brevity>
Call trace: submit_compressed_extents+0x38/0x3d0 async_cow_submit+0x50/0xd0 run_ordered_work+0xc8/0x280 btrfs_work_helper+0x98/0x250 process_one_work+0x1f0/0x4ac worker_thread+0x188/0x504 kthread+0x110/0x114 ret_from_fork+0x10/0x18
Fix this by adding respective barrier calls which ensure that all accesses preceding setting of WORK_DONE_BIT are strictly ordered before setting the flag. At the same time add a read barrier after reading of WORK_DONE_BIT in run_ordered_work which ensures all subsequent loads would be strictly ordered after reading the bit. This in turn ensures are all accesses before WORK_DONE_BIT are going to be strictly ordered before any access that can occur in ordered_func.
Reported-by: Chris Murphy lists@colorremedies.com Fixes: 08a9ff326418 ("btrfs: Added btrfs_workqueue_struct implemented ordered execution based on kernel workqueue") CC: stable@vger.kernel.org # 4.4+ Link: https://bugzilla.redhat.com/show_bug.cgi?id=2011928 Reviewed-by: Josef Bacik josef@toxicpanda.com Tested-by: Chris Murphy chris@colorremedies.com Signed-off-by: Nikolay Borisov nborisov@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/async-thread.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -234,6 +234,13 @@ static void run_ordered_work(struct __bt ordered_list); if (!test_bit(WORK_DONE_BIT, &work->flags)) break; + /* + * Orders all subsequent loads after reading WORK_DONE_BIT, + * paired with the smp_mb__before_atomic in btrfs_work_helper + * this guarantees that the ordered function will see all + * updates from ordinary work function. + */ + smp_rmb();
/* * we are going to call the ordered done function, but @@ -317,6 +324,13 @@ static void btrfs_work_helper(struct wor thresh_exec_hook(wq); work->func(work); if (need_order) { + /* + * Ensures all memory accesses done in the work function are + * ordered before setting the WORK_DONE_BIT. Ensuring the thread + * which is going to executed the ordered work sees them. + * Pairs with the smp_rmb in run_ordered_work. + */ + smp_mb__before_atomic(); set_bit(WORK_DONE_BIT, &work->flags); run_ordered_work(wq, work); } else {
From: Christian Brauner christian.brauner@ubuntu.com
commit 968219708108440b23bc292e0486e3cc1d9a1bed upstream.
When calling setattr_prepare() to determine the validity of the attributes the ia_{g,u}id fields contain the value that will be written to inode->i_{g,u}id. When the {g,u}id attribute of the file isn't altered and the caller's fs{g,u}id matches the current {g,u}id attribute the attribute change is allowed.
The value in ia_{g,u}id does already account for idmapped mounts and will have taken the relevant idmapping into account. So in order to verify that the {g,u}id attribute isn't changed we simple need to compare the ia_{g,u}id value against the inode's i_{g,u}id value.
This only has any meaning for idmapped mounts as idmapping helpers are idempotent without them. And for idmapped mounts this really only has a meaning when circular idmappings are used, i.e. mappings where e.g. id 1000 is mapped to id 1001 and id 1001 is mapped to id 1000. Such ciruclar mappings can e.g. be useful when sharing the same home directory between multiple users at the same time.
As an example consider a directory with two files: /source/file1 owned by {g,u}id 1000 and /source/file2 owned by {g,u}id 1001. Assume we create an idmapped mount at /target with an idmapping that maps files owned by {g,u}id 1000 to being owned by {g,u}id 1001 and files owned by {g,u}id 1001 to being owned by {g,u}id 1000. In effect, the idmapped mount at /target switches the ownership of /source/file1 and source/file2, i.e. /target/file1 will be owned by {g,u}id 1001 and /target/file2 will be owned by {g,u}id 1000.
This means that a user with fs{g,u}id 1000 must be allowed to setattr /target/file2 from {g,u}id 1000 to {g,u}id 1000. Similar, a user with fs{g,u}id 1001 must be allowed to setattr /target/file1 from {g,u}id 1001 to {g,u}id 1001. Conversely, a user with fs{g,u}id 1000 must fail to setattr /target/file1 from {g,u}id 1001 to {g,u}id 1000. And a user with fs{g,u}id 1001 must fail to setattr /target/file2 from {g,u}id 1000 to {g,u}id 1000. Both cases must fail with EPERM for non-capable callers.
Before this patch we could end up denying legitimate attribute changes and allowing invalid attribute changes when circular mappings are used. To even get into this situation the caller must've been privileged both to create that mapping and to create that idmapped mount.
This hasn't been seen in the wild anywhere but came up when expanding the testsuite during work on a series of hardening patches. All idmapped fstests pass without any regressions and we add new tests to verify the behavior of circular mappings.
Link: https://lore.kernel.org/r/20211109145713.1868404-1-brauner@kernel.org Fixes: 2f221d6f7b88 ("attr: handle idmapped mounts") Cc: Seth Forshee seth.forshee@digitalocean.com Cc: Christoph Hellwig hch@lst.de Cc: Al Viro viro@zeniv.linux.org.uk Cc: stable@vger.kernel.org CC: linux-fsdevel@vger.kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Acked-by: Seth Forshee sforshee@digitalocean.com Signed-off-by: Christian Brauner christian.brauner@ubuntu.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/attr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/attr.c +++ b/fs/attr.c @@ -35,7 +35,7 @@ static bool chown_ok(struct user_namespa kuid_t uid) { kuid_t kuid = i_uid_into_mnt(mnt_userns, inode); - if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, kuid)) + if (uid_eq(current_fsuid(), kuid) && uid_eq(uid, inode->i_uid)) return true; if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) return true; @@ -62,7 +62,7 @@ static bool chgrp_ok(struct user_namespa { kgid_t kgid = i_gid_into_mnt(mnt_userns, inode); if (uid_eq(current_fsuid(), i_uid_into_mnt(mnt_userns, inode)) && - (in_group_p(gid) || gid_eq(gid, kgid))) + (in_group_p(gid) || gid_eq(gid, inode->i_gid))) return true; if (capable_wrt_inode_uidgid(mnt_userns, inode, CAP_CHOWN)) return true;
From: Thomas Gleixner tglx@linutronix.de
commit 3751c3d34cd5a750c86d1c8eaf217d8faf7f9325 upstream.
The recent addition of timestamp correction to compensate the CDC error introduced a subtle signed/unsigned bug in stmmac_get_tx_hwtstamp() while it managed for some obscure reason to avoid that in stmmac_get_rx_hwtstamp().
The issue is:
s64 adjust = 0; u64 ns;
adjust += -(2 * (NSEC_PER_SEC / priv->plat->clk_ptp_rate)); ns += adjust;
works by chance on 64bit, but falls apart on 32bit because the compiler knows that adjust fits into 32bit and then treats the addition as a u64 + u32 resulting in an off by ~2 seconds failure.
The RX variant uses an u64 for adjust and does the adjustment via
ns -= adjust;
because consistency is obviously overrated.
Get rid of the pointless zero initialized adjust variable and do:
ns -= (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate;
which is obviously correct and spares the adjust obfuscation. Aside of that it yields a more accurate result because the multiplication takes place before the integer divide truncation and not afterwards.
Stick the calculation into an inline so it can't be accidentally disimproved. Return an u32 from that inline as the result is guaranteed to fit which lets the compiler optimize the substraction.
Cc: stable@vger.kernel.org Fixes: 3600be5f58c1 ("net: stmmac: add timestamp correction to rid CDC sync error") Reported-by: Benedikt Spranger b.spranger@linutronix.de Signed-off-by: Thomas Gleixner tglx@linutronix.de Tested-by: Benedikt Spranger b.spranger@linutronix.de Tested-by: Kurt Kanzenbach kurt@linutronix.de # Intel EHL Link: https://lore.kernel.org/r/87mtm578cs.ffs@tglx Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 23 +++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -511,6 +511,14 @@ bool stmmac_eee_init(struct stmmac_priv return true; }
+static inline u32 stmmac_cdc_adjust(struct stmmac_priv *priv) +{ + /* Correct the clk domain crossing(CDC) error */ + if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) + return (2 * NSEC_PER_SEC) / priv->plat->clk_ptp_rate; + return 0; +} + /* stmmac_get_tx_hwtstamp - get HW TX timestamps * @priv: driver private structure * @p : descriptor pointer @@ -524,7 +532,6 @@ static void stmmac_get_tx_hwtstamp(struc { struct skb_shared_hwtstamps shhwtstamp; bool found = false; - s64 adjust = 0; u64 ns = 0;
if (!priv->hwts_tx_en) @@ -543,12 +550,7 @@ static void stmmac_get_tx_hwtstamp(struc }
if (found) { - /* Correct the clk domain crossing(CDC) error */ - if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) { - adjust += -(2 * (NSEC_PER_SEC / - priv->plat->clk_ptp_rate)); - ns += adjust; - } + ns -= stmmac_cdc_adjust(priv);
memset(&shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); shhwtstamp.hwtstamp = ns_to_ktime(ns); @@ -573,7 +575,6 @@ static void stmmac_get_rx_hwtstamp(struc { struct skb_shared_hwtstamps *shhwtstamp = NULL; struct dma_desc *desc = p; - u64 adjust = 0; u64 ns = 0;
if (!priv->hwts_rx_en) @@ -586,11 +587,7 @@ static void stmmac_get_rx_hwtstamp(struc if (stmmac_get_rx_timestamp_status(priv, p, np, priv->adv_ts)) { stmmac_get_timestamp(priv, desc, priv->adv_ts, &ns);
- /* Correct the clk domain crossing(CDC) error */ - if (priv->plat->has_gmac4 && priv->plat->clk_ptp_rate) { - adjust += 2 * (NSEC_PER_SEC / priv->plat->clk_ptp_rate); - ns -= adjust; - } + ns -= stmmac_cdc_adjust(priv);
netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); shhwtstamp = skb_hwtstamps(skb);
From: Sven Schnelle svens@stackframe.org
commit bec05f33ebc1006899c6d3e59a00c58881fe7626 upstream.
sticon_build_attr() checked the reverse argument and flipped background and foreground color, but returned the non-reverse value afterwards. Fix this and also add two local variables for foreground and background color to make the code easier to read.
Signed-off-by: Sven Schnelle svens@stackframe.org Cc: stable@vger.kernel.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/console/sticon.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -332,13 +332,13 @@ static u8 sticon_build_attr(struct vc_da bool blink, bool underline, bool reverse, bool italic) { - u8 attr = ((color & 0x70) >> 1) | ((color & 7)); + u8 fg = color & 7; + u8 bg = (color & 0x70) >> 4;
- if (reverse) { - color = ((color >> 3) & 0x7) | ((color & 0x7) << 3); - } - - return attr; + if (reverse) + return (fg << 3) | bg; + else + return (bg << 3) | fg; }
static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
From: Nguyen Dinh Phi phind.uet@gmail.com
commit 563fbefed46ae4c1f70cffb8eb54c02df480b2c2 upstream.
If the userspace tools switch from NL80211_IFTYPE_P2P_GO to NL80211_IFTYPE_ADHOC via send_msg(NL80211_CMD_SET_INTERFACE), it does not call the cleanup cfg80211_stop_ap(), this leads to the initialization of in-use data. For example, this path re-init the sdata->assigned_chanctx_list while it is still an element of assigned_vifs list, and makes that linked list corrupt.
Signed-off-by: Nguyen Dinh Phi phind.uet@gmail.com Reported-by: syzbot+bbf402b783eeb6d908db@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20211027173722.777287-1-phind.uet@gmail.com Cc: stable@vger.kernel.org Fixes: ac800140c20e ("cfg80211: .stop_ap when interface is going down") Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/wireless/util.c | 1 + 1 file changed, 1 insertion(+)
--- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1044,6 +1044,7 @@ int cfg80211_change_iface(struct cfg8021
switch (otype) { case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: cfg80211_stop_ap(rdev, dev, true); break; case NL80211_IFTYPE_ADHOC:
From: Johannes Berg johannes.berg@intel.com
commit c033a38a81bc539d6c0db8c5387e0b14d819a0cf upstream.
In commit 8c89f7b3d3f2 ("mac80211: Use flex-array for radiotap header bitmap") we accidentally pointed the position to the wrong place, so we overwrite a present bitmap, and thus cause all kinds of trouble.
To see the issue, note that the previous code read:
pos = (void *)(it_present + 1);
The requirement now is that we need to calculate pos via it_optional, to not trigger the compiler hardening checks, as:
pos = (void *)&rthdr->it_optional[...];
Rewriting the original expression, we get (obviously, since that just adds "+ x - x" terms):
pos = (void *)(it_present + 1 + rthdr->it_optional - rthdr->it_optional)
and moving the "+ rthdr->it_optional" outside to be used as an array:
pos = (void *)&rthdr->it_optional[it_present + 1 - rthdr->it_optional];
The original is off by one, fix it.
Cc: stable@vger.kernel.org Fixes: 8c89f7b3d3f2 ("mac80211: Use flex-array for radiotap header bitmap") Reported-by: Sid Hayn sidhayn@gmail.com Signed-off-by: Johannes Berg johannes.berg@intel.com Tested-by: Sid Hayn sidhayn@gmail.com Reviewed-by: Kees Cook keescook@chromium.org Link: https://lore.kernel.org/r/20211109100203.c61007433ed6.I1dade57aba7de9c4f48d6... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mac80211/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -364,7 +364,7 @@ ieee80211_add_rx_radiotap_header(struct * the compiler to think we have walked past the end of the * struct member. */ - pos = (void *)&rthdr->it_optional[it_present - rthdr->it_optional]; + pos = (void *)&rthdr->it_optional[it_present + 1 - rthdr->it_optional];
/* the order of the following fields is important */
From: Felix Fietkau nbd@nbd.name
commit f6ab25d41b18f3d26883cb9c20875e1a85c4f05b upstream.
When __ieee80211_select_queue is called, skb->cb has not been cleared yet, which means that info->control.flags can contain garbage. In some cases this leads to IEEE80211_TX_CTRL_DONT_REORDER being set, causing packets marked for other queues to randomly end up in BE instead.
This flag only needs to be checked in ieee80211_select_queue_80211, since the radiotap parser is the only piece of code that sets it
Fixes: 66d06c84730c ("mac80211: adhere to Tx control flag that prevents frame reordering") Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Link: https://lore.kernel.org/r/20211110212201.35452-1-nbd@nbd.name Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mac80211/wme.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -143,7 +143,6 @@ u16 ieee80211_select_queue_80211(struct u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct sk_buff *skb) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mac80211_qos_map *qos_map; bool qos;
@@ -156,7 +155,7 @@ u16 __ieee80211_select_queue(struct ieee else qos = false;
- if (!qos || (info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER)) { + if (!qos) { skb->priority = 0; /* required for correct WPA/11i MIC */ return IEEE80211_AC_BE; }
From: Alvin Lee Alvin.Lee2@amd.com
commit 58065a1e524de30df9a2d8214661d5d7eed0a2d9 upstream.
[Why] Swizzle mode enum for DC_SW_VAR_R_X was existing, but not mapped correctly.
[How] Update mapping and conversion for DC_SW_VAR_R_X.
Reviewed-by: XiangBing Foo XiangBing.Foo@amd.com Reviewed-by: Martin Leung Martin.Leung@amd.com Acked-by: Qingqing Zhuo qingqing.zhuo@amd.com Signed-off-by: Alvin Lee Alvin.Lee2@amd.com Cc: stable@vger.kernel.org Tested-by: Daniel Wheeler Daniel.Wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 4 +++- drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -1854,7 +1854,9 @@ static void swizzle_to_dml_params( case DC_SW_VAR_D_X: *sw_mode = dm_sw_var_d_x; break; - + case DC_SW_VAR_R_X: + *sw_mode = dm_sw_var_r_x; + break; default: ASSERT(0); /* Not supported */ break; --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_enums.h @@ -80,11 +80,11 @@ enum dm_swizzle_mode { dm_sw_SPARE_13 = 24, dm_sw_64kb_s_x = 25, dm_sw_64kb_d_x = 26, - dm_sw_SPARE_14 = 27, + dm_sw_64kb_r_x = 27, dm_sw_SPARE_15 = 28, dm_sw_var_s_x = 29, dm_sw_var_d_x = 30, - dm_sw_64kb_r_x, + dm_sw_var_r_x = 31, dm_sw_gfx7_2d_thin_l_vp, dm_sw_gfx7_2d_thin_gl, };
From: Roman Li Roman.Li@amd.com
commit 55eea8ef98641f6e1e1c202bd3a49a57c1dd4059 upstream.
[Why] Some monitors exhibit corruption at 16bpp DSC.
[How] - Add helpers for patching edid caps. - Use it for limiting DSC target bitrate to 15bpp for known monitors
Reviewed-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Acked-by: Qingqing Zhuo qingqing.zhuo@amd.com Signed-off-by: Roman Li Roman.Li@amd.com Cc: stable@vger.kernel.org Tested-by: Daniel Wheeler Daniel.Wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 35 ++++++++++++++ 1 file changed, 35 insertions(+)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -40,6 +40,39 @@
#include "dm_helpers.h"
+struct monitor_patch_info { + unsigned int manufacturer_id; + unsigned int product_id; + void (*patch_func)(struct dc_edid_caps *edid_caps, unsigned int param); + unsigned int patch_param; +}; +static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param); + +static const struct monitor_patch_info monitor_patch_table[] = { +{0x6D1E, 0x5BBF, set_max_dsc_bpp_limit, 15}, +{0x6D1E, 0x5B9A, set_max_dsc_bpp_limit, 15}, +}; + +static void set_max_dsc_bpp_limit(struct dc_edid_caps *edid_caps, unsigned int param) +{ + if (edid_caps) + edid_caps->panel_patch.max_dsc_target_bpp_limit = param; +} + +static int amdgpu_dm_patch_edid_caps(struct dc_edid_caps *edid_caps) +{ + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(monitor_patch_table); i++) + if ((edid_caps->manufacturer_id == monitor_patch_table[i].manufacturer_id) + && (edid_caps->product_id == monitor_patch_table[i].product_id)) { + monitor_patch_table[i].patch_func(edid_caps, monitor_patch_table[i].patch_param); + ret++; + } + + return ret; +} + /* dm_helpers_parse_edid_caps * * Parse edid caps @@ -125,6 +158,8 @@ enum dc_edid_status dm_helpers_parse_edi kfree(sads); kfree(sadb);
+ amdgpu_dm_patch_edid_caps(edid_caps); + return result; }
From: Matthew Brost matthew.brost@intel.com
commit 669b949c1a44d0cb2bcd18ff6ab4fd0c21e7cf6f upstream.
A small race that could result in incorrect accounting of the number of outstanding G2H. Basically prior to this patch we did not increment the number of outstanding G2H if we encoutered a GT reset while sending a H2G. This was incorrect as the context state had already been updated to anticipate a G2H response thus the counter should be incremented.
As part of this change we remove a legacy (now unused) path that was the last caller requiring a G2H response that was not guaranteed to loop. This allows us to simplify the accounting as we don't need to handle the case where the send fails due to the channel being busy.
Also always use helper when decrementing this value.
v2 (Daniele): update GEM_BUG_ON check, pull in dead code removal from later patch, remove loop param from context_deregister.
Fixes: f4eb1f3fe946 ("drm/i915/guc: Ensure G2H response has space in buffer") Signed-off-by: Matthew Brost matthew.brost@intel.com Signed-off-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Cc: stable@vger.kernel.org Reviewed-by: John Harrison John.C.Harrison@Intel.com Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-3-matthew... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 79 ++++++++++------------ 1 file changed, 37 insertions(+), 42 deletions(-)
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -352,20 +352,29 @@ static inline void set_lrc_desc_register xa_unlock_irqrestore(&guc->context_lookup, flags); }
+static void decr_outstanding_submission_g2h(struct intel_guc *guc) +{ + if (atomic_dec_and_test(&guc->outstanding_submission_g2h)) + wake_up_all(&guc->ct.wq); +} + static int guc_submission_send_busy_loop(struct intel_guc *guc, const u32 *action, u32 len, u32 g2h_len_dw, bool loop) { - int err; - - err = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop); + /* + * We always loop when a send requires a reply (i.e. g2h_len_dw > 0), + * so we don't handle the case where we don't get a reply because we + * aborted the send due to the channel being busy. + */ + GEM_BUG_ON(g2h_len_dw && !loop);
- if (!err && g2h_len_dw) + if (g2h_len_dw) atomic_inc(&guc->outstanding_submission_g2h);
- return err; + return intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop); }
int intel_guc_wait_for_pending_msg(struct intel_guc *guc, @@ -616,7 +625,7 @@ static void scrub_guc_desc_for_outstandi init_sched_state(ce);
if (pending_enable || destroyed || deregister) { - atomic_dec(&guc->outstanding_submission_g2h); + decr_outstanding_submission_g2h(guc); if (deregister) guc_signal_context_fence(ce); if (destroyed) { @@ -635,7 +644,7 @@ static void scrub_guc_desc_for_outstandi intel_engine_signal_breadcrumbs(ce->engine); } intel_context_sched_disable_unpin(ce); - atomic_dec(&guc->outstanding_submission_g2h); + decr_outstanding_submission_g2h(guc); spin_lock_irqsave(&ce->guc_state.lock, flags); guc_blocked_fence_complete(ce); spin_unlock_irqrestore(&ce->guc_state.lock, flags); @@ -1233,8 +1242,7 @@ static int register_context(struct intel }
static int __guc_action_deregister_context(struct intel_guc *guc, - u32 guc_id, - bool loop) + u32 guc_id) { u32 action[] = { INTEL_GUC_ACTION_DEREGISTER_CONTEXT, @@ -1243,16 +1251,16 @@ static int __guc_action_deregister_conte
return guc_submission_send_busy_loop(guc, action, ARRAY_SIZE(action), G2H_LEN_DW_DEREGISTER_CONTEXT, - loop); + true); }
-static int deregister_context(struct intel_context *ce, u32 guc_id, bool loop) +static int deregister_context(struct intel_context *ce, u32 guc_id) { struct intel_guc *guc = ce_to_guc(ce);
trace_intel_context_deregister(ce);
- return __guc_action_deregister_context(guc, guc_id, loop); + return __guc_action_deregister_context(guc, guc_id); }
static intel_engine_mask_t adjust_engine_mask(u8 class, intel_engine_mask_t mask) @@ -1340,26 +1348,23 @@ static int guc_lrc_desc_pin(struct intel * registering this context. */ if (context_registered) { + bool disabled; + unsigned long flags; + trace_intel_context_steal_guc_id(ce); - if (!loop) { + GEM_BUG_ON(!loop); + + /* Seal race with Reset */ + spin_lock_irqsave(&ce->guc_state.lock, flags); + disabled = submission_disabled(guc); + if (likely(!disabled)) { set_context_wait_for_deregister_to_register(ce); intel_context_get(ce); - } else { - bool disabled; - unsigned long flags; - - /* Seal race with Reset */ - spin_lock_irqsave(&ce->guc_state.lock, flags); - disabled = submission_disabled(guc); - if (likely(!disabled)) { - set_context_wait_for_deregister_to_register(ce); - intel_context_get(ce); - } - spin_unlock_irqrestore(&ce->guc_state.lock, flags); - if (unlikely(disabled)) { - reset_lrc_desc(guc, desc_idx); - return 0; /* Will get registered later */ - } + } + spin_unlock_irqrestore(&ce->guc_state.lock, flags); + if (unlikely(disabled)) { + reset_lrc_desc(guc, desc_idx); + return 0; /* Will get registered later */ }
/* @@ -1367,13 +1372,9 @@ static int guc_lrc_desc_pin(struct intel * context whose guc_id was stolen. */ with_intel_runtime_pm(runtime_pm, wakeref) - ret = deregister_context(ce, ce->guc_id, loop); - if (unlikely(ret == -EBUSY)) { - clr_context_wait_for_deregister_to_register(ce); - intel_context_put(ce); - } else if (unlikely(ret == -ENODEV)) { + ret = deregister_context(ce, ce->guc_id); + if (unlikely(ret == -ENODEV)) ret = 0; /* Will get registered later */ - } } else { with_intel_runtime_pm(runtime_pm, wakeref) ret = register_context(ce, loop); @@ -1730,7 +1731,7 @@ static inline void guc_lrc_desc_unpin(st GEM_BUG_ON(context_enabled(ce));
clr_context_registered(ce); - deregister_context(ce, ce->guc_id, true); + deregister_context(ce, ce->guc_id); }
static void __guc_context_destroy(struct intel_context *ce) @@ -2583,12 +2584,6 @@ g2h_context_lookup(struct intel_guc *guc return ce; }
-static void decr_outstanding_submission_g2h(struct intel_guc *guc) -{ - if (atomic_dec_and_test(&guc->outstanding_submission_g2h)) - wake_up_all(&guc->ct.wq); -} - int intel_guc_deregister_done_process_msg(struct intel_guc *guc, const u32 *msg, u32 len)
From: Matthew Brost matthew.brost@intel.com
commit 9888beaaf118b6878347e1fe2b369fc66d756d18 upstream.
When unblocking a context, do not enable scheduling if the context is banned, guc_id invalid, or not registered.
v2: (Daniele) - Add helper for unblock
Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation") Signed-off-by: Matthew Brost matthew.brost@intel.com Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Cc: stable@vger.kernel.org Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-10-matthe... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -148,6 +148,7 @@ static inline void clr_context_registere #define SCHED_STATE_BLOCKED_SHIFT 4 #define SCHED_STATE_BLOCKED BIT(SCHED_STATE_BLOCKED_SHIFT) #define SCHED_STATE_BLOCKED_MASK (0xfff << SCHED_STATE_BLOCKED_SHIFT) + static inline void init_sched_state(struct intel_context *ce) { /* Only should be called from guc_lrc_desc_pin() */ @@ -1549,6 +1550,23 @@ static struct i915_sw_fence *guc_context return &ce->guc_blocked; }
+#define SCHED_STATE_MULTI_BLOCKED_MASK \ + (SCHED_STATE_BLOCKED_MASK & ~SCHED_STATE_BLOCKED) +#define SCHED_STATE_NO_UNBLOCK \ + (SCHED_STATE_MULTI_BLOCKED_MASK | \ + SCHED_STATE_PENDING_DISABLE | \ + SCHED_STATE_BANNED) + +static bool context_cant_unblock(struct intel_context *ce) +{ + lockdep_assert_held(&ce->guc_state.lock); + + return (ce->guc_state.sched_state & SCHED_STATE_NO_UNBLOCK) || + context_guc_id_invalid(ce) || + !lrc_desc_registered(ce_to_guc(ce), ce->guc_id) || + !intel_context_is_pinned(ce); +} + static void guc_context_unblock(struct intel_context *ce) { struct intel_guc *guc = ce_to_guc(ce); @@ -1563,9 +1581,7 @@ static void guc_context_unblock(struct i spin_lock_irqsave(&ce->guc_state.lock, flags);
if (unlikely(submission_disabled(guc) || - !intel_context_is_pinned(ce) || - context_pending_disable(ce) || - context_blocked(ce) > 1)) { + context_cant_unblock(ce))) { enable = false; } else { enable = true;
From: Matthew Brost matthew.brost@intel.com
commit 1ca36cff0166b0483fe3b99e711e9c800ebbfaa4 upstream.
If the context is reset as a result of the request cancellation the context reset G2H is received after schedule disable done G2H which is the wrong order. The schedule disable done G2H release the waiting request cancellation code which resubmits the context. This races with the context reset G2H which also wants to resubmit the context but in this case it really should be a NOP as request cancellation code owns the resubmit. Use some clever tricks of checking the context state to seal this race until the GuC firmware is fixed.
v2: (Checkpatch) - Fix typos v3: (Daniele) - State that is a bug in the GuC firmware
Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation") Signed-off-by: Matthew Brost matthew.brost@intel.com Cc: stable@vger.kernel.org Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-7-matthew... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 41 ++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -838,17 +838,33 @@ __unwind_incomplete_requests(struct inte static void __guc_reset_context(struct intel_context *ce, bool stalled) { struct i915_request *rq; + unsigned long flags; u32 head; + bool skip = false;
intel_context_get(ce);
/* - * GuC will implicitly mark the context as non-schedulable - * when it sends the reset notification. Make sure our state - * reflects this change. The context will be marked enabled - * on resubmission. + * GuC will implicitly mark the context as non-schedulable when it sends + * the reset notification. Make sure our state reflects this change. The + * context will be marked enabled on resubmission. + * + * XXX: If the context is reset as a result of the request cancellation + * this G2H is received after the schedule disable complete G2H which is + * wrong as this creates a race between the request cancellation code + * re-submitting the context and this G2H handler. This is a bug in the + * GuC but can be worked around in the meantime but converting this to a + * NOP if a pending enable is in flight as this indicates that a request + * cancellation has occurred. */ - clr_context_enabled(ce); + spin_lock_irqsave(&ce->guc_state.lock, flags); + if (likely(!context_pending_enable(ce))) + clr_context_enabled(ce); + else + skip = true; + spin_unlock_irqrestore(&ce->guc_state.lock, flags); + if (unlikely(skip)) + goto out_put;
rq = intel_context_find_active_request(ce); if (!rq) { @@ -867,6 +883,7 @@ static void __guc_reset_context(struct i out_replay: guc_reset_state(ce, head, stalled); __unwind_incomplete_requests(ce); +out_put: intel_context_put(ce); }
@@ -1618,6 +1635,13 @@ static void guc_context_cancel_request(s guc_reset_state(ce, intel_ring_wrap(ce->ring, rq->head), true); } + + /* + * XXX: Racey if context is reset, see comment in + * __guc_reset_context(). + */ + flush_work(&ce_to_guc(ce)->ct.requests.worker); + guc_context_unblock(ce); } } @@ -2732,7 +2756,12 @@ static void guc_handle_context_reset(str { trace_intel_context_reset(ce);
- if (likely(!intel_context_is_banned(ce))) { + /* + * XXX: Racey if request cancellation has occurred, see comment in + * __guc_reset_context(). + */ + if (likely(!intel_context_is_banned(ce) && + !context_blocked(ce))) { capture_error_state(guc, ce); guc_context_replay(ce); }
From: Matthew Brost matthew.brost@intel.com
commit 88209a8ecb8b8752322908a3c3362a001bdc3a39 upstream.
Don't drop ce->guc_active.lock when unwinding a context after reset. At one point we had to drop this because of a lock inversion but that is no longer the case. It is much safer to hold the lock so let's do that.
Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface") Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Signed-off-by: Matthew Brost matthew.brost@intel.com Cc: stable@vger.kernel.org Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-5-matthew... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -814,8 +814,6 @@ __unwind_incomplete_requests(struct inte continue;
list_del_init(&rq->sched.link); - spin_unlock(&ce->guc_active.lock); - __i915_request_unsubmit(rq);
/* Push the request back into the queue for later resubmission. */ @@ -828,8 +826,6 @@ __unwind_incomplete_requests(struct inte
list_add_tail(&rq->sched.link, pl); set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); - - spin_lock(&ce->guc_active.lock); } spin_unlock(&ce->guc_active.lock); spin_unlock_irqrestore(&sched_engine->lock, flags);
From: Matthew Brost matthew.brost@intel.com
commit c39f51cc980dd918c5b3da61d54c4725785e766e upstream.
When unwinding requests on a reset context, if other requests in the context are in the priority list the requests could be resubmitted out of seqno order. Traverse the list of active requests in reverse and append to the head of the priority list to fix this.
Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface") Signed-off-by: Matthew Brost matthew.brost@intel.com Reviewed-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Cc: stable@vger.kernel.org Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-4-matthew... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -807,9 +807,9 @@ __unwind_incomplete_requests(struct inte
spin_lock_irqsave(&sched_engine->lock, flags); spin_lock(&ce->guc_active.lock); - list_for_each_entry_safe(rq, rn, - &ce->guc_active.requests, - sched.link) { + list_for_each_entry_safe_reverse(rq, rn, + &ce->guc_active.requests, + sched.link) { if (i915_request_completed(rq)) continue;
@@ -824,7 +824,7 @@ __unwind_incomplete_requests(struct inte } GEM_BUG_ON(i915_sched_engine_is_empty(sched_engine));
- list_add_tail(&rq->sched.link, pl); + list_add(&rq->sched.link, pl); set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags); } spin_unlock(&ce->guc_active.lock);
From: Johan Hovold johan@kernel.org
commit 5591c8f79db1729d9c5ac7f5b4d3a5c26e262d93 upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: 5320918b9a87 ("drm/udl: initial UDL driver (v4)") Cc: stable@vger.kernel.org # 3.4 Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20211025115353.5089-1-johan@ke... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/udl/udl_connector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -30,7 +30,7 @@ static int udl_get_edid_block(void *data int bval = (i + block * EDID_LENGTH) << 8; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x02, (0x80 | (0x02 << 5)), bval, - 0xA1, read_buff, 2, HZ); + 0xA1, read_buff, 2, 1000); if (ret < 1) { DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); kfree(read_buff);
From: Anand K Mistry amistry@google.com
commit 8244a3bc27b3efd057da154b8d7e414670d5044f upstream.
drm_gem_ttm_mmap() drops a reference to the gem object on success. If the gem object's refcount == 1 on entry to drm_gem_prime_mmap(), that drop will free the gem object, and the subsequent drm_gem_object_get() will be a UAF. Fix by grabbing a reference before calling the mmap helper.
This issue was forseen when the reference dropping was adding in commit 9786b65bc61ac ("drm/ttm: fix mmap refcounting"): "For that to work properly the drm_gem_object_get() call in drm_gem_ttm_mmap() must be moved so it happens before calling obj->funcs->mmap(), otherwise the gem refcount would go down to zero."
Signed-off-by: Anand K Mistry amistry@google.com Fixes: 9786b65bc61a ("drm/ttm: fix mmap refcounting") Cc: Gerd Hoffmann kraxel@redhat.com Cc: Daniel Vetter daniel.vetter@ffwll.ch 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 Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v5.5+ Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Link: https://patchwork.freedesktop.org/patch/msgid/20210930085932.1.I8043d61cc238... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/drm_prime.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_ob if (obj->funcs && obj->funcs->mmap) { vma->vm_ops = obj->funcs->vm_ops;
+ drm_gem_object_get(obj); ret = obj->funcs->mmap(obj, vma); - if (ret) + if (ret) { + drm_gem_object_put(obj); return ret; + } vma->vm_private_data = obj; - drm_gem_object_get(obj); return 0; }
From: Jeremy Cline jcline@redhat.com
commit abae9164a421bc4a41a3769f01ebcd1f9d955e0e upstream.
Rather than protecting the nouveau_drm clients list with the lock within the "client" nouveau_cli, add a dedicated lock to serialize access to the list. This is both clearer and necessary to avoid lockdep being upset with us when we need to iterate through all the clients in the list and potentially lock their mutex, which is the same class as the lock protecting the entire list.
Cc: stable@vger.kernel.org # 5.4+ Signed-off-by: Jeremy Cline jcline@redhat.com Reviewed-by: Lyude Paul lyude@redhat.com Reviewed-by: Ben Skeggs bskeggs@redhat.com Tested-by: Karol Herbst kherbst@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20201125202648.5220-3-jcline@r... Link: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests/14 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nouveau_drm.c | 10 ++++++---- drivers/gpu/drm/nouveau/nouveau_drv.h | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -562,6 +562,7 @@ nouveau_drm_device_init(struct drm_devic nvkm_dbgopt(nouveau_debug, "DRM");
INIT_LIST_HEAD(&drm->clients); + mutex_init(&drm->clients_lock); spin_lock_init(&drm->tile.lock);
/* workaround an odd issue on nvc1 by disabling the device's @@ -659,6 +660,7 @@ nouveau_drm_device_fini(struct drm_devic nouveau_cli_fini(&drm->client); nouveau_cli_fini(&drm->master); nvif_parent_dtor(&drm->parent); + mutex_destroy(&drm->clients_lock); kfree(drm); }
@@ -1090,9 +1092,9 @@ nouveau_drm_open(struct drm_device *dev,
fpriv->driver_priv = cli;
- mutex_lock(&drm->client.mutex); + mutex_lock(&drm->clients_lock); list_add(&cli->head, &drm->clients); - mutex_unlock(&drm->client.mutex); + mutex_unlock(&drm->clients_lock);
done: if (ret && cli) { @@ -1118,9 +1120,9 @@ nouveau_drm_postclose(struct drm_device nouveau_abi16_fini(cli->abi16); mutex_unlock(&cli->mutex);
- mutex_lock(&drm->client.mutex); + mutex_lock(&drm->clients_lock); list_del(&cli->head); - mutex_unlock(&drm->client.mutex); + mutex_unlock(&drm->clients_lock);
nouveau_cli_fini(cli); kfree(cli); --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -139,6 +139,11 @@ struct nouveau_drm {
struct list_head clients;
+ /** + * @clients_lock: Protects access to the @clients list of &struct nouveau_cli. + */ + struct mutex clients_lock; + u8 old_pm_cap;
struct {
From: Jeremy Cline jcline@redhat.com
commit aff2299e0d81b26304ccc6a1ec0170e437f38efc upstream.
Nouveau does not currently support hot-unplugging, but it still makes sense to switch from drm_dev_unregister() to drm_dev_unplug(). drm_dev_unplug() calls drm_dev_unregister() after marking the device as unplugged, but only after any device critical sections are finished.
Since nouveau isn't using drm_dev_enter() and drm_dev_exit(), there are no critical sections so this is nearly functionally equivalent. However, the DRM layer does check to see if the device is unplugged, and if it is returns appropriate error codes.
In the future nouveau can add critical sections in order to truly support hot-unplugging.
Cc: stable@vger.kernel.org # 5.4+ Signed-off-by: Jeremy Cline jcline@redhat.com Reviewed-by: Lyude Paul lyude@redhat.com Reviewed-by: Ben Skeggs bskeggs@redhat.com Tested-by: Karol Herbst kherbst@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20201125202648.5220-2-jcline@r... Link: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests/14 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -798,7 +798,7 @@ nouveau_drm_device_remove(struct drm_dev struct nvkm_client *client; struct nvkm_device *device;
- drm_dev_unregister(dev); + drm_dev_unplug(dev);
client = nvxx_client(&drm->client.base); device = nvkm_device_find(client->device);
From: Jeremy Cline jcline@redhat.com
commit f55aaf63bde0d0336c3823bb3713bd4a464abbcf upstream.
The postclose handler can run after the device has been removed (or the driver has been unbound) since userspace clients are free to hold the file open as long as they want. Because the device removal callback frees the entire nouveau_drm structure, any reference to it in the postclose handler will result in a use-after-free.
To reproduce this, one must simply open the device file, unbind the driver (or physically remove the device), and then close the device file. This was found and can be reproduced easily with the IGT core_hotunplug tests.
To avoid this, all clients are cleaned up in the device finalization rather than deferring it to the postclose handler, and the postclose handler is protected by a critical section which ensures the drm_dev_unplug() and the postclose handler won't race.
This is not an ideal fix, since as I understand the proposed plan for the kernel<->userspace interface for hotplug support, destroying the client before the file is closed will cause problems. However, I believe to properly fix this issue, the lifetime of the nouveau_drm structure needs to be extended to match the drm_device, and this proved to be a rather invasive change. Thus, I've broken this out so the fix can be easily backported.
This fixes with the two previous commits CVE-2020-27820 (Karol).
Cc: stable@vger.kernel.org # 5.4+ Signed-off-by: Jeremy Cline jcline@redhat.com Reviewed-by: Lyude Paul lyude@redhat.com Reviewed-by: Ben Skeggs bskeggs@redhat.com Tested-by: Karol Herbst kherbst@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20201125202648.5220-4-jcline@r... Link: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests/14 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nouveau_drm.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -633,6 +633,7 @@ fail_alloc: static void nouveau_drm_device_fini(struct drm_device *dev) { + struct nouveau_cli *cli, *temp_cli; struct nouveau_drm *drm = nouveau_drm(dev);
if (nouveau_pmops_runtime()) { @@ -657,6 +658,24 @@ nouveau_drm_device_fini(struct drm_devic nouveau_ttm_fini(drm); nouveau_vga_fini(drm);
+ /* + * There may be existing clients from as-yet unclosed files. For now, + * clean them up here rather than deferring until the file is closed, + * but this likely not correct if we want to support hot-unplugging + * properly. + */ + mutex_lock(&drm->clients_lock); + list_for_each_entry_safe(cli, temp_cli, &drm->clients, head) { + list_del(&cli->head); + mutex_lock(&cli->mutex); + if (cli->abi16) + nouveau_abi16_fini(cli->abi16); + mutex_unlock(&cli->mutex); + nouveau_cli_fini(cli); + kfree(cli); + } + mutex_unlock(&drm->clients_lock); + nouveau_cli_fini(&drm->client); nouveau_cli_fini(&drm->master); nvif_parent_dtor(&drm->parent); @@ -1112,6 +1131,16 @@ nouveau_drm_postclose(struct drm_device { struct nouveau_cli *cli = nouveau_cli(fpriv); struct nouveau_drm *drm = nouveau_drm(dev); + int dev_index; + + /* + * The device is gone, and as it currently stands all clients are + * cleaned up in the removal codepath. In the future this may change + * so that we can support hot-unplugging, but for now we immediately + * return to avoid a double-free situation. + */ + if (!drm_dev_enter(dev, &dev_index)) + return;
pm_runtime_get_sync(dev->dev);
@@ -1128,6 +1157,7 @@ nouveau_drm_postclose(struct drm_device kfree(cli); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); + drm_dev_exit(dev_index); }
static const struct drm_ioctl_desc
From: Imre Deak imre.deak@intel.com
commit 6c34bd4532a3f39952952ddc102737595729afc4 upstream.
Atm, there are no sink rate values set for DP (vs. eDP) sinks until the DPCD capabilities are successfully read from the sink. During this time intel_dp->num_common_rates is 0 which can lead to a
intel_dp->common_rates[-1] (*)
access, which is an undefined behaviour, in the following cases:
- In intel_dp_sync_state(), if the encoder is enabled without a sink connected to the encoder's connector (BIOS enabled a monitor, but the user unplugged the monitor until the driver loaded). - In intel_dp_sync_state() if the encoder is enabled with a sink connected, but for some reason the DPCD read has failed. - In intel_dp_compute_link_config() if modesetting a connector without a sink connected on it. - In intel_dp_compute_link_config() if modesetting a connector with a a sink connected on it, but before probing the connector first.
To avoid the (*) access in all the above cases, make sure that the sink rate table - and hence the common rate table - is always valid, by setting a default minimum sink rate when registering the connector before anything could use it.
I also considered setting all the DP link rates by default, so that modesetting with higher resolution modes also succeeds in the last two cases above. However in case a sink is not connected that would stop working after the first modeset, due to the LT fallback logic. So this would need more work, beyond the scope of this fix.
As I mentioned in the previous patch, I don't think the issue this patch fixes is user visible, however it is an undefined behaviour by definition and triggers a BUG() in CONFIG_UBSAN builds, hence CC:stable.
v2: Clear the default sink rates, before initializing these for eDP.
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4297 Suggested-by: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: stable@vger.kernel.org Signed-off-by: Imre Deak imre.deak@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Acked-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20211018143417.1452632-1-imre.... (cherry picked from commit 3f61ef9777c0ab0f03f4af0ed6fd3e5250537a8d) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_dp.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -111,6 +111,12 @@ bool intel_dp_is_edp(struct intel_dp *in static void intel_dp_unset_edid(struct intel_dp *intel_dp); static int intel_dp_dsc_compute_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
+static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp) +{ + intel_dp->sink_rates[0] = 162000; + intel_dp->num_sink_rates = 1; +} + /* update sink rates from dpcd */ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) { @@ -2462,6 +2468,9 @@ intel_edp_init_dpcd(struct intel_dp *int */ intel_psr_init_dpcd(intel_dp);
+ /* Clear the default sink rates */ + intel_dp->num_sink_rates = 0; + /* Read the eDP 1.4+ supported link rates. */ if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; @@ -5296,6 +5305,8 @@ intel_dp_init_connector(struct intel_dig return false;
intel_dp_set_source_rates(intel_dp); + intel_dp_set_default_sink_rates(intel_dp); + intel_dp_set_common_rates(intel_dp);
intel_dp->reset_link_params = true; intel_dp->pps.pps_pipe = INVALID_PIPE;
From: Imre Deak imre.deak@intel.com
commit cc99bc62ff6902688ee7bd3a7b25eefc620fbb6a upstream.
Atm until the DPCD for a connector is read the max link rate and lane count params are invalid. If the connector is modeset, in intel_dp_compute_config(), intel_dp_common_len_rate_limit(max_link_rate) will return 0, leading to a intel_dp->common_rates[-1] access.
Fix the above by making sure the max link params are always valid.
The above access leads to an undefined behaviour by definition, though not causing a user visible problem to my best knowledge, see the previous patch why. Nevertheless it is an undefined behaviour and it triggers a BUG() in CONFIG_UBSAN builds, hence CC:stable.
Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: stable@vger.kernel.org Signed-off-by: Imre Deak imre.deak@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Acked-by: Jani Nikula jani.nikula@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20211018094154.1407705-4-imre.... (cherry picked from commit 9ad87de4735620ffc555592e8c5f580478fa3ed0) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_dp.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1773,6 +1773,12 @@ void intel_dp_set_link_params(struct int intel_dp->lane_count = lane_count; }
+static void intel_dp_reset_max_link_params(struct intel_dp *intel_dp) +{ + intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); + intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); +} + /* Enable backlight PWM and backlight PP control. */ void intel_edp_backlight_on(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) @@ -1932,8 +1938,7 @@ void intel_dp_sync_state(struct intel_en if (intel_dp->dpcd[DP_DPCD_REV] == 0) intel_dp_get_dpcd(intel_dp);
- intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); - intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); + intel_dp_reset_max_link_params(intel_dp); }
bool intel_dp_initial_fastset_check(struct intel_encoder *encoder, @@ -2506,6 +2511,7 @@ intel_edp_init_dpcd(struct intel_dp *int intel_dp_set_sink_rates(intel_dp);
intel_dp_set_common_rates(intel_dp); + intel_dp_reset_max_link_params(intel_dp);
/* Read the eDP DSC DPCD registers */ if (DISPLAY_VER(dev_priv) >= 10) @@ -4249,12 +4255,7 @@ intel_dp_detect(struct drm_connector *co * supports link training fallback params. */ if (intel_dp->reset_link_params || intel_dp->is_mst) { - /* Initial max link lane count */ - intel_dp->max_link_lane_count = intel_dp_max_common_lane_count(intel_dp); - - /* Initial max link rate */ - intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp); - + intel_dp_reset_max_link_params(intel_dp); intel_dp->reset_link_params = false; }
@@ -5307,6 +5308,7 @@ intel_dp_init_connector(struct intel_dig intel_dp_set_source_rates(intel_dp); intel_dp_set_default_sink_rates(intel_dp); intel_dp_set_common_rates(intel_dp); + intel_dp_reset_max_link_params(intel_dp);
intel_dp->reset_link_params = true; intel_dp->pps.pps_pipe = INVALID_PIPE;
From: Ville Syrjälä ville.syrjala@linux.intel.com
commit 1977e8eb40ed53f0cac7db1a78295726f4ac0b24 upstream.
Looks like we never updated intel_bios_is_port_dp_dual_mode() when the VBT port mapping became erratic on modern platforms. This is causing us to look up the wrong child device and thus throwing the heuristic off (ie. we might end looking at a child device for a genuine DP++ port when we were supposed to look at one for a native HDMI port).
Fix it up by not using the outdated port_mapping[] in intel_bios_is_port_dp_dual_mode() and rely on intel_bios_encoder_data_lookup() instead.
Cc: stable@vger.kernel.org Tested-by: Randy Dunlap rdunlap@infradead.org Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4138 Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20211025142147.23897-1-ville.s... Reviewed-by: Jani Nikula jani.nikula@intel.com (cherry picked from commit 32c2bc89c7420fad2959ee23ef5b6be8b05d2bde) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_bios.c | 85 ++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 22 deletions(-)
--- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -1692,6 +1692,39 @@ static u8 map_ddc_pin(struct drm_i915_pr return 0; }
+static u8 dvo_port_type(u8 dvo_port) +{ + switch (dvo_port) { + case DVO_PORT_HDMIA: + case DVO_PORT_HDMIB: + case DVO_PORT_HDMIC: + case DVO_PORT_HDMID: + case DVO_PORT_HDMIE: + case DVO_PORT_HDMIF: + case DVO_PORT_HDMIG: + case DVO_PORT_HDMIH: + case DVO_PORT_HDMII: + return DVO_PORT_HDMIA; + case DVO_PORT_DPA: + case DVO_PORT_DPB: + case DVO_PORT_DPC: + case DVO_PORT_DPD: + case DVO_PORT_DPE: + case DVO_PORT_DPF: + case DVO_PORT_DPG: + case DVO_PORT_DPH: + case DVO_PORT_DPI: + return DVO_PORT_DPA; + case DVO_PORT_MIPIA: + case DVO_PORT_MIPIB: + case DVO_PORT_MIPIC: + case DVO_PORT_MIPID: + return DVO_PORT_MIPIA; + default: + return dvo_port; + } +} + static enum port __dvo_port_to_port(int n_ports, int n_dvo, const int port_mapping[][3], u8 dvo_port) { @@ -2622,35 +2655,17 @@ bool intel_bios_is_port_edp(struct drm_i return false; }
-static bool child_dev_is_dp_dual_mode(const struct child_device_config *child, - enum port port) +static bool child_dev_is_dp_dual_mode(const struct child_device_config *child) { - static const struct { - u16 dp, hdmi; - } port_mapping[] = { - /* - * Buggy VBTs may declare DP ports as having - * HDMI type dvo_port :( So let's check both. - */ - [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, - [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, - [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, - [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, - [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, - }; - - if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) - return false; - if ((child->device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) != (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS)) return false;
- if (child->dvo_port == port_mapping[port].dp) + if (dvo_port_type(child->dvo_port) == DVO_PORT_DPA) return true;
/* Only accept a HDMI dvo_port as DP++ if it has an AUX channel */ - if (child->dvo_port == port_mapping[port].hdmi && + if (dvo_port_type(child->dvo_port) == DVO_PORT_HDMIA && child->aux_channel != 0) return true;
@@ -2660,10 +2675,36 @@ static bool child_dev_is_dp_dual_mode(co bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *i915, enum port port) { + static const struct { + u16 dp, hdmi; + } port_mapping[] = { + /* + * Buggy VBTs may declare DP ports as having + * HDMI type dvo_port :( So let's check both. + */ + [PORT_B] = { DVO_PORT_DPB, DVO_PORT_HDMIB, }, + [PORT_C] = { DVO_PORT_DPC, DVO_PORT_HDMIC, }, + [PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, }, + [PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, }, + [PORT_F] = { DVO_PORT_DPF, DVO_PORT_HDMIF, }, + }; const struct intel_bios_encoder_data *devdata;
+ if (HAS_DDI(i915)) { + const struct intel_bios_encoder_data *devdata; + + devdata = intel_bios_encoder_data_lookup(i915, port); + + return devdata && child_dev_is_dp_dual_mode(&devdata->child); + } + + if (port == PORT_A || port >= ARRAY_SIZE(port_mapping)) + return false; + list_for_each_entry(devdata, &i915->vbt.display_devices, node) { - if (child_dev_is_dp_dual_mode(&devdata->child, port)) + if ((devdata->child.dvo_port == port_mapping[port].dp || + devdata->child.dvo_port == port_mapping[port].hdmi) && + child_dev_is_dp_dual_mode(&devdata->child)) return true; }
From: hongao hongao@uniontech.com
commit bf552083916a7f8800477b5986940d1c9a31b953 upstream.
amdgpu_connector_vga_get_modes missed function amdgpu_get_native_mode which assign amdgpu_encoder->native_mode with *preferred_mode result in amdgpu_encoder->native_mode.clock always be 0. That will cause amdgpu_connector_set_property returned early on: if ((rmx_type != DRM_MODE_SCALE_NONE) && (amdgpu_encoder->native_mode.clock == 0)) when we try to set scaling mode Full/Full aspect/Center. Add the missing function to amdgpu_connector_vga_get_mode can fix this. It also works on dvi connectors because amdgpu_connector_dvi_helper_funcs.get_mode use the same method.
Signed-off-by: hongao hongao@uniontech.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_connectors.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -827,6 +827,7 @@ static int amdgpu_connector_vga_get_mode
amdgpu_connector_get_edid(connector); ret = amdgpu_connector_ddc_get_modes(connector); + amdgpu_get_native_mode(connector);
return ret; }
From: Evan Quan evan.quan@amd.com
commit 6ee27ee27ba8b2e725886951ba2d2d87f113bece upstream.
Just bail out if the target IP block is already in the desired powergate/ungate state. This can avoid some duplicate settings which sometimes may cause unexpected issues.
Link: https://lore.kernel.org/all/YV81vidWQLWvATMM@zn.tnic/ Bug: https://bugzilla.kernel.org/show_bug.cgi?id=214921 Bug: https://bugzilla.kernel.org/show_bug.cgi?id=215025 Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1789 Fixes: bf756fb833cb ("drm/amdgpu: add missing cleanups for Polaris12 UVD/VCE on suspend") Signed-off-by: Evan Quan evan.quan@amd.com Tested-by: Borislav Petkov bp@suse.de Reviewed-by: Lijo Lazar lijo.lazar@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_device.c | 3 +++ drivers/gpu/drm/amd/include/amd_shared.h | 3 ++- drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 10 ++++++++++ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 8 ++++++++ 4 files changed, 23 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3532,6 +3532,9 @@ int amdgpu_device_init(struct amdgpu_dev adev->rmmio_size = pci_resource_len(adev->pdev, 2); }
+ for (i = 0; i < AMD_IP_BLOCK_TYPE_NUM; i++) + atomic_set(&adev->pm.pwr_state[i], POWER_STATE_UNKNOWN); + adev->rmmio = ioremap(adev->rmmio_base, adev->rmmio_size); if (adev->rmmio == NULL) { return -ENOMEM; --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -98,7 +98,8 @@ enum amd_ip_block_type { AMD_IP_BLOCK_TYPE_ACP, AMD_IP_BLOCK_TYPE_VCN, AMD_IP_BLOCK_TYPE_MES, - AMD_IP_BLOCK_TYPE_JPEG + AMD_IP_BLOCK_TYPE_JPEG, + AMD_IP_BLOCK_TYPE_NUM, };
enum amd_clockgating_state { --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -927,6 +927,13 @@ int amdgpu_dpm_set_powergating_by_smu(st { int ret = 0; const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; + enum ip_power_state pwr_state = gate ? POWER_STATE_OFF : POWER_STATE_ON; + + if (atomic_read(&adev->pm.pwr_state[block_type]) == pwr_state) { + dev_dbg(adev->dev, "IP block%d already in the target %s state!", + block_type, gate ? "gate" : "ungate"); + return 0; + }
switch (block_type) { case AMD_IP_BLOCK_TYPE_UVD: @@ -979,6 +986,9 @@ int amdgpu_dpm_set_powergating_by_smu(st break; }
+ if (!ret) + atomic_set(&adev->pm.pwr_state[block_type], pwr_state); + return ret; }
--- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -417,6 +417,12 @@ struct amdgpu_dpm { enum amd_dpm_forced_level forced_level; };
+enum ip_power_state { + POWER_STATE_UNKNOWN, + POWER_STATE_ON, + POWER_STATE_OFF, +}; + struct amdgpu_pm { struct mutex mutex; u32 current_sclk; @@ -452,6 +458,8 @@ struct amdgpu_pm { struct i2c_adapter smu_i2c; struct mutex smu_i2c_mutex; struct list_head pm_attr_list; + + atomic_t pwr_state[AMD_IP_BLOCK_TYPE_NUM]; };
#define R600_SSTU_DFLT 0
From: Eric W. Biederman ebiederm@xmission.com
commit 26d5badbccddcc063dc5174a2baffd13a23322aa upstream.
Add a simple helper force_fatal_sig that causes a signal to be delivered to a process as if the signal handler was set to SIG_DFL.
Reimplement force_sigsegv based upon this new helper. This fixes force_sigsegv so that when it forces the default signal handler to be used the code now forces the signal to be unblocked as well.
Reusing the tested logic in force_sig_info_to_task that was built for force_sig_seccomp this makes the implementation trivial.
This is interesting both because it makes force_sigsegv simpler and because there are a couple of buggy places in the kernel that call do_exit(SIGILL) or do_exit(SIGSYS) because there is no straight forward way today for those places to simply force the exit of a process with the chosen signal. Creating force_fatal_sig allows those places to be implemented with normal signal exits.
Link: https://lkml.kernel.org/r/20211020174406.17889-13-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/sched/signal.h | 1 + kernel/signal.c | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-)
--- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -338,6 +338,7 @@ extern int kill_pid(struct pid *pid, int extern __must_check bool do_notify_parent(struct task_struct *, int); extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent); extern void force_sig(int); +extern void force_fatal_sig(int); extern int send_sig(int, struct task_struct *, int); extern int zap_other_threads(struct task_struct *p); extern struct sigqueue *sigqueue_alloc(void); --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1650,6 +1650,19 @@ void force_sig(int sig) } EXPORT_SYMBOL(force_sig);
+void force_fatal_sig(int sig) +{ + struct kernel_siginfo info; + + clear_siginfo(&info); + info.si_signo = sig; + info.si_errno = 0; + info.si_code = SI_KERNEL; + info.si_pid = 0; + info.si_uid = 0; + force_sig_info_to_task(&info, current, true); +} + /* * When things go south during signal handling, we * will force a SIGSEGV. And if the signal that caused @@ -1658,15 +1671,10 @@ EXPORT_SYMBOL(force_sig); */ void force_sigsegv(int sig) { - struct task_struct *p = current; - - if (sig == SIGSEGV) { - unsigned long flags; - spin_lock_irqsave(&p->sighand->siglock, flags); - p->sighand->action[sig - 1].sa.sa_handler = SIG_DFL; - spin_unlock_irqrestore(&p->sighand->siglock, flags); - } - force_sig(SIGSEGV); + if (sig == SIGSEGV) + force_fatal_sig(SIGSEGV); + else + force_sig(SIGSEGV); }
int force_sig_fault_to_task(int sig, int code, void __user *addr
From: Eric W. Biederman ebiederm@xmission.com
commit 941edc5bf174b67f94db19817cbeab0a93e0c32a upstream.
Use force_fatal_sig instead of calling do_exit directly. This ensures the ordinary signal handling path gets invoked, core dumps as appropriate get created, and for multi-threaded processes all of the threads are terminated not just a single thread.
When asked Gabriel Krisman Bertazi krisman@collabora.com said [1]:
ebiederm@xmission.com (Eric W. Biederman) asked:
Why does do_syscal_user_dispatch call do_exit(SIGSEGV) and do_exit(SIGSYS) instead of force_sig(SIGSEGV) and force_sig(SIGSYS)?
Looking at the code these cases are not expected to happen, so I would be surprised if userspace depends on any particular behaviour on the failure path so I think we can change this.
Hi Eric,
There is not really a good reason, and the use case that originated the feature doesn't rely on it.
Unless I'm missing yet another problem and others correct me, I think it makes sense to change it as you described.
Is using do_exit in this way something you copied from seccomp?
I'm not sure, its been a while, but I think it might be just that. The first prototype of SUD was implemented as a seccomp mode.
If at some point it becomes interesting we could relax "force_fatal_sig(SIGSEGV)" to instead say "force_sig_fault(SIGSEGV, SEGV_MAPERR, sd->selector)".
I avoid doing that in this patch to avoid making it possible to catch currently uncatchable signals.
Cc: Gabriel Krisman Bertazi krisman@collabora.com Cc: Thomas Gleixner tglx@linutronix.de Cc: Peter Zijlstra peterz@infradead.org Cc: Andy Lutomirski luto@kernel.org [1] https://lkml.kernel.org/r/87mtr6gdvi.fsf@collabora.com Link: https://lkml.kernel.org/r/20211020174406.17889-14-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/entry/syscall_user_dispatch.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
--- a/kernel/entry/syscall_user_dispatch.c +++ b/kernel/entry/syscall_user_dispatch.c @@ -47,14 +47,18 @@ bool syscall_user_dispatch(struct pt_reg * access_ok() is performed once, at prctl time, when * the selector is loaded by userspace. */ - if (unlikely(__get_user(state, sd->selector))) - do_exit(SIGSEGV); + if (unlikely(__get_user(state, sd->selector))) { + force_fatal_sig(SIGSEGV); + return true; + }
if (likely(state == SYSCALL_DISPATCH_FILTER_ALLOW)) return false;
- if (state != SYSCALL_DISPATCH_FILTER_BLOCK) - do_exit(SIGSYS); + if (state != SYSCALL_DISPATCH_FILTER_BLOCK) { + force_fatal_sig(SIGSYS); + return true; + } }
sd->on_dispatch = true;
From: Eric W. Biederman ebiederm@xmission.com
commit 83a1f27ad773b1d8f0460d3a676114c7651918cc upstream.
If the register state may be partial and corrupted instead of calling do_exit, call force_sigsegv(SIGSEGV). Which properly kills the process with SIGSEGV and does not let any more userspace code execute, instead of just killing one thread of the process and potentially confusing everything.
Cc: Michael Ellerman mpe@ellerman.id.au Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: Paul Mackerras paulus@samba.org Cc: linuxppc-dev@lists.ozlabs.org History-tree: git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git Fixes: 756f1ae8a44e ("PPC32: Rework signal code and add a swapcontext system call.") Fixes: 04879b04bf50 ("[PATCH] ppc64: VMX (Altivec) support & signal32 rework, from Ben Herrenschmidt") Link: https://lkml.kernel.org/r/20211020174406.17889-7-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/signal_32.c | 6 ++++-- arch/powerpc/kernel/signal_64.c | 9 ++++++--- 2 files changed, 10 insertions(+), 5 deletions(-)
--- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1062,8 +1062,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucon * or if another thread unmaps the region containing the context. * We kill the task with a SIGSEGV in this situation. */ - if (do_setcontext(new_ctx, regs, 0)) - do_exit(SIGSEGV); + if (do_setcontext(new_ctx, regs, 0)) { + force_sigsegv(SIGSEGV); + return -EFAULT; + }
set_thread_flag(TIF_RESTOREALL); return 0; --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -703,15 +703,18 @@ SYSCALL_DEFINE3(swapcontext, struct ucon * We kill the task with a SIGSEGV in this situation. */
- if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) - do_exit(SIGSEGV); + if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) { + force_sigsegv(SIGSEGV); + return -EFAULT; + } set_current_blocked(&set);
if (!user_read_access_begin(new_ctx, ctx_size)) return -EFAULT; if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) { user_read_access_end(); - do_exit(SIGSEGV); + force_sigsegv(SIGSEGV); + return -EFAULT; } user_read_access_end();
From: Eric W. Biederman ebiederm@xmission.com
commit 9bc508cf0791c8e5a37696de1a046d746fcbd9d8 upstream.
Reading the history it is unclear why default_trap_handler calls do_exit. It is not even menthioned in the commit where the change happened. My best guess is that because it is unknown why the exception happened it was desired to guarantee the process never returned to userspace.
Using do_exit(SIGSEGV) has the problem that it will only terminate one thread of a process, leaving the process in an undefined state.
Use force_sigsegv(SIGSEGV) instead which effectively has the same behavior except that is uses the ordinary signal mechanism and terminates all threads of a process and is generally well defined.
Cc: Heiko Carstens hca@linux.ibm.com Cc: Vasily Gorbik gor@linux.ibm.com Cc: Christian Borntraeger borntraeger@de.ibm.com Cc: linux-s390@vger.kernel.org Fixes: ca2ab03237ec ("[PATCH] s390: core changes") History Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Link: https://lkml.kernel.org/r/20211020174406.17889-11-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -84,7 +84,7 @@ static void default_trap_handler(struct { if (user_mode(regs)) { report_user_fault(regs, SIGSEGV, 0); - do_exit(SIGSEGV); + force_sigsegv(SIGSEGV); } else die(regs, "Unknown program exception"); }
From: Eric W. Biederman ebiederm@xmission.com
commit c317d306d55079525c9610267fdaf3a8a6d2f08b upstream.
The function try_to_clear_window_buffer is only called from rtrap_32.c. After it is called the signal pending state is retested, and signals are handled if TIF_SIGPENDING is set. This allows try_to_clear_window_buffer to call force_fatal_signal and then rely on the signal being delivered to kill the process, without any danger of returning to userspace, or otherwise using possible corrupt state on failure.
The functional difference between force_fatal_sig and do_exit is that do_exit will only terminate a single thread, and will never trigger a core-dump. A multi-threaded program for which a single thread terminates unexpectedly is hard to reason about. Calling force_fatal_sig does not give userspace a chance to catch the signal, but otherwise is an ordinary fatal signal exit, and it will trigger a coredump of the offending process if core dumps are enabled.
Cc: David Miller davem@davemloft.net Cc: sparclinux@vger.kernel.org Link: https://lkml.kernel.org/r/20211020174406.17889-15-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/sparc/kernel/windows.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/arch/sparc/kernel/windows.c +++ b/arch/sparc/kernel/windows.c @@ -121,8 +121,10 @@ void try_to_clear_window_buffer(struct p
if ((sp & 7) || copy_to_user((char __user *) sp, &tp->reg_window[window], - sizeof(struct reg_window32))) - do_exit(SIGILL); + sizeof(struct reg_window32))) { + force_fatal_sig(SIGILL); + return; + } } tp->w_saved = 0; }
From: Eric W. Biederman ebiederm@xmission.com
commit 086ec444f86660e103de8945d0dcae9b67132ac9 upstream.
Modify the 32bit version of setup_rt_frame and setup_frame to act similar to the 64bit version of setup_rt_frame and fail with a signal instead of calling do_exit.
Replacing do_exit(SIGILL) with force_fatal_signal(SIGILL) ensures that the process will be terminated cleanly when the stack frame is invalid, instead of just killing off a single thread and leaving the process is a weird state.
Cc: David Miller davem@davemloft.net Cc: sparclinux@vger.kernel.org Link: https://lkml.kernel.org/r/20211020174406.17889-16-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/sparc/kernel/signal_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -244,7 +244,7 @@ static int setup_frame(struct ksignal *k get_sigframe(ksig, regs, sigframe_size);
if (invalid_frame_pointer(sf, sigframe_size)) { - do_exit(SIGILL); + force_fatal_sig(SIGILL); return -EINVAL; }
@@ -336,7 +336,7 @@ static int setup_rt_frame(struct ksignal sf = (struct rt_signal_frame __user *) get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) { - do_exit(SIGILL); + force_fatal_sig(SIGILL); return -EINVAL; }
From: Eric W. Biederman ebiederm@xmission.com
commit 1fbd60df8a852d9c55de8cd3621899cf4c72a5b7 upstream.
Update save_v86_state to always complete all of it's work except possibly some of the copies to userspace even if save_v86_state takes a fault. This ensures that the kernel is always in a sane state, even if userspace has done something silly.
When save_v86_state takes a fault update it to force userspace to take a SIGSEGV and terminate the userspace application.
As Andy pointed out in review of the first version of this change there are races between sigaction and the application terinating. Now that the code has been modified to always perform all save_v86_state's work (except possibly copying to userspace) those races do not matter from a kernel perspective.
Forcing the userspace application to terminate (by resetting it's handler to SIGDFL) is there to keep everything as close to the current behavior as possible while removing the unique (and difficult to maintain) use of do_exit.
If this new SIGSEGV happens during handle_signal the next time around the exit_to_user_mode_loop, SIGSEGV will be delivered to userspace.
All of the callers of handle_vm86_trap and handle_vm86_fault run the exit_to_user_mode_loop before they return to userspace any signal sent to the current task during their execution will be delivered to the current task before that tasks exits to usermode.
Cc: Andy Lutomirski luto@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Ingo Molnar mingo@redhat.com Cc: Borislav Petkov bp@alien8.de Cc: x86@kernel.org Cc: H Peter Anvin hpa@zytor.com v1: https://lkml.kernel.org/r/20211020174406.17889-10-ebiederm@xmission.com Link: https://lkml.kernel.org/r/877de1xcr6.fsf_-_@disp2133 Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/vm86_32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -142,6 +142,7 @@ void save_v86_state(struct kernel_vm86_r
user_access_end();
+exit_vm86: preempt_disable(); tsk->thread.sp0 = vm86->saved_sp0; tsk->thread.sysenter_cs = __KERNEL_CS; @@ -161,7 +162,8 @@ Efault_end: user_access_end(); Efault: pr_alert("could not access userspace vm86 info\n"); - do_exit(SIGSEGV); + force_sigsegv(SIGSEGV); + goto exit_vm86; }
static int do_vm86_irq_handling(int subfunction, int irqnumber);
From: Eric W. Biederman ebiederm@xmission.com
commit 695dd0d634df8903e5ead8aa08d326f63b23368a upstream.
Directly calling do_exit with a signal number has the problem that all of the side effects of the signal don't happen, such as killing all of the threads of a process instead of just the calling thread.
So replace do_exit(SIGSYS) with force_fatal_sig(SIGSYS) which causes the signal handling to take it's normal path and work as expected.
Cc: Andy Lutomirski luto@kernel.org Link: https://lkml.kernel.org/r/20211020174406.17889-17-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/entry/vsyscall/vsyscall_64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c @@ -226,7 +226,8 @@ bool emulate_vsyscall(unsigned long erro if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) { warn_bad_vsyscall(KERN_DEBUG, regs, "seccomp tried to change syscall nr or ip"); - do_exit(SIGSYS); + force_fatal_sig(SIGSYS); + return true; } regs->orig_ax = -1; if (tmp)
From: Eric W. Biederman ebiederm@xmission.com
commit e21294a7aaae32c5d7154b187113a04db5852e37 upstream.
Now that force_fatal_sig exists it is unnecessary and a bit confusing to use force_sigsegv in cases where the simpler force_fatal_sig is wanted. So change every instance we can to make the code clearer.
Acked-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Philippe Mathieu-Daudé f4bug@amsat.org Link: https://lkml.kernel.org/r/877de7jrev.fsf@disp2133 Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arc/kernel/process.c | 2 +- arch/m68k/kernel/traps.c | 2 +- arch/powerpc/kernel/signal_32.c | 2 +- arch/powerpc/kernel/signal_64.c | 4 ++-- arch/s390/kernel/traps.c | 2 +- arch/um/kernel/trap.c | 2 +- arch/x86/kernel/vm86_32.c | 2 +- fs/exec.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-)
--- a/arch/arc/kernel/process.c +++ b/arch/arc/kernel/process.c @@ -294,7 +294,7 @@ int elf_check_arch(const struct elf32_hd eflags = x->e_flags; if ((eflags & EF_ARC_OSABI_MSK) != EF_ARC_OSABI_CURRENT) { pr_err("ABI mismatch - you need newer toolchain\n"); - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); return 0; }
--- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -1145,7 +1145,7 @@ asmlinkage void set_esp0(unsigned long s */ asmlinkage void fpsp040_die(void) { - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); }
#ifdef CONFIG_M68KFPU_EMU --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1063,7 +1063,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucon * We kill the task with a SIGSEGV in this situation. */ if (do_setcontext(new_ctx, regs, 0)) { - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); return -EFAULT; }
--- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -704,7 +704,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucon */
if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) { - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); return -EFAULT; } set_current_blocked(&set); @@ -713,7 +713,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucon return -EFAULT; if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) { user_read_access_end(); - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); return -EFAULT; } user_read_access_end(); --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -84,7 +84,7 @@ static void default_trap_handler(struct { if (user_mode(regs)) { report_user_fault(regs, SIGSEGV, 0); - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); } else die(regs, "Unknown program exception"); } --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -158,7 +158,7 @@ static void bad_segv(struct faultinfo fi
void fatal_sigsegv(void) { - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); do_signal(¤t->thread.regs); /* * This is to tell gcc that we're not returning - do_signal --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -162,7 +162,7 @@ Efault_end: user_access_end(); Efault: pr_alert("could not access userspace vm86 info\n"); - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV); goto exit_vm86; }
--- a/fs/exec.c +++ b/fs/exec.c @@ -1852,7 +1852,7 @@ out: * SIGSEGV. */ if (bprm->point_of_no_return && !fatal_signal_pending(current)) - force_sigsegv(SIGSEGV); + force_fatal_sig(SIGSEGV);
out_unmark: current->fs->in_exec = 0;
From: Eric W. Biederman ebiederm@xmission.com
commit e349d945fac76bddc78ae1cb92a0145b427a87ce upstream.
Recently to prevent issues with SECCOMP_RET_KILL and similar signals being changed before they are delivered SA_IMMUTABLE was added.
Unfortunately this broke debuggers[1][2] which reasonably expect to be able to trap synchronous SIGTRAP and SIGSEGV even when the target process is not configured to handle those signals.
Update force_sig_to_task to support both the case when we can allow the debugger to intercept and possibly ignore the signal and the case when it is not safe to let userspace know about the signal until the process has exited.
Suggested-by: Linus Torvalds torvalds@linux-foundation.org Reported-by: Kyle Huey me@kylehuey.com Reported-by: kernel test robot oliver.sang@intel.com Cc: stable@vger.kernel.org [1] https://lkml.kernel.org/r/CAP045AoMY4xf8aC_4QU_-j7obuEPYgTcnQQP3Yxk=2X90jtpj... [2] https://lkml.kernel.org/r/20211117150258.GB5403@xsang-OptiPlex-9020 Fixes: 00b06da29cf9 ("signal: Add SA_IMMUTABLE to ensure forced siganls do not get changed") Link: https://lkml.kernel.org/r/877dd5qfw5.fsf_-_@email.froward.int.ebiederm.org Reviewed-by: Kees Cook keescook@chromium.org Tested-by: Kees Cook keescook@chromium.org Tested-by: Kyle Huey khuey@kylehuey.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/signal.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
--- a/kernel/signal.c +++ b/kernel/signal.c @@ -1298,6 +1298,12 @@ int do_send_sig_info(int sig, struct ker return ret; }
+enum sig_handler { + HANDLER_CURRENT, /* If reachable use the current handler */ + HANDLER_SIG_DFL, /* Always use SIG_DFL handler semantics */ + HANDLER_EXIT, /* Only visible as the process exit code */ +}; + /* * Force a signal that the process can't ignore: if necessary * we unblock the signal and change any SIG_IGN to SIG_DFL. @@ -1310,7 +1316,8 @@ int do_send_sig_info(int sig, struct ker * that is why we also clear SIGNAL_UNKILLABLE. */ static int -force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t, bool sigdfl) +force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t, + enum sig_handler handler) { unsigned long int flags; int ret, blocked, ignored; @@ -1321,9 +1328,10 @@ force_sig_info_to_task(struct kernel_sig action = &t->sighand->action[sig-1]; ignored = action->sa.sa_handler == SIG_IGN; blocked = sigismember(&t->blocked, sig); - if (blocked || ignored || sigdfl) { + if (blocked || ignored || (handler != HANDLER_CURRENT)) { action->sa.sa_handler = SIG_DFL; - action->sa.sa_flags |= SA_IMMUTABLE; + if (handler == HANDLER_EXIT) + action->sa.sa_flags |= SA_IMMUTABLE; if (blocked) { sigdelset(&t->blocked, sig); recalc_sigpending_and_wake(t); @@ -1343,7 +1351,7 @@ force_sig_info_to_task(struct kernel_sig
int force_sig_info(struct kernel_siginfo *info) { - return force_sig_info_to_task(info, current, false); + return force_sig_info_to_task(info, current, HANDLER_CURRENT); }
/* @@ -1660,7 +1668,7 @@ void force_fatal_sig(int sig) info.si_code = SI_KERNEL; info.si_pid = 0; info.si_uid = 0; - force_sig_info_to_task(&info, current, true); + force_sig_info_to_task(&info, current, HANDLER_SIG_DFL); }
/* @@ -1693,7 +1701,7 @@ int force_sig_fault_to_task(int sig, int info.si_flags = flags; info.si_isr = isr; #endif - return force_sig_info_to_task(&info, t, false); + return force_sig_info_to_task(&info, t, HANDLER_CURRENT); }
int force_sig_fault(int sig, int code, void __user *addr @@ -1813,7 +1821,8 @@ int force_sig_seccomp(int syscall, int r info.si_errno = reason; info.si_arch = syscall_get_arch(current); info.si_syscall = syscall; - return force_sig_info_to_task(&info, current, force_coredump); + return force_sig_info_to_task(&info, current, + force_coredump ? HANDLER_EXIT : HANDLER_CURRENT); }
/* For the crazy architectures that include trap information in
From: Eric W. Biederman ebiederm@xmission.com
commit fcb116bc43c8c37c052530ead79872f8b2615711 upstream.
Recently to prevent issues with SECCOMP_RET_KILL and similar signals being changed before they are delivered SA_IMMUTABLE was added.
Unfortunately this broke debuggers[1][2] which reasonably expect to be able to trap synchronous SIGTRAP and SIGSEGV even when the target process is not configured to handle those signals.
Add force_exit_sig and use it instead of force_fatal_sig where historically the code has directly called do_exit. This has the implementation benefits of going through the signal exit path (including generating core dumps) without the danger of allowing userspace to ignore or change these signals.
This avoids userspace regressions as older kernels exited with do_exit which debuggers also can not intercept.
In the future is should be possible to improve the quality of implementation of the kernel by changing some of these force_exit_sig calls to force_fatal_sig. That can be done where it matters on a case-by-case basis with careful analysis.
Reported-by: Kyle Huey me@kylehuey.com Reported-by: kernel test robot oliver.sang@intel.com [1] https://lkml.kernel.org/r/CAP045AoMY4xf8aC_4QU_-j7obuEPYgTcnQQP3Yxk=2X90jtpj... [2] https://lkml.kernel.org/r/20211117150258.GB5403@xsang-OptiPlex-9020 Fixes: 00b06da29cf9 ("signal: Add SA_IMMUTABLE to ensure forced siganls do not get changed") Fixes: a3616a3c0272 ("signal/m68k: Use force_sigsegv(SIGSEGV) in fpsp040_die") Fixes: 83a1f27ad773 ("signal/powerpc: On swapcontext failure force SIGSEGV") Fixes: 9bc508cf0791 ("signal/s390: Use force_sigsegv in default_trap_handler") Fixes: 086ec444f866 ("signal/sparc32: In setup_rt_frame and setup_fram use force_fatal_sig") Fixes: c317d306d550 ("signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer fails") Fixes: 695dd0d634df ("signal/x86: In emulate_vsyscall force a signal instead of calling do_exit") Fixes: 1fbd60df8a85 ("signal/vm86_32: Properly send SIGSEGV when the vm86 state cannot be saved.") Fixes: 941edc5bf174 ("exit/syscall_user_dispatch: Send ordinary signals on failure") Link: https://lkml.kernel.org/r/871r3dqfv8.fsf_-_@email.froward.int.ebiederm.org Reviewed-by: Kees Cook keescook@chromium.org Tested-by: Kees Cook keescook@chromium.org Tested-by: Kyle Huey khuey@kylehuey.com Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Cc: Thomas Backlund tmb@iki.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/m68k/kernel/traps.c | 2 +- arch/powerpc/kernel/signal_32.c | 2 +- arch/powerpc/kernel/signal_64.c | 4 ++-- arch/s390/kernel/traps.c | 2 +- arch/sparc/kernel/signal_32.c | 4 ++-- arch/sparc/kernel/windows.c | 2 +- arch/x86/entry/vsyscall/vsyscall_64.c | 2 +- arch/x86/kernel/vm86_32.c | 2 +- include/linux/sched/signal.h | 1 + kernel/entry/syscall_user_dispatch.c | 4 ++-- kernel/signal.c | 13 +++++++++++++ 11 files changed, 26 insertions(+), 12 deletions(-)
--- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -1145,7 +1145,7 @@ asmlinkage void set_esp0(unsigned long s */ asmlinkage void fpsp040_die(void) { - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); }
#ifdef CONFIG_M68KFPU_EMU --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -1063,7 +1063,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucon * We kill the task with a SIGSEGV in this situation. */ if (do_setcontext(new_ctx, regs, 0)) { - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); return -EFAULT; }
--- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -704,7 +704,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucon */
if (__get_user_sigset(&set, &new_ctx->uc_sigmask)) { - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); return -EFAULT; } set_current_blocked(&set); @@ -713,7 +713,7 @@ SYSCALL_DEFINE3(swapcontext, struct ucon return -EFAULT; if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)) { user_read_access_end(); - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); return -EFAULT; } user_read_access_end(); --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -84,7 +84,7 @@ static void default_trap_handler(struct { if (user_mode(regs)) { report_user_fault(regs, SIGSEGV, 0); - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); } else die(regs, "Unknown program exception"); } --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -244,7 +244,7 @@ static int setup_frame(struct ksignal *k get_sigframe(ksig, regs, sigframe_size);
if (invalid_frame_pointer(sf, sigframe_size)) { - force_fatal_sig(SIGILL); + force_exit_sig(SIGILL); return -EINVAL; }
@@ -336,7 +336,7 @@ static int setup_rt_frame(struct ksignal sf = (struct rt_signal_frame __user *) get_sigframe(ksig, regs, sigframe_size); if (invalid_frame_pointer(sf, sigframe_size)) { - force_fatal_sig(SIGILL); + force_exit_sig(SIGILL); return -EINVAL; }
--- a/arch/sparc/kernel/windows.c +++ b/arch/sparc/kernel/windows.c @@ -122,7 +122,7 @@ void try_to_clear_window_buffer(struct p if ((sp & 7) || copy_to_user((char __user *) sp, &tp->reg_window[window], sizeof(struct reg_window32))) { - force_fatal_sig(SIGILL); + force_exit_sig(SIGILL); return; } } --- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c @@ -226,7 +226,7 @@ bool emulate_vsyscall(unsigned long erro if ((!tmp && regs->orig_ax != syscall_nr) || regs->ip != address) { warn_bad_vsyscall(KERN_DEBUG, regs, "seccomp tried to change syscall nr or ip"); - force_fatal_sig(SIGSYS); + force_exit_sig(SIGSYS); return true; } regs->orig_ax = -1; --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -162,7 +162,7 @@ Efault_end: user_access_end(); Efault: pr_alert("could not access userspace vm86 info\n"); - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); goto exit_vm86; }
--- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -339,6 +339,7 @@ extern __must_check bool do_notify_paren extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent); extern void force_sig(int); extern void force_fatal_sig(int); +extern void force_exit_sig(int); extern int send_sig(int, struct task_struct *, int); extern int zap_other_threads(struct task_struct *p); extern struct sigqueue *sigqueue_alloc(void); --- a/kernel/entry/syscall_user_dispatch.c +++ b/kernel/entry/syscall_user_dispatch.c @@ -48,7 +48,7 @@ bool syscall_user_dispatch(struct pt_reg * the selector is loaded by userspace. */ if (unlikely(__get_user(state, sd->selector))) { - force_fatal_sig(SIGSEGV); + force_exit_sig(SIGSEGV); return true; }
@@ -56,7 +56,7 @@ bool syscall_user_dispatch(struct pt_reg return false;
if (state != SYSCALL_DISPATCH_FILTER_BLOCK) { - force_fatal_sig(SIGSYS); + force_exit_sig(SIGSYS); return true; } } --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1671,6 +1671,19 @@ void force_fatal_sig(int sig) force_sig_info_to_task(&info, current, HANDLER_SIG_DFL); }
+void force_exit_sig(int sig) +{ + struct kernel_siginfo info; + + clear_siginfo(&info); + info.si_signo = sig; + info.si_errno = 0; + info.si_code = SI_KERNEL; + info.si_pid = 0; + info.si_uid = 0; + force_sig_info_to_task(&info, current, HANDLER_EXIT); +} + /* * When things go south during signal handling, we * will force a SIGSEGV. And if the signal that caused
From: Nadav Amit namit@vmware.com
commit a4a118f2eead1d6c49e00765de89878288d4b890 upstream.
When __unmap_hugepage_range() calls to huge_pmd_unshare() succeed, a TLB flush is missing. This TLB flush must be performed before releasing the i_mmap_rwsem, in order to prevent an unshared PMDs page from being released and reused before the TLB flush took place.
Arguably, a comprehensive solution would use mmu_gather interface to batch the TLB flushes and the PMDs page release, however it is not an easy solution: (1) try_to_unmap_one() and try_to_migrate_one() also call huge_pmd_unshare() and they cannot use the mmu_gather interface; and (2) deferring the release of the page reference for the PMDs page until after i_mmap_rwsem is dropeed can confuse huge_pmd_unshare() into thinking PMDs are shared when they are not.
Fix __unmap_hugepage_range() by adding the missing TLB flush, and forcing a flush when unshare is successful.
Fixes: 24669e58477e ("hugetlb: use mmu_gather instead of a temporary linked list for accumulating pages)" # 3.6 Signed-off-by: Nadav Amit namit@vmware.com Reviewed-by: Mike Kravetz mike.kravetz@oracle.com Cc: Aneesh Kumar K.V aneesh.kumar@linux.vnet.ibm.com Cc: KAMEZAWA Hiroyuki kamezawa.hiroyu@jp.fujitsu.com Cc: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/hugetlb.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
--- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -4439,6 +4439,7 @@ void __unmap_hugepage_range(struct mmu_g struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); struct mmu_notifier_range range; + bool force_flush = false;
WARN_ON(!is_vm_hugetlb_page(vma)); BUG_ON(start & ~huge_page_mask(h)); @@ -4467,10 +4468,8 @@ void __unmap_hugepage_range(struct mmu_g ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, &address, ptep)) { spin_unlock(ptl); - /* - * We just unmapped a page of PMDs by clearing a PUD. - * The caller's TLB flush range should cover this area. - */ + tlb_flush_pmd_range(tlb, address & PUD_MASK, PUD_SIZE); + force_flush = true; continue; }
@@ -4527,6 +4526,22 @@ void __unmap_hugepage_range(struct mmu_g } mmu_notifier_invalidate_range_end(&range); tlb_end_vma(tlb, vma); + + /* + * If we unshared PMDs, the TLB flush was not recorded in mmu_gather. We + * could defer the flush until now, since by holding i_mmap_rwsem we + * guaranteed that the last refernece would not be dropped. But we must + * do the flushing before we return, as otherwise i_mmap_rwsem will be + * dropped and the last reference to the shared PMDs page might be + * dropped as well. + * + * In theory we could defer the freeing of the PMD pages as well, but + * huge_pmd_unshare() relies on the exact page_count for the PMD page to + * detect sharing, so we cannot defer the release of the page either. + * Instead, do flush now. + */ + if (force_flush) + tlb_flush_mmu_tlbonly(tlb); }
void __unmap_hugepage_range_final(struct mmu_gather *tlb,
From: Leon Romanovsky leonro@nvidia.com
commit 83dde7498fefeb920b1def317421262317d178e5 upstream.
Like other commits in the tree add __maybe_unused to a static inline in a C file because some clang compilers will complain about unused code:
drivers/infiniband/core/nldev.c:2543:1: warning: unused function '__chk_RDMA_NL_NLDEV'
MODULE_ALIAS_RDMA_NETLINK(RDMA_NL_NLDEV, 5); ^
Fixes: e3bf14bdc17a ("rdma: Autoload netlink client modules") Link: https://lore.kernel.org/r/4a8101919b765e01d7fde6f27fd572c958deeb4a.163626720... Reported-by: kernel test robot lkp@intel.com Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/rdma/rdma_netlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/include/rdma/rdma_netlink.h +++ b/include/rdma/rdma_netlink.h @@ -30,7 +30,7 @@ enum rdma_nl_flags { * constant as well and the compiler checks they are the same. */ #define MODULE_ALIAS_RDMA_NETLINK(_index, _val) \ - static inline void __chk_##_index(void) \ + static inline void __maybe_unused __chk_##_index(void) \ { \ BUILD_BUG_ON(_index != _val); \ } \
From: Dmitrii Banshchikov me@ubique.spb.ru
commit 5e0bc3082e2e403ac0753e099c2b01446bb35578 upstream.
Use of bpf_ktime_get_coarse_ns() and bpf_timer_* helpers in tracing progs may result in locking issues.
bpf_ktime_get_coarse_ns() uses ktime_get_coarse_ns() time accessor that isn't safe for any context: ====================================================== WARNING: possible circular locking dependency detected 5.15.0-syzkaller #0 Not tainted ------------------------------------------------------ syz-executor.4/14877 is trying to acquire lock: ffffffff8cb30008 (tk_core.seq.seqcount){----}-{0:0}, at: ktime_get_coarse_ts64+0x25/0x110 kernel/time/timekeeping.c:2255
but task is already holding lock: ffffffff90dbf200 (&obj_hash[i].lock){-.-.}-{2:2}, at: debug_object_deactivate+0x61/0x400 lib/debugobjects.c:735
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&obj_hash[i].lock){-.-.}-{2:2}: lock_acquire+0x19f/0x4d0 kernel/locking/lockdep.c:5625 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:110 [inline] _raw_spin_lock_irqsave+0xd1/0x120 kernel/locking/spinlock.c:162 __debug_object_init+0xd9/0x1860 lib/debugobjects.c:569 debug_hrtimer_init kernel/time/hrtimer.c:414 [inline] debug_init kernel/time/hrtimer.c:468 [inline] hrtimer_init+0x20/0x40 kernel/time/hrtimer.c:1592 ntp_init_cmos_sync kernel/time/ntp.c:676 [inline] ntp_init+0xa1/0xad kernel/time/ntp.c:1095 timekeeping_init+0x512/0x6bf kernel/time/timekeeping.c:1639 start_kernel+0x267/0x56e init/main.c:1030 secondary_startup_64_no_verify+0xb1/0xbb
-> #0 (tk_core.seq.seqcount){----}-{0:0}: check_prev_add kernel/locking/lockdep.c:3051 [inline] check_prevs_add kernel/locking/lockdep.c:3174 [inline] validate_chain+0x1dfb/0x8240 kernel/locking/lockdep.c:3789 __lock_acquire+0x1382/0x2b00 kernel/locking/lockdep.c:5015 lock_acquire+0x19f/0x4d0 kernel/locking/lockdep.c:5625 seqcount_lockdep_reader_access+0xfe/0x230 include/linux/seqlock.h:103 ktime_get_coarse_ts64+0x25/0x110 kernel/time/timekeeping.c:2255 ktime_get_coarse include/linux/timekeeping.h:120 [inline] ktime_get_coarse_ns include/linux/timekeeping.h:126 [inline] ____bpf_ktime_get_coarse_ns kernel/bpf/helpers.c:173 [inline] bpf_ktime_get_coarse_ns+0x7e/0x130 kernel/bpf/helpers.c:171 bpf_prog_a99735ebafdda2f1+0x10/0xb50 bpf_dispatcher_nop_func include/linux/bpf.h:721 [inline] __bpf_prog_run include/linux/filter.h:626 [inline] bpf_prog_run include/linux/filter.h:633 [inline] BPF_PROG_RUN_ARRAY include/linux/bpf.h:1294 [inline] trace_call_bpf+0x2cf/0x5d0 kernel/trace/bpf_trace.c:127 perf_trace_run_bpf_submit+0x7b/0x1d0 kernel/events/core.c:9708 perf_trace_lock+0x37c/0x440 include/trace/events/lock.h:39 trace_lock_release+0x128/0x150 include/trace/events/lock.h:58 lock_release+0x82/0x810 kernel/locking/lockdep.c:5636 __raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:149 [inline] _raw_spin_unlock_irqrestore+0x75/0x130 kernel/locking/spinlock.c:194 debug_hrtimer_deactivate kernel/time/hrtimer.c:425 [inline] debug_deactivate kernel/time/hrtimer.c:481 [inline] __run_hrtimer kernel/time/hrtimer.c:1653 [inline] __hrtimer_run_queues+0x2f9/0xa60 kernel/time/hrtimer.c:1749 hrtimer_interrupt+0x3b3/0x1040 kernel/time/hrtimer.c:1811 local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1086 [inline] __sysvec_apic_timer_interrupt+0xf9/0x270 arch/x86/kernel/apic/apic.c:1103 sysvec_apic_timer_interrupt+0x8c/0xb0 arch/x86/kernel/apic/apic.c:1097 asm_sysvec_apic_timer_interrupt+0x12/0x20 __raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:152 [inline] _raw_spin_unlock_irqrestore+0xd4/0x130 kernel/locking/spinlock.c:194 try_to_wake_up+0x702/0xd20 kernel/sched/core.c:4118 wake_up_process kernel/sched/core.c:4200 [inline] wake_up_q+0x9a/0xf0 kernel/sched/core.c:953 futex_wake+0x50f/0x5b0 kernel/futex/waitwake.c:184 do_futex+0x367/0x560 kernel/futex/syscalls.c:127 __do_sys_futex kernel/futex/syscalls.c:199 [inline] __se_sys_futex+0x401/0x4b0 kernel/futex/syscalls.c:180 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
There is a possible deadlock with bpf_timer_* set of helpers: hrtimer_start() lock_base(); trace_hrtimer...() perf_event() bpf_run() bpf_timer_start() hrtimer_start() lock_base() <- DEADLOCK
Forbid use of bpf_ktime_get_coarse_ns() and bpf_timer_* helpers in BPF_PROG_TYPE_KPROBE, BPF_PROG_TYPE_TRACEPOINT, BPF_PROG_TYPE_PERF_EVENT and BPF_PROG_TYPE_RAW_TRACEPOINT prog types.
Fixes: d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper") Fixes: b00628b1c7d5 ("bpf: Introduce bpf timers.") Reported-by: syzbot+43fd005b5a1b4d10781e@syzkaller.appspotmail.com Signed-off-by: Dmitrii Banshchikov me@ubique.spb.ru Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20211113142227.566439-2-me@ubique.spb.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/bpf/cgroup.c | 2 ++ kernel/bpf/helpers.c | 2 -- kernel/bpf/verifier.c | 7 +++++++ kernel/trace/bpf_trace.c | 2 -- net/core/filter.c | 6 ++++++ net/ipv4/bpf_tcp_ca.c | 2 ++ 6 files changed, 17 insertions(+), 4 deletions(-)
--- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1773,6 +1773,8 @@ sysctl_func_proto(enum bpf_func_id func_ return &bpf_sysctl_get_new_value_proto; case BPF_FUNC_sysctl_set_new_value: return &bpf_sysctl_set_new_value_proto; + case BPF_FUNC_ktime_get_coarse_ns: + return &bpf_ktime_get_coarse_ns_proto; default: return cgroup_base_func_proto(func_id, prog); } --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -1367,8 +1367,6 @@ bpf_base_func_proto(enum bpf_func_id fun return &bpf_ktime_get_ns_proto; case BPF_FUNC_ktime_get_boot_ns: return &bpf_ktime_get_boot_ns_proto; - case BPF_FUNC_ktime_get_coarse_ns: - return &bpf_ktime_get_coarse_ns_proto; case BPF_FUNC_ringbuf_output: return &bpf_ringbuf_output_proto; case BPF_FUNC_ringbuf_reserve: --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -11451,6 +11451,13 @@ static int check_map_prog_compatibility( } }
+ if (map_value_has_timer(map)) { + if (is_tracing_prog_type(prog_type)) { + verbose(env, "tracing progs cannot use bpf_timer yet\n"); + return -EINVAL; + } + } + if ((bpf_prog_is_dev_bound(prog->aux) || bpf_map_is_dev_bound(map)) && !bpf_offload_prog_map_match(prog, map)) { verbose(env, "offload device mismatch between prog and map\n"); --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1037,8 +1037,6 @@ bpf_tracing_func_proto(enum bpf_func_id return &bpf_ktime_get_ns_proto; case BPF_FUNC_ktime_get_boot_ns: return &bpf_ktime_get_boot_ns_proto; - case BPF_FUNC_ktime_get_coarse_ns: - return &bpf_ktime_get_coarse_ns_proto; case BPF_FUNC_tail_call: return &bpf_tail_call_proto; case BPF_FUNC_get_current_pid_tgid: --- a/net/core/filter.c +++ b/net/core/filter.c @@ -7162,6 +7162,8 @@ sock_filter_func_proto(enum bpf_func_id #endif case BPF_FUNC_sk_storage_get: return &bpf_sk_storage_get_cg_sock_proto; + case BPF_FUNC_ktime_get_coarse_ns: + return &bpf_ktime_get_coarse_ns_proto; default: return bpf_base_func_proto(func_id); } @@ -10306,6 +10308,8 @@ sk_reuseport_func_proto(enum bpf_func_id return &sk_reuseport_load_bytes_relative_proto; case BPF_FUNC_get_socket_cookie: return &bpf_get_socket_ptr_cookie_proto; + case BPF_FUNC_ktime_get_coarse_ns: + return &bpf_ktime_get_coarse_ns_proto; default: return bpf_base_func_proto(func_id); } @@ -10787,6 +10791,8 @@ bpf_sk_base_func_proto(enum bpf_func_id case BPF_FUNC_skc_to_udp6_sock: func = &bpf_skc_to_udp6_sock_proto; break; + case BPF_FUNC_ktime_get_coarse_ns: + return &bpf_ktime_get_coarse_ns_proto; default: return bpf_base_func_proto(func_id); } --- a/net/ipv4/bpf_tcp_ca.c +++ b/net/ipv4/bpf_tcp_ca.c @@ -212,6 +212,8 @@ bpf_tcp_ca_get_func_proto(enum bpf_func_ offsetof(struct tcp_congestion_ops, release)) return &bpf_sk_getsockopt_proto; return NULL; + case BPF_FUNC_ktime_get_coarse_ns: + return &bpf_ktime_get_coarse_ns_proto; default: return bpf_base_func_proto(func_id); }
From: Ondrej Mosnacek omosnace@redhat.com
commit dc27f3c5d10c58069672215787a96b4fae01818b upstream.
When the hash table slot array allocation fails in hashtab_init(), h->size is left initialized with a non-zero value, but the h->htable pointer is NULL. This may then cause a NULL pointer dereference, since the policydb code relies on the assumption that even after a failed hashtab_init(), hashtab_map() and hashtab_destroy() can be safely called on it. Yet, these detect an empty hashtab only by looking at the size.
Fix this by making sure that hashtab_init() always leaves behind a valid empty hashtab when the allocation fails.
Cc: stable@vger.kernel.org Fixes: 03414a49ad5f ("selinux: do not allocate hashtabs dynamically") Signed-off-by: Ondrej Mosnacek omosnace@redhat.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/selinux/ss/hashtab.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
--- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -30,13 +30,20 @@ static u32 hashtab_compute_size(u32 nel)
int hashtab_init(struct hashtab *h, u32 nel_hint) { - h->size = hashtab_compute_size(nel_hint); + u32 size = hashtab_compute_size(nel_hint); + + /* should already be zeroed, but better be safe */ h->nel = 0; - if (!h->size) - return 0; + h->size = 0; + h->htable = NULL;
- h->htable = kcalloc(h->size, sizeof(*h->htable), GFP_KERNEL); - return h->htable ? 0 : -ENOMEM; + if (size) { + h->htable = kcalloc(size, sizeof(*h->htable), GFP_KERNEL); + if (!h->htable) + return -ENOMEM; + h->size = size; + } + return 0; }
int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
From: Takashi Iwai tiwai@suse.de
commit 827b0913a9d9d07a0c3e559dbb20ca4d6d285a54 upstream.
The recent fix for DAPM to correct the kctl change notification by the commit 5af82c81b2c4 ("ASoC: DAPM: Fix missing kctl change notifications") caused other regressions since it changed the behavior of snd_soc_dapm_set_pin() that is called from several API functions. Formerly it returned always 0 for success, but now it returns 0 or 1.
This patch addresses it, restoring the old behavior of snd_soc_dapm_set_pin() while keeping the fix in snd_soc_dapm_put_pin_switch().
Fixes: 5af82c81b2c4 ("ASoC: DAPM: Fix missing kctl change notifications") Reported-by: Yu-Hsuan Hsu yuhsuan@chromium.org Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/r/20211105090925.20575-1-tiwai@suse.de Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/soc-dapm.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
--- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2557,8 +2557,13 @@ static struct snd_soc_dapm_widget *dapm_ return NULL; }
-static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, - const char *pin, int status) +/* + * set the DAPM pin status: + * returns 1 when the value has been updated, 0 when unchanged, or a negative + * error code; called from kcontrol put callback + */ +static int __snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, + const char *pin, int status) { struct snd_soc_dapm_widget *w = dapm_find_widget(dapm, pin, true); int ret = 0; @@ -2584,6 +2589,18 @@ static int snd_soc_dapm_set_pin(struct s return ret; }
+/* + * similar as __snd_soc_dapm_set_pin(), but returns 0 when successful; + * called from several API functions below + */ +static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, + const char *pin, int status) +{ + int ret = __snd_soc_dapm_set_pin(dapm, pin, status); + + return ret < 0 ? ret : 0; +} + /** * snd_soc_dapm_sync_unlocked - scan and power dapm paths * @dapm: DAPM context @@ -3587,10 +3604,10 @@ int snd_soc_dapm_put_pin_switch(struct s const char *pin = (const char *)kcontrol->private_value; int ret;
- if (ucontrol->value.integer.value[0]) - ret = snd_soc_dapm_enable_pin(&card->dapm, pin); - else - ret = snd_soc_dapm_disable_pin(&card->dapm, pin); + mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); + ret = __snd_soc_dapm_set_pin(&card->dapm, pin, + !!ucontrol->value.integer.value[0]); + mutex_unlock(&card->dapm_mutex);
snd_soc_dapm_sync(&card->dapm); return ret;
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
commit 2ce1b21cb3326e12af3c72c47e1d294b19d73947 upstream.
commit d5bb69dc54ec1 ("ASoC: sh: rcar: dma: : use proper DMAENGINE API for termination") updated DMAEngine API _all() to _sync(), but it should be _async(). _all() and _async() are almost same, the difference is only return error code. _sync() will call dmaengine_synchronize() and will be kernel panic. This patch is needed for v5.15 or later.
[ 27.293264] BUG: scheduling while atomic: irq/130-ec70000/131/0x00000003 [ 27.300084] 2 locks held by irq/130-ec70000/131: [ 27.304743] #0: ffff0004c274d908 (&group->lock){....}-{2:2}, at: _snd_pcm_stream_lock_irqsave+0x48/0x54 [ 27.314344] #1: ffff0004c1788c60 (&priv->lock#2){....}-{2:2}, at: rsnd_soc_dai_trigger+0x70/0x7bc [ 27.323409] irq event stamp: 206 [ 27.326664] hardirqs last enabled at (205): [<ffff80001082de50>] _raw_spin_unlock_irq+0x50/0xa0 [ 27.335529] hardirqs last disabled at (206): [<ffff80001082d9e4>] _raw_spin_lock_irqsave+0xc4/0xd0 [ 27.344564] softirqs last enabled at (0): [<ffff800010037324>] copy_process+0x644/0x1b10 [ 27.352819] softirqs last disabled at (0): [<0000000000000000>] 0x0 [ 27.359142] CPU: 0 PID: 131 Comm: irq/130-ec70000 Not tainted 5.14.0-rc1+ #918 [ 27.366429] Hardware name: Renesas H3ULCB Kingfisher board based on r8a77950 (DT) [ 27.373975] Call trace: [ 27.376442] dump_backtrace+0x0/0x1b4 [ 27.380141] show_stack+0x24/0x30 [ 27.383488] dump_stack_lvl+0x8c/0xb8 [ 27.387184] dump_stack+0x18/0x34 [ 27.390528] __schedule_bug+0x8c/0x9c [ 27.394224] __schedule+0x790/0x8dc [ 27.397746] schedule+0x7c/0x110 [ 27.401003] synchronize_irq+0x94/0xd0 [ 27.404786] rcar_dmac_device_synchronize+0x20/0x2c [ 27.409710] rsnd_dmaen_stop+0x50/0x64 [ 27.413495] rsnd_soc_dai_trigger+0x554/0x7bc [ 27.417890] snd_soc_pcm_dai_trigger+0xe8/0x264
Cc: stable@kernel.org Fixes: commit d5bb69dc54ec1 ("ASoC: sh: rcar: dma: : use proper DMAENGINE API for termination") Link: https://lore.kernel.org/r/TY2PR01MB3692889E1A7476C4322CC296D8AE9@TY2PR01MB36... Reported-by: Yoshihiro Shimoda yoshihiro.shimoda.uh@renesas.com Acked-by: Wolfram Sang wsa+renesas@sang-engineering.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87mtmfz36o.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/sh/rcar/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c @@ -102,7 +102,7 @@ static int rsnd_dmaen_stop(struct rsnd_m struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
if (dmaen->chan) - dmaengine_terminate_sync(dmaen->chan); + dmaengine_terminate_async(dmaen->chan);
return 0; }
From: Uwe Kleine-König u.kleine-koenig@pengutronix.de
commit fc153aba3ef371d0d76eb88230ed4e0dee5b38f2 upstream.
Instead of maintaining a single-linked list of devices that must be searched linearly in .remove() just use spi_set_drvdata() to remember the link between the spi device and the driver struct. Then the global list and the next member can be dropped.
This simplifies the driver, reduces the memory footprint and the time to search the list. Also it makes obvious that there is always a corresponding driver struct for a given device in .remove(), so the error path for !max3421_hcd can be dropped, too.
As a side effect this fixes a data inconsistency when .probe() races with itself for a second max3421 device in manipulating max3421_hcd_list. A similar race is fixed in .remove(), too.
Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.") Signed-off-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Link: https://lore.kernel.org/r/20211018204028.2914597-1-u.kleine-koenig@pengutron... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/max3421-hcd.c | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-)
--- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -125,8 +125,6 @@ struct max3421_hcd {
struct task_struct *spi_thread;
- struct max3421_hcd *next; - enum max3421_rh_state rh_state; /* lower 16 bits contain port status, upper 16 bits the change mask: */ u32 port_status; @@ -174,8 +172,6 @@ struct max3421_ep { u8 retransmit; /* packet needs retransmission */ };
-static struct max3421_hcd *max3421_hcd_list; - #define MAX3421_FIFO_SIZE 64
#define MAX3421_SPI_DIR_RD 0 /* read register from MAX3421 */ @@ -1882,9 +1878,8 @@ max3421_probe(struct spi_device *spi) } set_bit(HCD_FLAG_POLL_RH, &hcd->flags); max3421_hcd = hcd_to_max3421(hcd); - max3421_hcd->next = max3421_hcd_list; - max3421_hcd_list = max3421_hcd; INIT_LIST_HEAD(&max3421_hcd->ep_list); + spi_set_drvdata(spi, max3421_hcd);
max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); if (!max3421_hcd->tx) @@ -1934,28 +1929,18 @@ error: static int max3421_remove(struct spi_device *spi) { - struct max3421_hcd *max3421_hcd = NULL, **prev; - struct usb_hcd *hcd = NULL; + struct max3421_hcd *max3421_hcd; + struct usb_hcd *hcd; unsigned long flags;
- for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) { - max3421_hcd = *prev; - hcd = max3421_to_hcd(max3421_hcd); - if (hcd->self.controller == &spi->dev) - break; - } - if (!max3421_hcd) { - dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n", - spi); - return -ENODEV; - } + max3421_hcd = spi_get_drvdata(spi); + hcd = max3421_to_hcd(max3421_hcd);
usb_remove_hcd(hcd);
spin_lock_irqsave(&max3421_hcd->lock, flags);
kthread_stop(max3421_hcd->spi_thread); - *prev = max3421_hcd->next;
spin_unlock_irqrestore(&max3421_hcd->lock, flags);
From: Brett Creeley brett.creeley@intel.com
commit 1a8c7778bcde5981463a5b9f9b2caa44a327ff93 upstream.
When a VF requests promiscuous mode and it's trusted and true promiscuous mode is enabled the PF driver attempts to enable unicast and/or multicast promiscuous mode filters based on the request. This is fine, but there are a couple issues with the current code.
[1] The define to configure the unicast promiscuous mode mask also includes bits to configure the multicast promiscuous mode mask, which causes multicast to be set/cleared unintentionally. [2] All 4 cases for enable/disable unicast/multicast mode are not handled in the promiscuous mode message handler, which causes unexpected results regarding the current promiscuous mode settings.
To fix [1] make sure any promiscuous mask defines include the correct bits for each of the promiscuous modes.
To fix [2] make sure that all 4 cases are handled since there are 2 bits (FLAG_VF_UNICAST_PROMISC and FLAG_VF_MULTICAST_PROMISC) that can be either set or cleared. Also, since either unicast and/or multicast promiscuous configuration can fail, introduce two separate error values to handle each of these cases.
Fixes: 01b5e89aab49 ("ice: Add VF promiscuous support") Signed-off-by: Brett Creeley brett.creeley@intel.com Tested-by: Tony Brelinski tony.brelinski@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/intel/ice/ice.h | 5 - drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 78 +++++++++++------------ 2 files changed, 40 insertions(+), 43 deletions(-)
--- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -139,13 +139,10 @@ #define ice_for_each_q_vector(vsi, i) \ for ((i) = 0; (i) < (vsi)->num_q_vectors; (i)++)
-#define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_MCAST_TX | \ - ICE_PROMISC_UCAST_RX | ICE_PROMISC_MCAST_RX) +#define ICE_UCAST_PROMISC_BITS (ICE_PROMISC_UCAST_TX | ICE_PROMISC_UCAST_RX)
#define ICE_UCAST_VLAN_PROMISC_BITS (ICE_PROMISC_UCAST_TX | \ - ICE_PROMISC_MCAST_TX | \ ICE_PROMISC_UCAST_RX | \ - ICE_PROMISC_MCAST_RX | \ ICE_PROMISC_VLAN_TX | \ ICE_PROMISC_VLAN_RX)
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -2952,6 +2952,7 @@ bool ice_is_any_vf_in_promisc(struct ice static int ice_vc_cfg_promiscuous_mode_msg(struct ice_vf *vf, u8 *msg) { enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; + enum ice_status mcast_status = 0, ucast_status = 0; bool rm_promisc, alluni = false, allmulti = false; struct virtchnl_promisc_info *info = (struct virtchnl_promisc_info *)msg; @@ -3041,52 +3042,51 @@ static int ice_vc_cfg_promiscuous_mode_m goto error_param; } } else { - enum ice_status status; - u8 promisc_m; + u8 mcast_m, ucast_m;
- if (alluni) { - if (vf->port_vlan_info || vsi->num_vlan) - promisc_m = ICE_UCAST_VLAN_PROMISC_BITS; - else - promisc_m = ICE_UCAST_PROMISC_BITS; - } else if (allmulti) { - if (vf->port_vlan_info || vsi->num_vlan) - promisc_m = ICE_MCAST_VLAN_PROMISC_BITS; - else - promisc_m = ICE_MCAST_PROMISC_BITS; + if (vf->port_vlan_info || vsi->num_vlan > 1) { + mcast_m = ICE_MCAST_VLAN_PROMISC_BITS; + ucast_m = ICE_UCAST_VLAN_PROMISC_BITS; } else { - if (vf->port_vlan_info || vsi->num_vlan) - promisc_m = ICE_UCAST_VLAN_PROMISC_BITS; - else - promisc_m = ICE_UCAST_PROMISC_BITS; + mcast_m = ICE_MCAST_PROMISC_BITS; + ucast_m = ICE_UCAST_PROMISC_BITS; }
- /* Configure multicast/unicast with or without VLAN promiscuous - * mode - */ - status = ice_vf_set_vsi_promisc(vf, vsi, promisc_m, rm_promisc); - if (status) { - dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed, error: %s\n", - rm_promisc ? "dis" : "en", vf->vf_id, - ice_stat_str(status)); - v_ret = ice_err_to_virt_err(status); - goto error_param; - } else { - dev_dbg(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d succeeded\n", - rm_promisc ? "dis" : "en", vf->vf_id); + ucast_status = ice_vf_set_vsi_promisc(vf, vsi, ucast_m, + !alluni); + if (ucast_status) { + dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n", + alluni ? "en" : "dis", vf->vf_id); + v_ret = ice_err_to_virt_err(ucast_status); + } + + mcast_status = ice_vf_set_vsi_promisc(vf, vsi, mcast_m, + !allmulti); + if (mcast_status) { + dev_err(dev, "%sable Tx/Rx filter promiscuous mode on VF-%d failed\n", + allmulti ? "en" : "dis", vf->vf_id); + v_ret = ice_err_to_virt_err(mcast_status); } }
- if (allmulti && - !test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) - dev_info(dev, "VF %u successfully set multicast promiscuous mode\n", vf->vf_id); - else if (!allmulti && test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) - dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n", vf->vf_id); - - if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) - dev_info(dev, "VF %u successfully set unicast promiscuous mode\n", vf->vf_id); - else if (!alluni && test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) - dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n", vf->vf_id); + if (!mcast_status) { + if (allmulti && + !test_and_set_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) + dev_info(dev, "VF %u successfully set multicast promiscuous mode\n", + vf->vf_id); + else if (!allmulti && test_and_clear_bit(ICE_VF_STATE_MC_PROMISC, vf->vf_states)) + dev_info(dev, "VF %u successfully unset multicast promiscuous mode\n", + vf->vf_id); + } + + if (!ucast_status) { + if (alluni && !test_and_set_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) + dev_info(dev, "VF %u successfully set unicast promiscuous mode\n", + vf->vf_id); + else if (!alluni && test_and_clear_bit(ICE_VF_STATE_UC_PROMISC, vf->vf_states)) + dev_info(dev, "VF %u successfully unset unicast promiscuous mode\n", + vf->vf_id); + }
error_param: return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
From: Leon Romanovsky leonro@nvidia.com
commit 2ff04286a9569675948f39cec2c6ad47c3584633 upstream.
PF pointer is always valid when PCI core calls its .shutdown() and .remove() callbacks. There is no need to check it again.
Fixes: 837f08fdecbe ("ice: Add basic driver framework for Intel(R) E800 Series") Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/intel/ice/ice_main.c | 3 --- 1 file changed, 3 deletions(-)
--- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -4600,9 +4600,6 @@ static void ice_remove(struct pci_dev *p struct ice_pf *pf = pci_get_drvdata(pdev); int i;
- if (!pf) - return; - for (i = 0; i < ICE_MAX_RESET_WAIT; i++) { if (!ice_is_reset_in_progress(pf->state)) break;
From: Josef Bacik josef@toxicpanda.com
commit e60feb445fce9e51c1558a6aa7faf9dd5ded533b upstream.
If you already have an inode and need to update the time on the inode there is no way to do this properly. Export this helper to allow file systems to update time on the inode so the appropriate handler is called, either ->update_time or generic_update_time.
Signed-off-by: Josef Bacik josef@toxicpanda.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/inode.c | 7 ++++--- include/linux/fs.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-)
--- a/fs/inode.c +++ b/fs/inode.c @@ -1782,12 +1782,13 @@ EXPORT_SYMBOL(generic_update_time); * This does the actual work of updating an inodes time or version. Must have * had called mnt_want_write() before calling this. */ -static int update_time(struct inode *inode, struct timespec64 *time, int flags) +int inode_update_time(struct inode *inode, struct timespec64 *time, int flags) { if (inode->i_op->update_time) return inode->i_op->update_time(inode, time, flags); return generic_update_time(inode, time, flags); } +EXPORT_SYMBOL(inode_update_time);
/** * atime_needs_update - update the access time @@ -1857,7 +1858,7 @@ void touch_atime(const struct path *path * of the fs read only, e.g. subvolumes in Btrfs. */ now = current_time(inode); - update_time(inode, &now, S_ATIME); + inode_update_time(inode, &now, S_ATIME); __mnt_drop_write(mnt); skip_update: sb_end_write(inode->i_sb); @@ -2002,7 +2003,7 @@ int file_update_time(struct file *file) if (__mnt_want_write_file(file)) return 0;
- ret = update_time(inode, &now, sync_it); + ret = inode_update_time(inode, &now, sync_it); __mnt_drop_write_file(file);
return ret; --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2498,6 +2498,8 @@ enum file_time_flags {
extern bool atime_needs_update(const struct path *, struct inode *); extern void touch_atime(const struct path *); +int inode_update_time(struct inode *inode, struct timespec64 *time, int flags); + static inline void file_accessed(struct file *file) { if (!(file->f_flags & O_NOATIME))
From: Josef Bacik josef@toxicpanda.com
commit 54fde91f52f515e0b1514f0f0fa146e87a672227 upstream.
Christoph pointed out that I'm updating bdev->bd_inode for the device time when we remove block devices from a btrfs file system, however this isn't actually exposed to anything. The inode we want to update is the one that's associated with the path to the device, usually on devtmpfs, so that blkid notices the difference.
We still don't want to do the blkdev_open, so use kern_path() to get the path to the given device and do the update time on that inode.
Fixes: 8f96a5bfa150 ("btrfs: update the bdev time directly when closing") Reported-by: Christoph Hellwig hch@lst.de Signed-off-by: Josef Bacik josef@toxicpanda.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/volumes.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
--- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -14,6 +14,7 @@ #include <linux/semaphore.h> #include <linux/uuid.h> #include <linux/list_sort.h> +#include <linux/namei.h> #include "misc.h" #include "ctree.h" #include "extent_map.h" @@ -1884,18 +1885,22 @@ out: /* * Function to update ctime/mtime for a given device path. * Mainly used for ctime/mtime based probe like libblkid. + * + * We don't care about errors here, this is just to be kind to userspace. */ -static void update_dev_time(struct block_device *bdev) +static void update_dev_time(const char *device_path) { - struct inode *inode = bdev->bd_inode; + struct path path; struct timespec64 now; + int ret;
- /* Shouldn't happen but just in case. */ - if (!inode) + ret = kern_path(device_path, LOOKUP_FOLLOW, &path); + if (ret) return;
- now = current_time(inode); - generic_update_time(inode, &now, S_MTIME | S_CTIME); + now = current_time(d_inode(path.dentry)); + inode_update_time(d_inode(path.dentry), &now, S_MTIME | S_CTIME); + path_put(&path); }
static int btrfs_rm_dev_item(struct btrfs_device *device) @@ -2071,7 +2076,7 @@ void btrfs_scratch_superblocks(struct bt btrfs_kobject_uevent(bdev, KOBJ_CHANGE);
/* Update ctime/mtime for device path for libblkid */ - update_dev_time(bdev); + update_dev_time(device_path); }
int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, @@ -2735,7 +2740,7 @@ int btrfs_init_new_device(struct btrfs_f btrfs_forget_devices(device_path);
/* Update ctime/mtime for blkid or udev */ - update_dev_time(bdev); + update_dev_time(device_path);
return ret;
From: Eric Dumazet edumazet@google.com
commit c4777efa751d293e369aec464ce6875e957be255 upstream.
While commit 097b9146c0e2 ("net: fix up truesize of cloned skb in skb_prepare_for_shift()") fixed immediate issues found when KFENCE was enabled/tested, there are still similar issues, when tcp_trim_head() hits KFENCE while the master skb is cloned.
This happens under heavy networking TX workloads, when the TX completion might be delayed after incoming ACK.
This patch fixes the WARNING in sk_stream_kill_queues when sk->sk_mem_queued/sk->sk_forward_alloc are not zero.
Fixes: d3fb45f370d9 ("mm, kfence: insert KFENCE hooks for SLAB") Signed-off-by: Eric Dumazet edumazet@google.com Acked-by: Marco Elver elver@google.com Link: https://lore.kernel.org/r/20211102004555.1359210-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/skbuff.h | 16 ++++++++++++++++ net/core/skbuff.c | 14 +------------- net/ipv4/tcp_output.c | 6 +++--- 3 files changed, 20 insertions(+), 16 deletions(-)
--- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1671,6 +1671,22 @@ static inline int skb_unclone(struct sk_ return 0; }
+/* This variant of skb_unclone() makes sure skb->truesize is not changed */ +static inline int skb_unclone_keeptruesize(struct sk_buff *skb, gfp_t pri) +{ + might_sleep_if(gfpflags_allow_blocking(pri)); + + if (skb_cloned(skb)) { + unsigned int save = skb->truesize; + int res; + + res = pskb_expand_head(skb, 0, 0, pri); + skb->truesize = save; + return res; + } + return 0; +} + /** * skb_header_cloned - is the header a clone * @skb: buffer to check --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -3449,19 +3449,7 @@ EXPORT_SYMBOL(skb_split); */ static int skb_prepare_for_shift(struct sk_buff *skb) { - int ret = 0; - - if (skb_cloned(skb)) { - /* Save and restore truesize: pskb_expand_head() may reallocate - * memory where ksize(kmalloc(S)) != ksize(kmalloc(S)), but we - * cannot change truesize at this point. - */ - unsigned int save_truesize = skb->truesize; - - ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); - skb->truesize = save_truesize; - } - return ret; + return skb_unclone_keeptruesize(skb, GFP_ATOMIC); }
/** --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1562,7 +1562,7 @@ int tcp_fragment(struct sock *sk, enum t return -ENOMEM; }
- if (skb_unclone(skb, gfp)) + if (skb_unclone_keeptruesize(skb, gfp)) return -ENOMEM;
/* Get a new skb... force flag on. */ @@ -1672,7 +1672,7 @@ int tcp_trim_head(struct sock *sk, struc { u32 delta_truesize;
- if (skb_unclone(skb, GFP_ATOMIC)) + if (skb_unclone_keeptruesize(skb, GFP_ATOMIC)) return -ENOMEM;
delta_truesize = __pskb_trim_head(skb, len); @@ -3184,7 +3184,7 @@ int __tcp_retransmit_skb(struct sock *sk cur_mss, GFP_ATOMIC)) return -ENOMEM; /* We'll try again later. */ } else { - if (skb_unclone(skb, GFP_ATOMIC)) + if (skb_unclone_keeptruesize(skb, GFP_ATOMIC)) return -ENOMEM;
diff = tcp_skb_pcount(skb);
From: Randy Dunlap rdunlap@infradead.org
commit ef775a0e36c6a81c5b07cb228c02f967133fe768 upstream.
When CONFIG_PROC_FS is not set, there is a build warning (turned into an error):
../drivers/hwmon/dell-smm-hwmon.c: In function 'i8k_init_procfs': ../drivers/hwmon/dell-smm-hwmon.c:624:24: error: unused variable 'data' [-Werror=unused-variable] struct dell_smm_data *data = dev_get_drvdata(dev);
Make I8K depend on PROC_FS and HWMON (instead of selecting HWMON -- it is strongly preferred to not select entire subsystems).
Build tested in all possible combinations of SENSORS_DELL_SMM, I8K, and PROC_FS.
Fixes: 039ae58503f3 ("hwmon: Allow to compile dell-smm-hwmon driver without /proc/i8k") Reported-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Borislav Petkov bp@suse.de Reviewed-by: Arnd Bergmann arnd@arndb.de Acked-by: Guenter Roeck linux@roeck-us.net Acked-by: Pali Rohár pali@kernel.org Link: https://lkml.kernel.org/r/20210910071921.16777-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1256,7 +1256,8 @@ config TOSHIBA
config I8K tristate "Dell i8k legacy laptop support" - select HWMON + depends on HWMON + depends on PROC_FS select SENSORS_DELL_SMM help This option enables legacy /proc/i8k userspace interface in hwmon
On Wed, 24 Nov 2021 12:54:47 +0100, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.5 release. There are 279 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 Fri, 26 Nov 2021 11:56:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.5-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.15.y and the diffstat can be found below.
thanks,
greg k-h
5.15.5-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Tested-by: Fox Chen foxhlchen@gmail.com
On Wed, Nov 24, 2021 at 12:54:47PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.5 release. There are 279 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 Fri, 26 Nov 2021 11:56:36 +0000. Anything received after that time might be too late.
Build results: total: 154 pass: 154 fail: 0 Qemu test results: total: 482 pass: 482 fail: 0
Tested-by: Guenter Roeck linux@roeck-us.net
Guenter
On Wed, 24 Nov 2021 at 18:35, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.5 release. There are 279 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 Fri, 26 Nov 2021 11:56:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.5-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.15.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 5.15.5-rc1 * git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc * git branch: linux-5.15.y * git commit: e3bb2e602026d5d841d7a2e62bfbe579265bb5ff * git describe: v5.15.4-280-ge3bb2e602026 * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15....
## No regressions (compared to v5.15.3)
## No fixes (compared to v5.15.3)
## Test result summary total: 97214, pass: 82201, fail: 1196, skip: 13115, xfail: 702
## Build Summary * arc: 10 total, 10 passed, 0 failed * arm: 259 total, 259 passed, 0 failed * arm64: 37 total, 35 passed, 2 failed * dragonboard-410c: 1 total, 1 passed, 0 failed * hi6220-hikey: 1 total, 1 passed, 0 failed * i386: 36 total, 36 passed, 0 failed * juno-r2: 1 total, 1 passed, 0 failed * mips: 34 total, 34 passed, 0 failed * parisc: 12 total, 12 passed, 0 failed * powerpc: 45 total, 42 passed, 3 failed * riscv: 24 total, 24 passed, 0 failed * s390: 18 total, 18 passed, 0 failed * sh: 20 total, 20 passed, 0 failed * sparc: 12 total, 12 passed, 0 failed * x15: 1 total, 1 passed, 0 failed * x86: 1 total, 1 passed, 0 failed * x86_64: 37 total, 37 passed, 0 failed
## Test suites summary * fwts * igt-gpu-tools * kselftest-android * kselftest-arm64 * kselftest-arm64/arm64.btitest.bti_c_func * kselftest-arm64/arm64.btitest.bti_j_func * kselftest-arm64/arm64.btitest.bti_jc_func * kselftest-arm64/arm64.btitest.bti_none_func * kselftest-arm64/arm64.btitest.nohint_func * kselftest-arm64/arm64.btitest.paciasp_func * kselftest-arm64/arm64.nobtitest.bti_c_func * kselftest-arm64/arm64.nobtitest.bti_j_func * kselftest-arm64/arm64.nobtitest.bti_jc_func * kselftest-arm64/arm64.nobtitest.bti_none_func * kselftest-arm64/arm64.nobtitest.nohint_func * kselftest-arm64/arm64.nobtitest.paciasp_func * kselftest-bpf * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-drivers * kselftest-efivarfs * kselftest-filesystems * kselftest-firmware * kselftest-fpu * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-ir * kselftest-kcmp * kselftest-kexec * kselftest-kvm * kselftest-lib * kselftest-livepatch * kselftest-lkdtm * kselftest-membarrier * kselftest-memfd * kselftest-memory-hotplug * kselftest-mincore * kselftest-mount * kselftest-mqueue * kselftest-net * kselftest-netfilter * kselftest-nsfs * kselftest-openat2 * kselftest-pid_namespace * kselftest-pidfd * kselftest-proc * kselftest-pstore * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-seccomp * kselftest-sigaltstack * kselftest-size * kselftest-splice * kselftest-static_keys * kselftest-sync * kselftest-sysctl * kselftest-tc-testing * kselftest-timens * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user * kselftest-vm * kselftest-x86 * kselftest-zram * kunit * kvm-unit-tests * libgpiod * libhugetlbfs * linux-log-parser * ltp-cap_bounds-tests * ltp-commands-tests * ltp-containers-tests * ltp-controllers-tests * ltp-cpuhotplug-tests * ltp-crypto-tests * ltp-cve-tests * ltp-dio-tests * ltp-fcntl-locktests-tests * ltp-filecaps-tests * ltp-fs-tests * ltp-fs_bind-tests * ltp-fs_perms_simple-tests * ltp-fsx-tests * ltp-hugetlb-tests * ltp-io-tests * ltp-ipc-tests * ltp-math-tests * ltp-mm-tests * ltp-nptl-tests * ltp-open-posix-tests * ltp-pty-tests * ltp-sched-tests * ltp-securebits-tests * ltp-syscalls-tests * ltp-tracing-tests * network-basic-tests * packetdrill * perf * perf/Zstd-perf.data-compression * rcutorture * ssuite * v4l2-compliance
-- Linaro LKFT https://lkft.linaro.org
On Wed, Nov 24, 2021 at 12:54:47PM +0100, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.5 release. There are 279 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 Fri, 26 Nov 2021 11:56:36 +0000. Anything received after that time might be too late.
Hi Greg,
Looking good.
Run tested on: - Intel Tiger Lake x86_64 (nuc11 i7-1165G7)
In addition build tested on: - Allwinner A64 - Allwinner H3 - Allwinner H5 - Allwinner H6 - NXP iMX6 - NXP iMX8 - Qualcomm Dragonboard - Rockchip RK3288 - Rockchip RK3328 - Rockchip RK3399pro - Samsung Exynos
Tested-by: Rudi Heitbaum rudi@heitbaum.com
On 24/11/2021 11:54, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.5 release. There are 279 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 Fri, 26 Nov 2021 11:56:36 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.5-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.15.y and the diffstat can be found below.
thanks,
greg k-h
No new regressions.
Test results for stable-v5.15: 10 builds: 10 pass, 0 fail 28 boots: 28 pass, 0 fail 114 tests: 108 pass, 6 fail
Linux version: 5.15.5-rc1-ge3bb2e602026 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Test failures: tegra194-p2972-0000: boot.py tegra194-p2972-0000: tegra-audio-boot-sanity.sh tegra194-p2972-0000: tegra-audio-hda-playback.sh tegra194-p3509-0000+p3668-0000: devices tegra194-p3509-0000+p3668-0000: tegra-audio-boot-sanity.sh tegra194-p3509-0000+p3668-0000: tegra-audio-hda-playback.sh
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
linux-stable-mirror@lists.linaro.org