This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.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.3-rc1
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Look at firmware version to determine using dmub on dcn21
Trond Myklebust trond.myklebust@hammerspace.com SUNRPC: Partial revert of commit 6f9f17287e78
Pali Rohár pali@kernel.org PCI: aardvark: Fix PCIe Max Payload Size setting
Pali Rohár pali@kernel.org PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros
Jernej Skrabec jernej.skrabec@gmail.com drm/sun4i: Fix macros in sun8i_csc.h
Xiaoming Ni nixiaoming@huawei.com powerpc/85xx: fix timebase sync issue when CONFIG_HOTPLUG_CPU=n
Nathan Lynch nathanl@linux.ibm.com powerpc/pseries/mobility: ignore ibm, platform-facilities updates
Nicholas Piggin npiggin@gmail.com powerpc/64s/interrupt: Fix check_return_regs_valid() false positive
Russell Currey ruscur@russell.cc powerpc/security: Use a mutex for interrupt exit code patching
Vasant Hegde hegdevasant@linux.vnet.ibm.com powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload
Nicholas Piggin npiggin@gmail.com powerpc/32e: Ignore ESR in instruction storage interrupt handler
Hari Bathini hbathini@linux.ibm.com powerpc/bpf: Fix write protecting JIT code
Gustavo A. R. Silva gustavoars@kernel.org powerpc/vas: Fix potential NULL pointer dereference
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: plat_nand: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: orion: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: pasemi: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: gpio: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: mpc5121: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: xway: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: ams-delta: Keep the driver compatible with on-die ECC engines
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: fsmc: Fix use of SM ORDER
Dong Aisheng aisheng.dong@nxp.com remoteproc: imx_rproc: Fix rsc-table name
Dong Aisheng aisheng.dong@nxp.com remoteproc: imx_rproc: Fix ignoring mapping vdev regions
Dong Aisheng aisheng.dong@nxp.com remoteproc: Fix the wrong default value of is_iomem
Peng Fan peng.fan@nxp.com remoteproc: elf_loader: Fix loading segment when is_iomem true
Halil Pasic pasic@linux.ibm.com s390/cio: make ccw_device_dma_* more robust
Harald Freudenberger freude@linux.ibm.com s390/ap: Fix hanging ioctl caused by orphaned replies
Sven Schnelle svens@linux.ibm.com s390/tape: fix timer initialization in tape_std_assign()
Vineeth Vijayan vneethv@linux.ibm.com s390/cio: check the subchannel validity for dev_busid
Thomas Richter tmricht@linux.ibm.com s390/cpumf: cpum_cf PMU displays invalid value after hotplug remove
Rafael J. Wysocki rafael.j.wysocki@intel.com PM: sleep: Avoid calling put_device() under dpm_list_mtx
Coly Li colyli@suse.de bcache: Revert "bcache: use bvec_virt"
Coly Li colyli@suse.de bcache: fix use-after-free problem in bcache_device_free()
Marek Vasut marex@denx.de video: backlight: Drop maximum brightness override for brightness zero
Jack Andersen jackoalan@gmail.com mfd: dln2: Add cell for initializing DLN2 ADC
Rongwei Wang rongwei.wang@linux.alibaba.com mm, thp: fix incorrect unmap behavior for private pages
Rongwei Wang rongwei.wang@linux.alibaba.com mm, thp: lock filemap when truncating page cache
Michal Hocko mhocko@suse.com mm, oom: do not trigger out_of_memory from the #PF
Vasily Averin vvs@virtuozzo.com mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks
Vasily Averin vvs@virtuozzo.com memcg: prohibit unconditional exceeding the limit of dying tasks
Matthew Wilcox (Oracle) willy@infradead.org mm/filemap.c: remove bogus VM_BUG_ON
Dominique Martinet asmadeus@codewreck.org 9p/net: fix missing error check in p9_check_errors
Daniel Borkmann daniel@iogearbox.net net, neigh: Enable state migration between NUD_PERMANENT and NTF_USE
Anatolij Gustschin agust@denx.de dmaengine: bestcomm: fix system boot lockups
Kishon Vijay Abraham I kishon@ti.com dmaengine: ti: k3-udma: Set r/tchan or rflow to NULL if request fail
Kishon Vijay Abraham I kishon@ti.com dmaengine: ti: k3-udma: Set bchan to NULL if a channel request fail
Namjae Jeon linkinjeon@kernel.org ksmbd: don't need 8byte alignment for request length in ksmbd_check_message
Marios Makassikis mmakassikis@freebox.fr ksmbd: Fix buffer length check in fsctl_validate_negotiate_info()
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com block: Hold invalidate_lock in BLKRESETZONE ioctl
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com block: Hold invalidate_lock in BLKZEROOUT ioctl
Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com block: Hold invalidate_lock in BLKDISCARD ioctl
Matthew Brost matthew.brost@intel.com drm/i915/guc: Fix blocked context accounting
Gao Xiang hsiangkao@linux.alibaba.com erofs: fix unsafe pagevec reuse of hooked pclusters
Xiubo Li xiubli@redhat.com ceph: fix mdsmap decode when there are MDS's beyond max_mds
Dongliang Mu mudongliangabcd@gmail.com f2fs: fix UAF in f2fs_available_free_memory
Daeho Jeong daehojeong@google.com f2fs: include non-compressed blocks in compr_written_block
Jaegeuk Kim jaegeuk@kernel.org f2fs: should use GFP_NOFS for directory inodes
Guo Ren guoren@linux.alibaba.com irqchip/sifive-plic: Fixup EOI failed when masked
Michael Pratt mpratt@google.com posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()
Paolo Bonzini pbonzini@redhat.com KVM: x86: move guest_pv_has out of user_access section
Thomas Gleixner tglx@linutronix.de PCI/MSI: Destroy sysfs before freeing entries
Thomas Gleixner tglx@linutronix.de PCI/MSI: Move non-mask check back into low level accessors
Dave Jones davej@codemonkey.org.uk x86/mce: Add errata workaround for Skylake SKX37
Maciej W. Rozycki macro@orcam.me.uk MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL
Masahiro Yamada masahiroy@kernel.org MIPS: fix *-pkg builds for loongson2ef platform
Masahiro Yamada masahiroy@kernel.org MIPS: fix duplicated slashes for Platform file path
John David Anglin dave.anglin@bell.net parisc: Flush kernel data mapping in set_pte_at() when installing pte for user page
Helge Deller deller@gmx.de parisc: Fix backtrace to always include init funtion names
Arnd Bergmann arnd@arndb.de ARM: 9156/1: drop cc-option fallbacks for architecture selection
Michał Mirosław mirq-linux@rere.qmqm.pl ARM: 9155/1: fix early early_iounmap()
Steve French stfrench@microsoft.com smb3: do not error on fsync when readonly
Linus Torvalds torvalds@linux-foundation.org thermal: int340x: fix build on 32-bit targets
Willem de Bruijn willemb@google.com selftests/net: udpgso_bench_rx: fix port argument
Rahul Lakkireddy rahul.lakkireddy@chelsio.com cxgb4: fix eeprom len when diagnostics not implemented
Dust Li dust.li@linux.alibaba.com net/smc: fix sk_refcnt underflow on linkdown and fallback
Eiichi Tsukata eiichi.tsukata@nutanix.com vsock: prevent unnecessary refcnt inc for nonblocking connect
Marek Behún kabel@kernel.org net: marvell: mvpp2: Fix wrong SerDes reconfiguration order
Christophe JAILLET christophe.jaillet@wanadoo.fr net: ethernet: ti: cpsw_ale: Fix access to un-initialized memory
Vladimir Oltean vladimir.oltean@nxp.com net: stmmac: allow a tc-taprio base-time of zero
Guangbin Huang huangguangbin2@huawei.com net: hns3: allow configure ETS bandwidth of all TCs
Yufeng Mo moyufeng@huawei.com net: hns3: fix kernel crash when unload VF while it is being reset
Jie Wang wangjie125@huawei.com net: hns3: fix pfc packet number incorrect after querying pfc parameters
Jie Wang wangjie125@huawei.com net: hns3: fix ROCE base interrupt vector initialization bug
Eric Dumazet edumazet@google.com net/sched: sch_taprio: fix undefined behavior in ktime_mono_to_any
Marek Behún kabel@kernel.org net: dsa: mv88e6xxx: Don't support >1G speeds on 6191X on ports other than 10
Evan Quan evan.quan@amd.com drm/amdgpu: fix uvd crash on Polaris12 during driver unloading
Muchun Song songmuchun@bytedance.com seq_file: fix passing wrong private data
Andrew Halaney ahalaney@redhat.com init: make unknown command line param message clearer
Imre Deak imre.deak@intel.com drm/i915/fb: Fix rounding error in subsampled plane size calculation
Dan Carpenter dan.carpenter@oracle.com gve: Fix off by one in gve_tx_timeout()
Arnd Bergmann arnd@arndb.de dmaengine: stm32-dma: avoid 64-bit division in stm32_dma_get_max_width
Amelie Delaunay amelie.delaunay@foss.st.com dmaengine: stm32-dma: fix burst in case of unaligned memory address
Jussi Maki joamaki@gmail.com bpf, sockmap: sk_skb data_end access incorrect when src_reg = dst_reg
John Fastabend john.fastabend@gmail.com bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding
John Fastabend john.fastabend@gmail.com bpf, sockmap: Fix race in ingress receive verdict with redirect to self
John Fastabend john.fastabend@gmail.com bpf, sockmap: Remove unhash handler for BPF sockmap usage
Arnd Bergmann arnd@arndb.de arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
Reiji Watanabe reijiw@google.com arm64: arm64_ftr_reg->name may not be a human-readable string
Christophe JAILLET christophe.jaillet@wanadoo.fr litex_liteeth: Fix a double free in the remove function
Chengfeng Ye cyeaa@connect.ust.hk nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails
Eric Dumazet edumazet@google.com llc: fix out-of-bound array index in llc_sk_dev_hash()
Ian Rogers irogers@google.com perf bpf: Add missing free to bpf_event__print_bpf_prog_info()
Dan Carpenter dan.carpenter@oracle.com zram: off by one in read_block_state()
Miaohe Lin linmiaohe@huawei.com mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and zs_unregister_migration()
Marc Kleine-Budde mkl@pengutronix.de can: mcp251xfd: mcp251xfd_chip_start(): fix error handling for mcp251xfd_chip_rx_int_enable()
Vincent Mailhol mailhol.vincent@wanadoo.fr can: etas_es58x: es58x_rx_err_msg(): fix memory leak in error path
Alex Deucher alexander.deucher@amd.com drm/amdgpu/powerplay: fix sysfs_emit/sysfs_emit_at handling
Fabio Estevam festevam@gmail.com Revert "drm/imx: Annotate dma-fence critical section in commit path"
Arnd Bergmann arnd@arndb.de drm: fb_helper: improve CONFIG_FB dependency
Hangbin Liu liuhangbin@gmail.com selftests/bpf/xdp_redirect_multi: Limit the tests in netns
Hangbin Liu liuhangbin@gmail.com selftests/bpf/xdp_redirect_multi: Give tcpdump a chance to terminate cleanly
Hangbin Liu liuhangbin@gmail.com selftests/bpf/xdp_redirect_multi: Use arping to accurate the arp number
Hangbin Liu liuhangbin@gmail.com selftests/bpf/xdp_redirect_multi: Put the logs to tmp folder
Mehrdad Arshad Rad arshad.rad@gmail.com libbpf: Fix lookup_and_delete_elem_flags error reporting
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPI: PM: Fix device wakeup power reference counting error
Kai Song songkai01@inspur.com mfd: altera-sysmgr: Fix a mistake caused by resource_size conversion
Mark Brown broonie@kernel.org mfd: sprd: Add SPI device ID table
Mark Brown broonie@kernel.org mfd: cpcap: Add SPI device ID table
Krzysztof Kozlowski krzysztof.kozlowski@canonical.com mfd: core: Add missing of_node_put for loop iteration
Takashi Iwai tiwai@suse.de ALSA: memalloc: Catch call with NULL snd_dma_buffer pointer
Arnd Bergmann arnd@arndb.de octeontx2-pf: select CONFIG_NET_DEVLINK
Huang Guobin huangguobin4@huawei.com bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed
Jason Gunthorpe jgg@ziepe.ca drm/ttm: remove ttm_bo_vm_insert_huge()
Luis Chamberlain mcgrof@kernel.org block: fix device_add_disk() kobject_create_and_add() error handling
Heiner Kallweit hkallweit1@gmail.com net: phy: fix duplex out of sync problem while changing settings
Rafael J. Wysocki rafael.j.wysocki@intel.com cpufreq: intel_pstate: Clear HWP desired on suspend/shutdown and offline
Selvin Xavier selvin.xavier@broadcom.com PCI: Do not enable AtomicOps on VFs
Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp ataflop: remove ataflop_probe_lock mutex
Luis Chamberlain mcgrof@kernel.org block/ataflop: provide a helper for cleanup up an atari disk
Luis Chamberlain mcgrof@kernel.org block/ataflop: add registration bool before calling del_gendisk()
Luis Chamberlain mcgrof@kernel.org block/ataflop: use the blk_cleanup_disk() helper
Luis Chamberlain mcgrof@kernel.org nvdimm/pmem: cleanup the disk if pmem_release_disk() is yet assigned
Chenyuan Mi cymi20@fudan.edu.cn drm/nouveau/svm: Fix refcount leak bug and missing check against null bug
Andrea Righi andrea.righi@canonical.com selftests: net: properly support IPv6 in GSO GRE test
Avri Altman avri.altman@wdc.com scsi: ufs: ufshpb: Properly handle max-single-cmd
Bean Huo beanhuo@micron.com scsi: ufs: core: Fix NULL pointer dereference
Daejun Park daejun7.park@samsung.com scsi: ufs: ufshpb: Use proper power management API
Jackie Liu liuyun01@kylinos.cn scsi: bsg: Fix errno when scsi_bsg_register_queue() fails
Luis Chamberlain mcgrof@kernel.org nvdimm/btt: do not call del_gendisk() if not needed
Christophe JAILLET christophe.jaillet@wanadoo.fr PCI: j721e: Fix j721e_pcie_probe() error path
Hans de Goede hdegoede@redhat.com ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses
Daniel Thompson daniel.thompson@linaro.org kdb: Adopt scheduler's task classification
Brett Creeley brett.creeley@intel.com ice: Fix not stopping Tx queues for VFs
Sylwester Dziedziuch sylwesterx.dziedziuch@intel.com ice: Fix replacing VF hardware MAC to existing MAC filter
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge
Ziyang Xuan william.xuanziyang@huawei.com net: vlan: fix a UAF in vlan_dev_real_dev()
Stafford Horne shorne@gmail.com openrisc: fix SMP tlb flush NULL pointer dereference
Jakub Kicinski kuba@kernel.org ethtool: fix ethtool msg len calculation for pause stats
Hangbin Liu liuhangbin@gmail.com kselftests/net: add missed toeplitz.sh/toeplitz_client.sh to Makefile
Hangbin Liu liuhangbin@gmail.com kselftests/net: add missed vrf_strict_mode_test.sh test to Makefile
Hangbin Liu liuhangbin@gmail.com kselftests/net: add missed SRv6 tests
Hangbin Liu liuhangbin@gmail.com kselftests/net: add missed setup_loopback.sh/setup_veth.sh to Makefile
Hangbin Liu liuhangbin@gmail.com kselftests/net: add missed icmp.sh test to Makefile
Maxim Kiselev bigunclemax@gmail.com net: davinci_emac: Fix interrupt pacing disable
Beld Zhang beldzhang@gmail.com io-wq: fix max-workers not correctly set on multi-node system
Yu Kuai yukuai3@huawei.com nbd: fix possible overflow for 'first_minor' in nbd_dev_add()
Yu Kuai yukuai3@huawei.com nbd: fix max value for 'first_minor'
YueHaibing yuehaibing@huawei.com xen-pciback: Fix return in pm_ctrl_init()
Sander Vanheule sander@svanheule.net gpio: realtek-otto: fix GPIO line IRQ offset
Christophe JAILLET christophe.jaillet@wanadoo.fr i2c: xlr: Fix a resource leak in the error handling path of 'xlr_i2c_probe()'
Dave Jiang dave.jiang@intel.com dmaengine: idxd: fix resource leak on dmaengine driver disable
Trond Myklebust trond.myklebust@hammerspace.com NFSv4: Fix a regression in nfs_set_open_stateid_locked()
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix EDIF bsg
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Increase ELS payload
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Flush stale events and msgs on session down
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix app start delay
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Fix app start fail
Quinn Tran qutran@marvell.com scsi: qla2xxx: Turn off target reset during issue_lip
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix gnl list corruption
Quinn Tran qutran@marvell.com scsi: qla2xxx: Relogin during fabric disturbance
Dmitry Bogdanov d.bogdanov@yadro.com scsi: target: core: Remove from tmr_list during LUN unlink
Jackie Liu liuyun01@kylinos.cn ar7: fix kernel builds for compiler test
Ahmad Fatoum a.fatoum@pengutronix.de watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT
Randy Dunlap rdunlap@infradead.org m68k: set a default value for MEMORY_RESERVE
Eric W. Biederman ebiederm@xmission.com signal/sh: Use force_sig(SIGKILL) instead of do_group_exit(SIGKILL)
Dave Jiang dave.jiang@intel.com dmaengine: idxd: reconfig device after device reset command
Dave Jiang dave.jiang@intel.com dmanegine: idxd: fix resource free ordering on driver removal
Dongliang Mu mudongliangabcd@gmail.com dmaengine: tegra210-adma: fix pm runtime unbalance
Lars-Peter Clausen lars@metafoo.de dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result`
Florian Westphal fw@strlen.de netfilter: nfnetlink_queue: fix OOB when mac header was cleared
Robert-Ionut Alexa robert-ionut.alexa@nxp.com soc: fsl: dpaa2-console: free buffer before returning from dpaa2_console_read
Geert Uytterhoeven geert@linux-m68k.org auxdisplay: ht16k33: Fix frame buffer device blanking
Geert Uytterhoeven geert@linux-m68k.org auxdisplay: ht16k33: Connect backlight to fbdev
Geert Uytterhoeven geert@linux-m68k.org auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string
Alexey Gladkov legion@kernel.org Fix user namespace leak
Trond Myklebust trond.myklebust@hammerspace.com NFS: Fix an Oops in pnfs_mark_request_commit()
Trond Myklebust trond.myklebust@hammerspace.com NFS: Fix up commit deadlocks
Amelie Delaunay amelie.delaunay@foss.st.com dmaengine: stm32-dma: fix stm32_dma_get_max_width
Claudiu Beznea claudiu.beznea@microchip.com dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro
Claudiu Beznea claudiu.beznea@microchip.com dmaengine: at_xdmac: call at_xdmac_axi_config() on resume path
Dan Carpenter dan.carpenter@oracle.com rtc: rv3032: fix error handling in rv3032_clkout_set_rate()
Christophe JAILLET christophe.jaillet@wanadoo.fr remoteproc: Fix a memory leak in an error handling path in 'rproc_handle_vdev()'
Zev Weiss zev@bewilderbeest.net mtd: core: don't remove debugfs directory if device is in use
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: arasan: Prevent an unsupported configuration
Kunihiko Hayashi hayashi.kunihiko@socionext.com PCI: uniphier: Serialize INTx masking/unmasking and fix the bit operation
Evgeny Novikov novikov@ispras.ru mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare()
Guido Günther agx@sigxcpu.org drm/bridge: nwl-dsi: Add atomic_get_input_bus_fmts
John Keeping john@metanate.com Input: st1232 - increase "wait ready" timeout
Jia-Ju Bai baijiaju1990@gmail.com fs: orangefs: fix error return code of orangefs_revalidate_lookup()
Kees Cook keescook@chromium.org sparc: Add missing "FORCE" target when using if_changed
Trond Myklebust trond.myklebust@hammerspace.com NFS: Fix deadlocks in nfs_scan_commit_list()
YueHaibing yuehaibing@huawei.com opp: Fix return in _opp_add_static_v2()
Pali Rohár pali@kernel.org PCI: aardvark: Fix preserving PCI_EXP_RTCTL_CRSSVE flag on emulated bridge
Marek Behún kabel@kernel.org PCI: aardvark: Don't spam about PIO Response Status
Alex Xu (Hello71) alex_y_xu@yahoo.ca drm/plane-helper: fix uninitialized variable reference
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/bridge/lontium-lt9611uxc: fix provided connector suport
Baptiste Lepers baptiste.lepers@gmail.com pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds
Trond Myklebust trond.myklebust@hammerspace.com NFS: Fix dentry verifier races
Trond Myklebust trond.myklebust@hammerspace.com NFS: Ignore the directory size when marking for revalidation
Trond Myklebust trond.myklebust@hammerspace.com NFS: Don't set NFS_INO_DATA_INVAL_DEFER and NFS_INO_INVALID_DATA
Trond Myklebust trond.myklebust@hammerspace.com NFS: Default change_attr_type to NFS4_CHANGE_TYPE_IS_UNDEFINED
Kewei Xu kewei.xu@mediatek.com i2c: mediatek: fixing the incorrect register offset
Mark Brown broonie@kernel.org Input: ariel-pwrbutton - add SPI device ID table
Mark Brown broonie@kernel.org rtc: mcp795: Add SPI ID table
Dave Jiang dave.jiang@intel.com dmaengine: idxd: move out percpu_ref_exit() to ensure it's outside submission
Heiner Kallweit hkallweit1@gmail.com i2c: i801: Use PCI bus rescan mutex to protect P2SB access
Dong Aisheng aisheng.dong@nxp.com remoteproc: imx_rproc: Fix TCM io memory type
Mark Brown broonie@kernel.org rtc: pcf2123: Add SPI ID table
Mark Brown broonie@kernel.org rtc: ds1390: Add SPI ID table
Mark Brown broonie@kernel.org rtc: ds1302: Add SPI ID table
J. Bruce Fields bfields@redhat.com nfsd: don't alloc under spinlock in rpc_parse_scope_id
Evgeny Novikov novikov@ispras.ru mtd: rawnand: intel: Fix potential buffer overflow in probe
Arnaud Pouliquen arnaud.pouliquen@foss.st.com rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined
Tom Rix trix@redhat.com apparmor: fix error check
Aharon Landau aharonl@nvidia.com RDMA/core: Require the driver to set the IOVA correctly during rereg_mr
Hans de Goede hdegoede@redhat.com power: supply: bq27xxx: Fix kernel crash on IRQ handler register error
Geert Uytterhoeven geert+renesas@glider.be mips: cm: Convert to bitfield API to fix out-of-bounds access
Parav Pandit parav@nvidia.com vdpa/mlx5: Fix clearing of VIRTIO_NET_F_MAC feature bit
Xuan Zhuo xuanzhuo@linux.alibaba.com virtio_ring: check desc == NULL when using indirect with packed
Geert Uytterhoeven geert@linux-m68k.org serial: cpm_uart: Protect udbg definitions by CONFIG_SERIAL_CPM_CONSOLE
Christophe JAILLET christophe.jaillet@wanadoo.fr ASoC: rsnd: Fix an error handling path in 'rsnd_node_count()'
Yixing Liu liuyixing1@huawei.com RDMA/hns: Modify the value of MAX_LP_MSG_LEN to meet hardware compatibility
Haoyue Xu xuhaoyue1@hisilicon.com RDMA/hns: Fix initial arm_st of CQ
Richard Fitzgerald rf@opensource.cirrus.com ASoC: cs42l42: Correct configuring of switch inversion from ts-inv
Christophe Leroy christophe.leroy@csgroup.eu powerpc: Don't provide __kernel_map_pages() without ARCH_SUPPORTS_DEBUG_PAGEALLOC
Logan Gunthorpe logang@deltatee.com iommu/dma: Fix incorrect error return on iommu deferred attach
Takashi Sakamoto o-takashi@sakamocchi.jp ALSA: oxfw: fix functional regression for Mackie Onyx 1640i in v5.14 or later
Denis Kirjanov kda@linux-powerpc.org powerpc/xmon: fix task state output
Bixuan Cui cuibixuan@linux.alibaba.com powerpc/44x/fsp2: add missing of_node_put
Christophe Leroy christophe.leroy@csgroup.eu powerpc/book3e: Fix set_memory_x() and set_memory_nx()
Christophe Leroy christophe.leroy@csgroup.eu powerpc/nohash: Fix __ptep_set_access_flags() and ptep_set_wrprotect()
Andrej Shadura andrew.shadura@collabora.co.uk HID: u2fzero: properly handle timeouts in usb_submit_urb
Andrej Shadura andrew.shadura@collabora.co.uk HID: u2fzero: clarify error check and length calculations
Claudiu Beznea claudiu.beznea@microchip.com clk: at91: clk-master: fix prescaler logic
Claudiu Beznea claudiu.beznea@microchip.com clk: at91: clk-master: check if div or pres is zero
Claudiu Beznea claudiu.beznea@microchip.com clk: at91: sam9x60-pll: use DIV_ROUND_CLOSEST_ULL
Anssi Hannula anssi.hannula@bitwise.fi serial: xilinx_uartps: Fix race condition causing stuck TX
Yang Yingliang yangyingliang@huawei.com phy: Sparx5 Eth SerDes: Fix return value check in sparx5_serdes_probe()
Sandeep Maheswaram quic_c_sanm@quicinc.com phy: qcom-snps: Correct the FSEL_MASK
Dmitry Baryshkov dmitry.baryshkov@linaro.org phy: qcom-qmp: another fix for the sc8180x PCIe definition
Dan Carpenter dan.carpenter@oracle.com phy: ti: gmii-sel: check of_get_address() for failure
Vladimir Zapolskiy vladimir.zapolskiy@linaro.org phy: qcom-qusb2: Fix a memory leak on probe
Mark Brown broonie@kernel.org ASoC: topology: Fix stub for snd_soc_tplg_component_remove()
Rahul Tanwar rtanwar@maxlinear.com pinctrl: equilibrium: Fix function addition in multiple groups
Vladimir Zapolskiy vladimir.zapolskiy@linaro.org arm64: dts: qcom: sdm845: Fix Qualcomm crypto engine bus clock
Bhupesh Sharma bhupesh.sharma@linaro.org arm64: dts: qcom: sdm845: Use RPMH_CE_CLK macro directly
Marijn Suijten marijn.suijten@somainline.org arm64: dts: qcom: pmi8994: Fix "eternal"->"external" typo in WLED node
Wan Jiabing wanjiabing@vivo.com soc: qcom: apr: Add of_node_put() before return
Dmitry Baryshkov dmitry.baryshkov@linaro.org soc: qcom: rpmhpd: fix sm8350_mxc's peer domain
Guru Das Srinagesh quic_gurus@quicinc.com firmware: qcom_scm: Fix error retval in __qcom_scm_is_call_available()
Jack Pham jackp@codeaurora.org usb: dwc3: gadget: Skip resizing EP's TX FIFO if already resized
Christophe Leroy christophe.leroy@csgroup.eu powerpc/booke: Disable STRICT_KERNEL_RWX, DEBUG_PAGEALLOC and KFENCE
Amelie Delaunay amelie.delaunay@foss.st.com usb: dwc2: drd: reset current session before setting the new one
Amelie Delaunay amelie.delaunay@foss.st.com usb: dwc2: drd: fix dwc2_drd_role_sw_set when clock could be disabled
Amelie Delaunay amelie.delaunay@foss.st.com usb: dwc2: drd: fix dwc2_force_mode call in dwc2_ovr_init
Stefan Agner stefan@agner.ch serial: imx: fix detach/attach of serial console
James Smart jsmart2021@gmail.com scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset
Srinivas Kandagatla srinivas.kandagatla@linaro.org scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer
Srinivas Kandagatla srinivas.kandagatla@linaro.org soundwire: bus: stop dereferencing invalid slave pointer
Nuno Sá nuno.sa@analog.com iio: adis: do not disabe IRQs in 'adis_init()'
Randy Dunlap rdunlap@infradead.org usb: typec: STUSB160X should select REGMAP_I2C
Yang Yingliang yangyingliang@huawei.com iio: buffer: Fix double-free in iio_buffers_alloc_sysfs_and_mask()
Dmitry Baryshkov dmitry.baryshkov@linaro.org soc: qcom: socinfo: add two missing PMIC IDs
Bjorn Andersson bjorn.andersson@linaro.org soc: qcom: rpmhpd: Make power_on actually enable the domain
Richard Fitzgerald rf@opensource.cirrus.com ASoC: cs42l42: Defer probe if request_threaded_irq() returns EPROBE_DEFER
Richard Fitzgerald rf@opensource.cirrus.com ASoC: cs42l42: Correct some register default values
Richard Fitzgerald rf@opensource.cirrus.com ASoC: cs42l42: Always configure both ASP TX channels
Olivier Moysan olivier.moysan@foss.st.com ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
Olivier Moysan olivier.moysan@foss.st.com ARM: dts: stm32: fix SAI sub nodes register range
Fabrice Gasnier fabrice.gasnier@foss.st.com ARM: dts: stm32: fix STUSB1600 Type-C irq level on stm32mp15xx-dkx
Marek Vasut marex@denx.de ARM: dts: stm32: Reduce DHCOR SPI NOR frequency to 50 MHz
Geert Uytterhoeven geert+renesas@glider.be pinctrl: renesas: checker: Fix off-by-one bug in drive register check
Athira Rajeev atrajeev@linux.vnet.ibm.cm powerpc/perf: Fix cycles/instructions as PM_CYC/PM_INST_CMPL in power10
Andrew Halaney ahalaney@redhat.com dyndbg: make dyndbg a known cli param
Logan Gunthorpe logang@deltatee.com RDMA/core: Set sgtable nents when using ib_dma_virt_map_sg()
Vegard Nossum vegard.nossum@oracle.com staging: ks7010: select CRYPTO_HASH/CRYPTO_MICHAEL_MIC
Nikita Yushchenko nikita.yoush@cogentembedded.com staging: most: dim2: do not double-register the same device
Randy Dunlap rdunlap@infradead.org usb: musb: select GENERIC_PHY instead of depending on it
Leon Romanovsky leon@kernel.org RDMA/mlx4: Return missed an error if device doesn't support steering
Dan Carpenter dan.carpenter@oracle.com scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn()
Yang Yingliang yangyingliang@huawei.com power: supply: max17040: fix null-ptr-deref in max17040_probe()
Jakob Hauser jahau@rocketmail.com power: supply: rt5033_battery: Change voltage values to µV
Dan Carpenter dan.carpenter@oracle.com usb: gadget: hid: fix error code in do_config()
Andy Shevchenko andriy.shevchenko@linux.intel.com serial: 8250_dw: Drop wrong use of ACPI_PTR()
Nathan Lynch nathanl@linux.ibm.com powerpc/paravirt: correct preempt debug splat in vcpu_is_preempted()
Nathan Lynch nathanl@linux.ibm.com powerpc: fix unbalanced node refcount in check_kvm_guest()
Christophe Leroy christophe.leroy@csgroup.eu video: fbdev: chipsfb: use memset_io() instead of memset()
Christophe Leroy christophe.leroy@csgroup.eu powerpc/mem: Fix arch/powerpc/mm/mem.c:53:12: error: no previous prototype for 'create_section_mapping'
Clément Léger clement.leger@bootlin.com clk: at91: check pmc node status before registering syscore ops
Dongliang Mu mudongliangabcd@gmail.com memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe
Christophe JAILLET christophe.jaillet@wanadoo.fr soc/tegra: Fix an error handling path in tegra_powergate_power_up()
Mark Brown broonie@kernel.org iio: st_pressure_spi: Add missing entries SPI to device ID table
Ranjani Sridharan ranjani.sridharan@linux.intel.com ASoC: SOF: topology: do not power down primary core during topology removal
Andreas Kemnade andreas@kemnade.info arm: dts: omap3-gta04a4: accelerometer irq fix
Yang Yingliang yangyingliang@huawei.com driver core: Fix possible memory leak in device_link_add()
Igor Pylypiv ipylypiv@google.com scsi: pm80xx: Fix misleading log statement in pm8001_mpi_get_nvmd_resp()
Sumit Saxena sumit.saxena@broadcom.com scsi: megaraid_sas: Fix concurrent access to ISR between IRQ polling and real interrupt
Bart Van Assche bvanassche@google.com scsi: ufs: core: Stop clearing UNIT ATTENTIONS
Bean Huo beanhuo@micron.com scsi: ufs: core: Fix ufshcd_probe_hba() prototype to match the definition
Claudiu Beznea claudiu.beznea@microchip.com power: reset: at91-reset: check properly the return value of devm_of_iomap
Srinivas Kandagatla srinivas.kandagatla@linaro.org soundwire: debugfs: use controller id and link_id for debugfs
Takashi Iwai tiwai@suse.de ALSA: usb-audio: Fix possible race at sync of urb completions
Takashi Iwai tiwai@suse.de ALSA: hda: Use position buffer for SKL+ again
Takashi Iwai tiwai@suse.de ALSA: hda: Reduce udelay() at SKL+ position reporting
David Stevens stevensd@chromium.org iommu/dma: Fix arch_sync_dma for map
David Stevens stevensd@chromium.org iommu/dma: Fix sync_sg with swiotlb
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: pm8916: Remove wrong reg-names for rtc@6000
Arnd Bergmann arnd@arndb.de iommu/mediatek: Fix out-of-range warning with clang
Geert Uytterhoeven geert+renesas@glider.be arm64: dts: renesas: beacon: Fix Ethernet PHY mode
Stephan Gerhold stephan@gerhold.net arm64: dts: qcom: msm8916: Fix Secondary MI2S bit clock
Yassine Oudjana y.oudjana@protonmail.com ASoC: wcd9335: Use correct version to initialize Class H
Biju Das biju.das.jz@bp.renesas.com pinctrl: renesas: rzg2l: Fix missing port register 21h
Dongliang Mu mudongliangabcd@gmail.com JFS: fix memleak in jfs_mount
Jackie Liu liuyun01@kylinos.cn MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT
Tong Zhang ztong0001@gmail.com scsi: dc395: Fix error case unwinding
Kuogee Hsieh khsieh@codeaurora.org arm64: dts: qcom: sc7280: fix display port phy reg property
Naina Mehta nainmeht@codeaurora.org soc: qcom: llcc: Disable MMUHWT retention
Douglas Anderson dianders@chromium.org arm64: dts: qcom: sc7180: Base dynamic CPU power coefficients in reality
Peter Rosin peda@axentia.se ARM: dts: at91: tse850: the emac<->phy interface is rmii
Tony Lindgren tony@atomide.com bus: ti-sysc: Fix timekeeping_suspended warning on resume
Anand Moon linux.amoon@gmail.com arm64: dts: meson-sm1: Fix the pwm regulator supply properties
Anand Moon linux.amoon@gmail.com arm64: dts: meson-g12b: Fix the pwm regulator supply properties
Anand Moon linux.amoon@gmail.com arm64: dts: meson-g12a: Fix the pwm regulator supply properties
Kishon Vijay Abraham I kishon@ti.com arm64: dts: ti: j7200-main: Fix "bus-range" upto 256 bus number for PCIe
Kishon Vijay Abraham I kishon@ti.com arm64: dts: ti: j7200-main: Fix "vendor-id"/"device-id" properties of pcie node
Kishon Vijay Abraham I kishon@ti.com arm64: dts: ti: k3-j721e-main: Fix "bus-range" upto 256 bus number for PCIe
Kishon Vijay Abraham I kishon@ti.com arm64: dts: ti: k3-j721e-main: Fix "max-virtual-functions" in PCIe EP nodes
Selvin Xavier selvin.xavier@broadcom.com RDMA/bnxt_re: Fix query SRQ failure
Marijn Suijten marijn.suijten@somainline.org ARM: dts: qcom: msm8974: Add xo_board reference clock to DSI0 PHY
Alex Bee knaerzche@gmail.com arm64: dts: rockchip: Fix GPU register width for RK3328
Jackie Liu liuyun01@kylinos.cn ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc()
James Smart jsmart2021@gmail.com scsi: lpfc: Fix NVMe I/O failover to non-optimized path
Quinn Tran qutran@marvell.com scsi: qla2xxx: edif: Use link event to wake up app
Ajish Koshy Ajish.Koshy@microchip.com scsi: pm80xx: Fix lockup in outbound queue management
Christophe JAILLET christophe.jaillet@wanadoo.fr clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths
Rafał Miłecki rafal@milecki.pl arm64: dts: broadcom: bcm4908: Fix UART clock name
Rafał Miłecki rafal@milecki.pl ARM: dts: BCM5301X: Fix memory nodes names
Junji Wei weijunji@bytedance.com RDMA/rxe: Fix wrong port_cap_flags
Alexandru Ardelean aardelean@deviqon.com iio: st_sensors: disable regulators after device unregistration
Dongjin Kim tobetter@gmail.com arm64: dts: meson: sm1: add Ethernet PHY reset line for ODROID-C4/HC4
Pavel Skripkin paskripkin@gmail.com staging: r8188eu: fix memory leak in rtw_set_key
Hector.Yuan hector.yuan@mediatek.com cpufreq: Fix parameter in parse_perf_domain()
Frank Rowand frank.rowand@sony.com of: unittest: fix EXPECT text for gpio hog errors
Alexei Starovoitov ast@kernel.org bpf: Fix propagation of signed bounds from 64-bit min/max into 32-bit.
Alexei Starovoitov ast@kernel.org bpf: Fix propagation of bounds from 64-bit min/max into 32-bit and var_off.
Dan Schatzberg schatzberg.dan@gmail.com cgroup: Fix rootcg cpu.stat guest double counting
Liu Jian liujian56@huawei.com skmsg: Lose offset info in sk_psock_skb_ingress
Geliang Tang geliang.tang@suse.com selftests: mptcp: fix proto type in link_failure tests
Sukadev Bhattiprolu sukadev@linux.ibm.com ibmvnic: delay complete()
Sukadev Bhattiprolu sukadev@linux.ibm.com ibmvnic: Process crqs after enabling interrupts
Sukadev Bhattiprolu sukadev@linux.ibm.com ibmvnic: don't stop queue in xmit
Jakub Kicinski kuba@kernel.org udp6: allow SO_MARK ctrl msg to affect routing
Andrea Righi andrea.righi@canonical.com selftests/bpf: Fix fclose/pclose mismatch in test_progs
Daniel Jordan daniel.m.jordan@oracle.com crypto: pcrypt - Delay write to padata->info
Nikolay Aleksandrov nikolay@nvidia.com selftests: net: bridge: update IGMP/MLD membership interval value
Ivan Vecera ivecera@redhat.com net: bridge: fix uninitialized variables when BRIDGE_CFM is disabled
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: phylink: avoid mvneta warning when setting pause parameters
Yinjun Zhang yinjun.zhang@corigine.com nfp: fix potential deadlock when canceling dim work
Yinjun Zhang yinjun.zhang@corigine.com nfp: fix NULL pointer access when scheduling dim work
Christophe JAILLET christophe.jaillet@wanadoo.fr ipmi: kcs_bmc: Fix a memory leak in the error handling path of 'kcs_bmc_serio_add_device()'
Shyam Sundar S K Shyam-sundar.S-k@amd.com net: amd-xgbe: Toggle PLL settings during rate change
Xin Long lucien.xin@gmail.com sctp: return true only for pathmtu update in sctp_transport_pl_toobig
Xin Long lucien.xin@gmail.com sctp: subtract sctphdr len in sctp_transport_pl_hlen
Xin Long lucien.xin@gmail.com sctp: reset probe_timer in sctp_transport_pl_update
Xin Long lucien.xin@gmail.com sctp: allow IP fragmentation when PLPMTUD enters Error state
Kumar Kartikeya Dwivedi memxor@gmail.com selftests/bpf: Fix memory leak in test_ima
Kumar Kartikeya Dwivedi memxor@gmail.com selftests/bpf: Fix fd cleanup in sk_lookup test
Alex Deucher alexander.deucher@amd.com drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits
Lang Yu lang.yu@amd.com drm/amdgpu: fix a potential memory leak in amdgpu_device_fini_sw()
Loic Poulain loic.poulain@linaro.org wcn36xx: Channel list update before hardware scan
Eric Dumazet edumazet@google.com bpf: Fixes possible race in update_prog_stats() for 32bit arches
Eric Dumazet edumazet@google.com bpf: Avoid races in __bpf_prog_run() for 32bit arches
Loic Poulain loic.poulain@linaro.org wcn36xx: Fix discarded frames due to wrong sequence number
Benjamin Li benl@squareup.com wcn36xx: add proper DMA memory barriers in rx path
Wang Hai wanghai38@huawei.com libertas: Fix possible memory leak in probe and disconnect
Wang Hai wanghai38@huawei.com libertas_tf: Fix possible memory leak in probe and disconnect
Janis Schoetterl-Glausch scgl@linux.ibm.com KVM: s390: Fix handle_sske page fault handling
Tiezhu Yang yangtiezhu@loongson.cn samples/kretprobes: Fix return value if register_kretprobe() failed
Peter Zijlstra peterz@infradead.org x86: Fix __get_wchan() for !STACKTRACE
Kees Cook keescook@chromium.org sched: Add wrapper for get_wchan() to keep task blocked
Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com spi: spi-rpc-if: Check return value of rpcif_sw_init()
Zhang Rui rui.zhang@intel.com cpufreq: intel_pstate: Fix cpu->pstate.turbo_freq initialization
Mathieu Desnoyers mathieu.desnoyers@efficios.com tracing: Fix missing trace_boot_init_histograms kstrdup NULL checks
Jon Maxwell jmaxwell37@gmail.com tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()
Ilya Leoshkevich iii@linux.ibm.com libbpf: Fix endianness detection in BPF_CORE_READ_BITFIELD_PROBED()
Mark Brown broonie@kernel.org tpm_tis_spi: Add missing SPI ID
Hao Wu hao.wu@rubrik.com tpm: fix Atmel TPM crash caused by too frequent queries
Andrii Nakryiko andrii@kernel.org libbpf: Fix off-by-one bug in bpf_core_apply_relo()
Yu Kuai yukuai3@huawei.com blk-cgroup: synchronize blkg creation against policy deactivation
Michael Schmitz schmitzmic@gmail.com block: ataflop: more blk-mq refactoring fixes
Abinaya Kalaiselvan akalaise@codeaurora.org ath10k: fix module load regression with iram-recovery feature
Arnd Bergmann arnd@arndb.de ARM: 9142/1: kasan: work around LPAE build warning
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: avoid refcount warnings when ->port_{fdb,mdb}_del returns error
Mark Rutland mark.rutland@arm.com irq: mips: avoid nested irq_enter()
Claudio Imbrenda imbrenda@linux.ibm.com KVM: s390: pv: avoid stalls for kvm_s390_pv_init_vm
Claudio Imbrenda imbrenda@linux.ibm.com KVM: s390: pv: avoid double free of sida page
David Hildenbrand david@redhat.com s390/uv: fully validate the VMA before calling follow_page()
David Hildenbrand david@redhat.com s390/mm: fix VMA and page table handling code in storage key handling functions
David Hildenbrand david@redhat.com s390/mm: validate VMA in PGSTE manipulation functions
David Hildenbrand david@redhat.com s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap()
David Hildenbrand david@redhat.com s390/gmap: validate VMA in __gmap_zap()
Nick Hainke vincent@systemli.org mt76: mt7615: mt7622: fix ibss and meshpoint
Andrii Nakryiko andrii@kernel.org libbpf: Fix BTF header parsing checks
Andrii Nakryiko andrii@kernel.org libbpf: Fix overflow in BTF sanity checks
Quentin Monnet quentin@isovalent.com bpftool: Avoid leaking the JSON writer prepared for program metadata
Mauricio Vásquez mauricio@kinvolk.io libbpf: Fix memory leak in btf__dedup()
Jim Mattson jmattson@google.com KVM: selftests: Fix nested SVM tests when built with clang
Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi
Horia Geantă horia.geanta@nxp.com crypto: tcrypt - fix skcipher multi-buffer tests for 1420B blocks
Jessica Zhang jesszhan@codeaurora.org drm/msm/dsi: fix wrong type in msm_dsi_host
Jessica Zhang jesszhan@codeaurora.org drm/msm: Fix potential NULL dereference in DPU SSPP
Joerg Roedel jroedel@suse.de x86/sev: Fix stack type check in vc_switch_off_ist()
Kees Cook keescook@chromium.org clocksource/drivers/timer-ti-dm: Select TIMER_OF
Anders Roxell anders.roxell@linaro.org PM: hibernate: fix sparse warnings
Max Gurtovoy mgurtovoy@nvidia.com nvme-rdma: fix error code in nvme_rdma_setup_ctrl
Ye Bin yebin10@huawei.com nbd: Fix use-after-free in pid_show
Stefan Agner stefan@agner.ch phy: micrel: ksz8041nl: do not use power down mode
Tim Gardner tim.gardner@canonical.com net: enetc: unmap DMA in enetc_send_cmd()
Johannes Berg johannes.berg@intel.com iwlwifi: pnvm: read EFI data only if long enough
Johannes Berg johannes.berg@intel.com iwlwifi: pnvm: don't kmemdup() more than we have
Johannes Berg johannes.berg@intel.com iwlwifi: mvm: reset PM state on unsuccessful resume
Jonas Dreßler verdre@v0yd.nl mwifiex: Send DELBA requests according to spec
Ziyang Xuan william.xuanziyang@huawei.com rsi: stop thread firstly in rsi_91x_init() error handling
Shayne Chen shayne.chen@mediatek.com mt76: mt7915: fix muar_idx in mt7915_mcu_alloc_sta_req()
Shayne Chen shayne.chen@mediatek.com mt76: mt7915: fix sta_rec_wtbl tag len
Lorenzo Bianconi lorenzo@kernel.org mt76: connac: fix possible NULL pointer dereference in mt76_connac_get_phy_mode_v2
Ryder Lee ryder.lee@mediatek.com mt76: mt7615: fix monitor mode tear down crash
Sean Wang sean.wang@mediatek.com mt76: mt7921: fix retrying release semaphore without end
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: fix possible infinite loop release semaphore
Ryder Lee ryder.lee@mediatek.com mt76: mt7615: fix hwmon temp sensor mem use-after-free
Ben Greear greearb@candelatech.com mt76: mt7915: fix hwmon temp sensor mem use-after-free
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: always wake device if necessary in debugfs
Sean Wang sean.wang@mediatek.com mt76: mt7921: fix kernel warning from cfg80211_calculate_bitrate
Sean Wang sean.wang@mediatek.com mt76: mt7921: fix firmware usage of RA info using legacy rates
Sean Wang sean.wang@mediatek.com mt76: mt7921: report HE MU radiotap
Lorenzo Bianconi lorenzo@kernel.org mt76: overwrite default reg_ops if necessary
Leon Yen Leon.Yen@mediatek.com mt76: connac: fix GTK rekey offload failure on WPA mixed mode
Deren Wu deren.wu@mediatek.com mt76: mt7921: fix dma hang in rmmod
Shayne Chen shayne.chen@mediatek.com mt76: mt7915: fix bit fields for HT rate idx
Shayne Chen shayne.chen@mediatek.com mt76: mt7915: fix potential overflow of eeprom page index
Deren Wu deren.wu@mediatek.com mt76: mt7921: Fix out of order process by invalid event pkt
Lorenzo Bianconi lorenzo@kernel.org mt76: mt76x02: fix endianness warnings in mt76x02_mac.c
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: fix survey-dump reporting
Sean Wang sean.wang@mediatek.com mt76: fix build error implicit enumeration conversion
Leon Yen Leon.Yen@mediatek.com mt76: connac: fix mt76_connac_gtk_rekey_tlv usage
Dan Carpenter dan.carpenter@oracle.com mt76: mt7915: fix info leak in mt7915_mcu_set_pre_cal()
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7615: fix endianness warning in mt7615_mac_write_txwi
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: fix endianness warning in mt7921_update_txs
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7915: fix endianness warning in mt7915_mac_add_txs_skb
Lorenzo Bianconi lorenzo@kernel.org mt76: mt7921: fix endianness in mt7921_mcu_tx_done_event
Lang Yu lang.yu@amd.com drm/amdkfd: Fix an inappropriate error handling in allloc memory of gpu
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPI: PM: Fix sharing of wakeup power resources
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPI: PM: Turn off unused wakeup power resources
Fei Shao fshao@chromium.org mailbox: mtk-cmdq: Fix local clock ID usage
Fei Shao fshao@chromium.org mailbox: mtk-cmdq: Validate alias_id on probe
Nathan Chancellor nathan@kernel.org platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning
Andrea Righi andrea.righi@canonical.com blk-wbt: prevent NULL pointer dereference in wb_timer_fn
Michael Schmitz schmitzmic@gmail.com block: ataflop: fix breakage introduced at blk-mq refactoring
Bixuan Cui cuibixuan@huawei.com io-wq: Remove duplicate code in io_workqueue_create()
Christophe JAILLET christophe.jaillet@wanadoo.fr mmc: mxs-mmc: disable regulator on error and in the remove function
Sean Young sean@mess.org media: ir_toy: assignment to be16 should be of correct type
Randy Dunlap rdunlap@infradead.org media: ivtv: fix build for UML
jason-jh.lin jason-jh.lin@mediatek.com mailbox: Remove WARN_ON for async_cb.cb in cmdq_exec_done
Jackie Liu liuyun01@kylinos.cn thermal/drivers/qcom/lmh: make QCOM_LMH depends on QCOM_SCM
Jakub Kicinski kuba@kernel.org net: stream: don't purge sk_error_queue in sk_stream_kill_queues()
Dan Carpenter dan.carpenter@oracle.com drm/msm: uninitialized variable in msm_gem_import()
Dan Carpenter dan.carpenter@oracle.com drm/msm: fix potential NULL dereference in cleanup
Dan Carpenter dan.carpenter@oracle.com drm/msm: unlock on error in get_sched_entity()
Dan Carpenter dan.carpenter@oracle.com drm/msm: potential error pointer dereference in init()
Dan Carpenter dan.carpenter@oracle.com drm/msm: Fix potential Oops in a6xx_gmu_rpmh_init()
Dmitry Baryshkov dmitry.baryshkov@linaro.org drm/msm/dsi: do not enable irq handler before powering up the host
Ziyang Xuan william.xuanziyang@huawei.com thermal/core: fix a UAF bug in __thermal_cooling_device_register()
Ovidiu Panait ovidiu.panait@windriver.com crypto: octeontx2 - set assoclen in aead_do_fallback()
Eric Dumazet edumazet@google.com tcp: switch orphan_count to bare per-cpu counters
Qi Zheng zhengqi.arch@bytedance.com x86: Fix get_wchan() to support the ORC unwinder
Randy Dunlap rdunlap@infradead.org net: tulip: winbond-840: fix build for UML
Randy Dunlap rdunlap@infradead.org net: intel: igc_ptp: fix build for UML
Randy Dunlap rdunlap@infradead.org net: fealnx: fix build for UML
Zhang Qiao zhangqiao22@huawei.com kernel/sched: Fix sched_fork() access an invalid sched_task_group
Sven Eckelmann seckelmann@datto.com ath10k: fix max antenna gain unit
Zev Weiss zev@bewilderbeest.net hwmon: (pmbus/lm25066) Let compiler determine outer dimension of lm25066_coeff
Yang Yingliang yangyingliang@huawei.com hwmon: Fix possible memleak in __hwmon_device_register()
Daniel Borkmann daniel@iogearbox.net net, neigh: Fix NTF_EXT_LEARNED in combination with NTF_USE
Dan Carpenter dan.carpenter@oracle.com memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host()
Arnd Bergmann arnd@arndb.de memstick: avoid out-of-range warning
Tony Lindgren tony@atomide.com mmc: sdhci-omap: Fix context restore
Tony Lindgren tony@atomide.com mmc: sdhci-omap: Fix NULL pointer exception if regulator is not configured
Catherine Sullivan csully@google.com gve: Track RX buffer allocation failures
John Fraker jfraker@google.com gve: Recover from queue stall due to missed IRQ
Dan Carpenter dan.carpenter@oracle.com b43: fix a lower bounds test
Dan Carpenter dan.carpenter@oracle.com b43legacy: fix a lower bounds test
liqiong liqiong@nfschina.com ima: fix deadlock when traversing "ima_default_rules".
Markus Schneider-Pargmann msp@baylibre.com hwrng: mtk - Force runtime pm ops for sleep ops
Giovanni Cabiddu giovanni.cabiddu@intel.com crypto: qat - disregard spurious PFVF interrupts
Giovanni Cabiddu giovanni.cabiddu@intel.com crypto: qat - detect PFVF collision after ACK
Arnd Bergmann arnd@arndb.de crypto: ccree - avoid out-of-range warnings from clang
Evgeny Novikov novikov@ispras.ru media: dvb-frontends: mn88443x: Handle errors of clk_prepare_enable()
Mansur Alisha Shaik mansur@codeaurora.org media: venus: fix vpp frequency calculation for decoder
Pablo Neira Ayuso pablo@netfilter.org netfilter: nft_dynset: relax superfluous check on set updates
Peter Zijlstra peterz@infradead.org rcu: Fix rcu_dynticks_curr_cpu_in_eqs() vs noinstr
Peter Zijlstra peterz@infradead.org rcu: Always inline rcu_dynticks_task*_{enter,exit}()
Yazen Ghannam yazen.ghannam@amd.com EDAC/amd64: Handle three rank interleaving mode
Borislav Petkov bp@suse.de x86/insn: Use get_unaligned() instead of memcpy()
Vincent Donnefort vincent.donnefort@arm.com PM: EM: Fix inefficient states detection
Linus Lüssing ll@simonwunderlich.de ath9k: Fix potential interrupt storm on queue reset
Stephen Boyd swboyd@chromium.org ath10k: Don't always treat modem stop events as crashes
Colin Ian King colin.king@canonical.com media: em28xx: Don't use ops->suspend if it is NULL
Anel Orazgaliyeva anelkz@amazon.de cpuidle: Fix kobject memory leaks in error paths
Arnd Bergmann arnd@arndb.de drm: fb_helper: fix CONFIG_FB dependency
Arnd Bergmann arnd@arndb.de crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency
Punit Agrawal punitagrawal@gmail.com kprobes: Do not use local variable when creating debugfs file
Yee Lee yee.lee@mediatek.com scs: Release kasan vmalloc poison in scs_free process
Eugen Hristev eugen.hristev@microchip.com media: atmel: fix the ispck initialization
Colin Ian King colin.king@canonical.com media: cx23885: Fix snd_card_free call on null card pointer
Kees Cook keescook@chromium.org media: tm6000: Avoid card name truncation
Kees Cook keescook@chromium.org media: si470x: Avoid card name truncation
Kees Cook keescook@chromium.org media: radio-wl1273: Avoid card name truncation
Ondrej Jirman megous@megous.com media: sun6i-csi: Allow the video device to be open multiple times
Randy Dunlap rdunlap@infradead.org media: i2c: ths8200 needs V4L2_ASYNC
Christophe JAILLET christophe.jaillet@wanadoo.fr media: imx-jpeg: Fix the error handling path of 'mxc_jpeg_probe()'
Christophe JAILLET christophe.jaillet@wanadoo.fr media: mtk-vpu: Fix a resource leak in the error handling path of 'mtk_vpu_probe()'
Tom Rix trix@redhat.com media: TDA1997x: handle short reads of hdmi info frame.
Dafna Hirschfeld dafna.hirschfeld@collabora.com media: mtk-vcodec: venc: fix return value when start_streaming fails
Ricardo Ribalda ribalda@chromium.org media: v4l2-ioctl: S_CTRL output the right value
Sakari Ailus sakari.ailus@linux.intel.com media: imx258: Fix getting clock frequency
Pavel Skripkin paskripkin@gmail.com media: dvb-usb: fix ununit-value in az6027_rc_query
Evgeny Novikov novikov@ispras.ru media: ttusb-dec: avoid release of non-acquired mutex
Colin Ian King colin.king@canonical.com media: cxd2880-spi: Fix a null pointer dereference on error handling path
Christophe JAILLET christophe.jaillet@wanadoo.fr media: meson-ge2d: Fix rotation parameter changes detection in 'ge2d_s_ctrl()'
Pavel Skripkin paskripkin@gmail.com media: em28xx: add missing em28xx_close_extension
Kumar Kartikeya Dwivedi memxor@gmail.com libbpf: Fix skel_internal.h to set errno on loader retval < 0
Arnd Bergmann arnd@arndb.de drm/amdgpu: fix warning for overflow check
Sudarshan Rajagopalan quic_sudaraja@quicinc.com arm64: mm: update max_pfn after memory hotplug
Matthew Auld matthew.auld@intel.com drm/ttm: stop calling tt_swapin in vm_access
Fabio Estevam festevam@denx.de ath10k: sdio: Add missing BH locking around napi_schdule()
Loic Poulain loic.poulain@linaro.org ath10k: Fix missing frame timestamp for beacon/probe-resp
Arnd Bergmann arnd@arndb.de gve: DQO: avoid unused variable warnings
Baochen Qiang bqiang@codeaurora.org ath11k: Fix memory leak in ath11k_qmi_driver_event_work
Pradeep Kumar Chitrapu pradeepc@codeaurora.org ath11k: fix packet drops due to incorrect 6 GHz freq value in rx status
Sriram R srirrama@codeaurora.org ath11k: Avoid race during regd updates
Dan Carpenter dan.carpenter@oracle.com ath11k: fix some sleeping in atomic bugs
Johan Almbladh johan.almbladh@anyfinetworks.com bpf/tests: Fix error in tail call limit tests
Linus Walleij linus.walleij@linaro.org net: dsa: rtl8366: Fix a bug in deleting VLANs
Linus Walleij linus.walleij@linaro.org net: dsa: rtl8366rb: Fix off-by-one bug
Leon Romanovsky leon@kernel.org net/mlx5: Accept devlink user input after driver initialization complete
Johannes Berg johannes.berg@intel.com cfg80211: always free wiphy specific regdomain
Johannes Berg johannes.berg@intel.com mac80211: twt: don't use potentially unaligned pointer
Kees Cook keescook@chromium.org fortify: Fix dropped strcpy() compile-time write overflow check
Florian Westphal fw@strlen.de mptcp: do not shrink snd_nxt when recovering
Jiasheng Jiang jiasheng@iscas.ac.cn rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies()
Leon Romanovsky leon@kernel.org qed: Don't ignore devlink allocation failures
Leon Romanovsky leon@kernel.org bnxt_en: Check devlink allocation and registration status
Hans de Goede hdegoede@redhat.com Bluetooth: hci_h5: Fix (runtime)suspend issues on RTL8723BS HCIs
Giovanni Cabiddu giovanni.cabiddu@intel.com crypto: qat - power up 4xxx device
Michael Walle michael@walle.cc crypto: caam - disable pkc for non-E SoCs
Guchun Chen guchun.chen@amd.com drm/amdgpu: move amdgpu_virt_release_full_gpu to fini_early stage
Harry Wentland harry.wentland@amd.com drm/amd/display: Pass display_pipe_params_st as const in DML
Andrey Grodzovsky andrey.grodzovsky@amd.com drm/amdgpu: Fix crash on device remove/driver unload
Dinghao Liu dinghao.liu@zju.edu.cn Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync
Ajay Singh ajay.kathat@microchip.com wilc1000: fix possible memory leak in cfg_scan_result()
Bryan O'Donoghue bryan.odonoghue@linaro.org wcn36xx: Fix Antenna Diversity Switching
Waiman Long longman@redhat.com cgroup: Make rebind_subsystems() disable v2 controllers all at once
Yoshitaka Ikeda ikeda@nskint.co.jp spi: Fixed division by zero warning
Alex Bee knaerzche@gmail.com drm: bridge: it66121: Fix return value it66121_probe
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: phylink: don't call netif_carrier_off() with NULL netdev
Yajun Deng yajun.deng@linux.dev net: net_namespace: Fix undefined member in key_remove_domain()
Sebastian Andrzej Siewior bigeasy@linutronix.de lockdep: Let lock_is_held_type() detect recursive read as read
liuyuntao liuyuntao10@huawei.com virtio-gpu: fix possible memory allocation failure
Nathan Chancellor nathan@kernel.org crypto: sm4 - Do not change section of ck and sbox
Iago Toral Quiroga itoral@igalia.com drm/v3d: fix wait for TMU write combiner flush
Leon Romanovsky leon@kernel.org net/mlx5: Publish and unpublish all devlink parameters at once
Peter Zijlstra peterz@infradead.org objtool: Handle __sanitize_cov*() tail calls
Peter Zijlstra peterz@infradead.org x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
Aleksander Jan Bajkowski olek2@wp.pl MIPS: lantiq: dma: fix burst length for DEU
Neeraj Upadhyay neeraju@codeaurora.org rcu: Fix existing exp request check in sync_sched_exp_online_cleanup()
Pavel Skripkin paskripkin@gmail.com Bluetooth: hci_uart: fix GPF in h5_recv
Toke Høiland-Jørgensen toke@redhat.com libbpf: Don't crash on object files with no symbol tables
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Bluetooth: fix init and cleanup of sco_conn.timeout_work
Paul Cercueil paul@crapouillou.net drm/bridge: it66121: Wait for next bridge to be probed
Paul Cercueil paul@crapouillou.net drm/bridge: it66121: Initialize {device,vendor}_ids
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Fix Intel SPR M3UPI event constraints
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Fix Intel SPR M2PCIE event constraints
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Fix Intel SPR IIO event constraints
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Fix Intel SPR CHA event constraints
Robert Foss robert.foss@linaro.org drm/bridge: anx7625: Propagate errors from sp_tx_rst_aux()
Imre Deak imre.deak@intel.com fbdev/efifb: Release PCI device's runtime PM ref during FB destroy
Andrii Nakryiko andrii@kernel.org selftests/bpf: Fix strobemeta selftest regression
Pablo Neira Ayuso pablo@netfilter.org netfilter: conntrack: set on IPS_ASSURED if flows enters internal stream state
Sven Schnelle svens@stackframe.org parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling
Sven Schnelle svens@stackframe.org parisc/unwind: fix unwinder when CONFIG_64BIT is enabled
Gao Xiang hsiangkao@linux.alibaba.com erofs: don't trigger WARN() when decompression fails
Helge Deller deller@gmx.de task_stack: Fix end_of_stack() for architectures with upwards-growing stack
Sven Schnelle svens@stackframe.org parisc: fix warning in flush_tlb_all
Stephane Eranian eranian@google.com perf/x86/intel: Fix ICL/SPR INST_RETIRED.PREC_DIST encodings
Shuah Khan skhan@linuxfoundation.org selftests/core: fix conflicting types compile error for close_range()
Anson Jacob Anson.Jacob@amd.com drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
Vitaly Kuznetsov vkuznets@redhat.com x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted
Eric Dumazet edumazet@google.com inet: remove races in inet{6}_getname()
王贇 yun.wang@linux.alibaba.com ftrace: do CPU checking after preemption disabled
Bryan O'Donoghue bryan.odonoghue@linaro.org Revert "wcn36xx: Enable firmware link monitoring"
Loic Poulain loic.poulain@linaro.org wcn36xx: Fix packet drop on resume
Loic Poulain loic.poulain@linaro.org wcn36xx: Correct band/freq reporting on RX
Yang Yingliang yangyingliang@huawei.com spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in bcm_qspi_probe()
Josef Bacik josef@toxicpanda.com btrfs: do not take the uuid_mutex in btrfs_rm_device
Sidong Yang realwakka@gmail.com btrfs: reflink: initialize return value to 0 in btrfs_extent_same()
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: flush switchdev workqueue when leaving the bridge
Hui Wang hui.wang@canonical.com ACPI: resources: Add one more Medion model in IRQ override quirk
Stefan Schaeckeler schaecsn@gmx.net ACPI: AC: Quirk GK45 to skip reading _PSR
Eric Dumazet edumazet@google.com net: annotate data-race in neigh_output()
Florian Westphal fw@strlen.de vrf: run conntrack only in context of lower/physdev for locally generated packets
Viktor Rosendahl Viktor.Rosendahl@bmw.de tools/latency-collector: Use correct size when writing queue_full_warning
Arnd Bergmann arnd@arndb.de ARM: 9136/1: ARMv7-M uses BE-8, not BE-32
Andreas Gruenbacher agruenba@redhat.com gfs2: Fix glock_hash_walk bugs
Andreas Gruenbacher agruenba@redhat.com gfs2: Cancel remote delete work asynchronously
Marc Kleine-Budde mkl@pengutronix.de can: bittiming: can_fixup_bittiming(): change type of tseg1 and alltseg to unsigned int
Vladimir Oltean vladimir.oltean@nxp.com net: dsa: lantiq_gswip: serialize access to the PCE table
Stephen Suryaputra ssuryaextr@gmail.com gre/sit: Don't generate link-local addr if addr_gen_mode is IN6_ADDR_GEN_MODE_NONE
Masami Hiramatsu mhiramat@kernel.org ARM: clang: Do not rely on lr register for stacktrace
Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp smackfs: use __GFP_NOFAIL for smk_cipso_doi()
Johannes Berg johannes.berg@intel.com iwlwifi: mvm: disable RX-diversity in powersave
Jiri Olsa jolsa@redhat.com selftests/bpf: Fix perf_buffer test on system with offline cpus
Shuah Khan skhan@linuxfoundation.org selftests: kvm: fix mismatched fclose() after popen()
Ye Bin yebin10@huawei.com PM: hibernate: Get block device exclusively in swsusp_check()
Nick Desaulniers ndesaulniers@google.com arm64: vdso32: suppress error message for 'make mrproper'
David Yang davidcomponentone@gmail.com samples/bpf: Fix application of sizeof to pointer
Hannes Reinecke hare@suse.de nvme: drop scan_lock and always kick requeue list when removing namespaces
Israel Rukshin israelr@nvidia.com nvmet-tcp: fix use-after-free when a port is removed
Israel Rukshin israelr@nvidia.com nvmet-rdma: fix use-after-free when a port is removed
Israel Rukshin israelr@nvidia.com nvmet: fix use-after-free when a port is removed
Alex Deucher alexander.deucher@amd.com drm/amdgpu/pm: properly handle sclk for profiling modes on vangogh
Michael Tretter m.tretter@pengutronix.de media: allegro: ignore interrupt if mailbox is not initialized
Jens Axboe axboe@kernel.dk block: remove inaccurate requeue check
Yaara Baruch yaara.baruch@intel.com iwlwifi: change all JnP to NO-160 configuration
Zheyu Ma zheyuma97@gmail.com mwl8k: Fix use-after-free in mwl8k_fw_state_machine()
Ryder Lee ryder.lee@mediatek.com mt76: mt7915: fix an off-by-one bound check
Kalesh Singh kaleshsingh@google.com tracing/cfi: Fix cmp_entries_* functions signature mismatch
Menglong Dong imagedong@tencent.com workqueue: make sysfs of unbound kworker cpumask more clever
Lasse Collin lasse.collin@tukaani.org lib/xz: Validate the value before assigning it to an enum variable
Lasse Collin lasse.collin@tukaani.org lib/xz: Avoid overlapping memcpy() with invalid input with in-place decompression
Yanfei Xu yanfei.xu@windriver.com locking/rwsem: Disable preemption for spinning region
Zheyu Ma zheyuma97@gmail.com memstick: r592: Fix a UAF bug when removing the driver
Xiao Ni xni@redhat.com md: update superblock after changing rdev flags in state_store
Luis Chamberlain mcgrof@kernel.org floppy: fix calling platform_device_unregister() on invalid drives
Jens Axboe axboe@kernel.dk block: bump max plugged deferred size from 16 to 32
Ansuel Smith ansuelsmth@gmail.com thermal/drivers/tsens: Add timeout to get_temp_tsens_valid
Tim Gardner tim.gardner@canonical.com drm/msm: prevent NULL dereference in msm_gpu_crashstate_capture()
Yuanzheng Song songyuanzheng@huawei.com thermal/core: Fix null pointer dereference in thermal_release()
Kees Cook keescook@chromium.org leaking_addresses: Always print a trailing newline
Matthias Schiffer matthias.schiffer@ew.tq-group.com net: phy: micrel: make *-skew-ps check more lenient
Yifan Zhang yifan1.zhang@amd.com drm/amdkfd: fix resume error when iommu disabled in Picasso
Aurabindo Pillai aurabindo.pillai@amd.com drm/amd/display: fix null pointer deref when plugging in display
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPI: scan: Release PM resources blocked by unused objects
André Almeida andrealmeid@collabora.com ACPI: battery: Accept charges over the design capacity as full
Andreas Gruenbacher agruenba@redhat.com iov_iter: Fix iov_iter_get_pages{,_alloc} page fault return value
Xin Xiong xiongx18@fudan.edu.cn mmc: moxart: Fix reference count leaks in moxart_probe
Will Deacon will@kernel.org KVM: arm64: Propagate errors from __pkvm_prot_finalize hypercall
Tuo Li islituo@gmail.com ath: dfs_pattern_detector: Fix possible null-pointer dereference in channel_detector_create()
Steven Rostedt (VMware) rostedt@goodmis.org tracing: Disable "other" permission bits in the tracefs files
Steven Rostedt (VMware) rostedt@goodmis.org tracefs: Have tracefs directories not set OTH permission bits by default
Alex Sierra alex.sierra@amd.com drm/amdkfd: rm BO resv on validation to avoid deadlock
Antoine Tenart atenart@kernel.org net-sysfs: try not to restart the syscall if it will fail eventually
Anant Thazhemadam anant.thazhemadam@gmail.com media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte()
Ricardo Ribalda ribalda@chromium.org media: ipu3-imgu: VIDIOC_QUERYCAP: Fix bus_info
Ricardo Ribalda ribalda@chromium.org media: ipu3-imgu: imgu_fmt: Handle properly try
Mirela Rabulea mirela.rabulea@nxp.com media: imx-jpeg: Fix possible null pointer dereference
Wojciech Drewek wojciech.drewek@intel.com ice: Move devlink port to PF/VF struct
Vincent Donnefort vincent.donnefort@arm.com cpufreq: Make policy min/max hard requirements
Rafael J. Wysocki rafael.j.wysocki@intel.com ACPICA: Avoid evaluating methods too early during system resume
Li Zhijian lizhijian@cn.fujitsu.com kselftests/sched: cleanup the child processes
Josh Don joshdon@google.com fs/proc/uptime.c: Fix idle time reporting in /proc/uptime
Corey Minyard cminyard@mvista.com ipmi: Disable some operations during a panic
Nadezda Lutovinova lutovinova@ispras.ru media: rcar-csi2: Add checking to rcsi2_start_receiver()
Hans de Goede hdegoede@redhat.com brcmfmac: Add DMI nvram filename quirk for Cyberbook T116 tablet
Zong-Zhe Yang kevin_yang@realtek.com rtw88: fix RX clock gate setting while fifo dump
Randy Dunlap rdunlap@infradead.org ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK
Rajat Asthana rajatasthana4@gmail.com media: mceusb: return without resubmitting URB in case of -EPROTO error.
Niklas Söderlund niklas.soderlund+renesas@ragnatech.se media: rcar-vin: Use user provided buffers when starting
Martin Kepplinger martink@posteo.de media: imx: set a media_device bus_info string
Sergey Senozhatsky senozhatsky@chromium.org media: videobuf2: rework vb2_mem_ops API
Nadezda Lutovinova lutovinova@ispras.ru media: s5p-mfc: Add checking to s5p_mfc_probe().
Tuo Li islituo@gmail.com media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe()
Evgeny Novikov novikov@ispras.ru media: vidtv: Fix memory leak in remove
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Set unique vdev name based in type
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Return -EIO for control errors
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Set capability in s_param
Dmitriy Ulitin ulitin@ispras.ru media: stm32: Potential NULL pointer dereference in dcmi_irq_thread()
Evgeny Novikov novikov@ispras.ru media: atomisp: Fix error handling in probe
Zheyu Ma zheyuma97@gmail.com media: netup_unidvb: handle interrupt properly according to the firmware
Dirk Bender d.bender@phytec.de media: mt9p031: Fix corrupted frame after restarting stream
Rakesh Babu rsaladi2@marvell.com octeontx2-pf: Enable promisc/allmulti match MCAM entries.
Alagu Sankar alagusankar@silex-india.com ath10k: high latency fixes for beacon buffer
Baochen Qiang bqiang@codeaurora.org ath11k: Change DMA_FROM_DEVICE to DMA_TO_DEVICE when map reinjected packets
Wen Gong wgong@codeaurora.org ath11k: add handler for scan event WMI_SCAN_EVENT_DEQUEUED
Sriram R srirrama@codeaurora.org ath11k: Avoid reg rules update during firmware recovery
Johannes Berg johannes.berg@intel.com leds: trigger: use RCU to protect the led_cdevs list
Petr Machata petrm@nvidia.com selftests: net: fib_nexthops: Wait before checking reported idle time
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
Jimmy Kizito Jimmy.Kizito@amd.com drm/amd/display: Fix null pointer dereference for encoders
Andrey Grodzovsky andrey.grodzovsky@amd.com drm/amdgpu: Fix MMIO access page fault
Eric Biggers ebiggers@google.com fscrypt: allow 256-bit master keys with AES-256-XTS
Mark Brown broonie@kernel.org spi: Check we have a spi_device_id for each DT compatible
Jonas Dreßler verdre@v0yd.nl mwifiex: Properly initialize private structure on interface type changes
Jonas Dreßler verdre@v0yd.nl mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type
Peter Zijlstra peterz@infradead.org x86: Increase exception stack sizes
Peter Zijlstra peterz@infradead.org x86/mm/64: Improve stack overflow warnings
Shreyansh Chouhan chouhan.shreyansh630@gmail.com crypto: aesni - check walk.nbytes instead of err
Seevalamuthu Mariappan seevalam@codeaurora.org ath11k: Align bss_chan_info structure with firmware
Pawan Gupta pawan.kumar.gupta@linux.intel.com smackfs: Fix use-after-free in netlbl_catmap_walk()
Paul E. McKenney paulmck@kernel.org rcu-tasks: Move RTGS_WAIT_CBS to beginning of rcu_tasks_kthread() loop
Hui Wang hui.wang@canonical.com ACPI: resources: Add DMI-based legacy IRQ override quirk
Jakub Kicinski kuba@kernel.org net: sched: update default qdisc visibility after Tx queue cnt changes
Peter Zijlstra peterz@infradead.org locking/lockdep: Avoid RCU-induced noinstr fail
Aleksander Jan Bajkowski olek2@wp.pl MIPS: lantiq: dma: reset correct number of channel
Aleksander Jan Bajkowski olek2@wp.pl MIPS: lantiq: dma: add small delay after reset
James Zhu James.Zhu@amd.com drm/amdgpu: move iommu_resume before ip init/resume
Barnabás Pőcze pobrn@protonmail.com platform/x86: wmi: do not fail if disabling fails
Scott Wood swood@redhat.com rcutorture: Avoid problematic critical section nesting on PREEMPT_RT
Simon Ser contact@emersion.fr drm/panel-orientation-quirks: add Valve Steam Deck
Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Bluetooth: call sock_hold earlier in sco_conn_del
Wang ShaoBo bobo.shaobowang@huawei.com Bluetooth: fix use-after-free error in lock_sock_nested()
Takashi Iwai tiwai@suse.de Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg()
Hans de Goede hdegoede@redhat.com drm: panel-orientation-quirks: Add quirk for the Samsung Galaxy Book 10.6
Hans de Goede hdegoede@redhat.com drm: panel-orientation-quirks: Add quirk for KD Kurio Smart C15200 2-in-1
Hans de Goede hdegoede@redhat.com drm: panel-orientation-quirks: Update the Lenovo Ideapad D330 quirk (v2)
Charan Teja Reddy charante@codeaurora.org dma-buf: WARN on dmabuf release with pending attachments
Kai Vehmanen kai.vehmanen@linux.intel.com component: do not leave master devres group open after bind
Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm power: supply: max17042_battery: Clear status bits in interrupt handler
Johan Hovold johan@kernel.org USB: chipidea: fix interrupt deadlock
Johan Hovold johan@kernel.org USB: iowarrior: fix control-message timeouts
Johan Hovold johan@kernel.org most: fix control-message timeouts
Johan Hovold johan@kernel.org Revert "serial: 8250: Fix reporting real baudrate value in c_ospeed field"
Pali Rohár pali@kernel.org serial: 8250: Fix reporting real baudrate value in c_ospeed field
Jens Axboe axboe@kernel.dk io-wq: serialize hash clear with wakeup
Namjae Jeon linkinjeon@kernel.org ksmbd: set unique value to volume serial field in FS_VOLUME_INFORMATION
Johan Hovold johan@kernel.org serial: 8250: fix racy uartclk update
Wang Hai wanghai38@huawei.com USB: serial: keyspan: fix memleak on probe errors
Mihail Chindris mihail.chindris@analog.com Documentation:devicetree:bindings:iio:dac: Fix val
Nuno Sá nuno.sa@analog.com iio: ad5770r: make devicetree property reading consistent
Pekka Korpinen pekka.korpinen@iki.fi iio: dac: ad5446: Fix ad5622_write() return value
Mihail Chindris mihail.chindris@analog.com drivers: iio: dac: ad5766: Fix dt property name
Yang Yingliang yangyingliang@huawei.com iio: buffer: Fix memory leak in iio_buffer_register_legacy_sysfs_groups()
Yang Yingliang yangyingliang@huawei.com iio: buffer: Fix memory leak in __iio_buffer_alloc_sysfs_and_mask()
Yang Yingliang yangyingliang@huawei.com iio: buffer: Fix memory leak in iio_buffers_alloc_sysfs_and_mask()
Yang Yingliang yangyingliang@huawei.com iio: buffer: check return value of kstrdup_const()
Suzuki K Poulose suzuki.poulose@arm.com coresight: trbe: Defer the probe on offline CPUs
Suzuki K Poulose suzuki.poulose@arm.com coresight: trbe: Fix incorrect access of the sink specific data
Tao Zhang quic_taozha@quicinc.com coresight: cti: Correct the parameter for pm_runtime_put
Yang Yingliang yangyingliang@huawei.com pinctrl: core: fix possible memory leak in pinctrl_enable()
Robert Marko robert.marko@sartura.hr mfd: simple-mfd-i2c: Select MFD_CORE to fix build error
Paulo Alcantara pc@cjr.nz cifs: set a minimum of 120s for next dns resolution
Shyam Prasad N sprasad@microsoft.com cifs: To match file servers, make sure the server hostname matches
Zhang Yi yi.zhang@huawei.com quota: correct error number in free_dqentry()
Zhang Yi yi.zhang@huawei.com quota: check block number when reading the block in quota file
Pali Rohár pali@kernel.org PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge
Pali Rohár pali@kernel.org PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge
Pali Rohár pali@kernel.org PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge
Pali Rohár pali@kernel.org PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated bridge
Marek Behún kabel@kernel.org PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG
Marek Behún kabel@kernel.org PCI: aardvark: Fix return value of MSI domain .alloc() method
Pali Rohár pali@kernel.org PCI: aardvark: Fix configuring Reference clock
Pali Rohár pali@kernel.org PCI: aardvark: Fix reporting Data Link Layer Link Active
Pali Rohár pali@kernel.org PCI: aardvark: Do not unmask unused interrupts
Pali Rohár pali@kernel.org PCI: aardvark: Fix checking for link up via LTSSM state
Pali Rohár pali@kernel.org PCI: aardvark: Do not clear status bits of masked interrupts
Dan Williams dan.j.williams@intel.com cxl/pci: Fix NULL vs ERR_PTR confusion
Li Chen lchen@ambarella.com PCI: cadence: Add cdns_plat_pcie_probe() missing return
Marek Behún kabel@kernel.org PCI: pci-bridge-emul: Fix emulation of W1C bits
Miklos Szeredi mszeredi@redhat.com ovl: fix filattr copy-up failure
yangerkun yangerkun@huawei.com ovl: fix use after free in struct ovl_aio_req
Juergen Gross jgross@suse.com xen/balloon: add late_initcall_sync() for initial ballooning done
Arnd Bergmann arnd@arndb.de ifb: fix building without CONFIG_NET_CLS_ACT
Pali Rohár pali@kernel.org serial: core: Fix initializing and restoring termios speed
Steven Rostedt (VMware) rostedt@goodmis.org ring-buffer: Protect ring_buffer_reset() from reentrancy
Pavel Begunkov asml.silence@gmail.com io_uring: honour zeroes as io-wq worker limits
Xiaoming Ni nixiaoming@huawei.com powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found
Oleksij Rempel linux@rempel-privat.de iio: adc: tsc2046: fix scan interval warning
Zhang Changzhong zhangchangzhong@huawei.com can: j1939: j1939_tp_cmd_recv(): check the dst address of TP.CM_BAM
Zhang Changzhong zhangchangzhong@huawei.com can: j1939: j1939_can_recv(): ignore messages with invalid source address
Zhang Changzhong zhangchangzhong@huawei.com can: j1939: j1939_tp_cmd_recv(): ignore abort message in the BAM transport
Marc Kleine-Budde mkl@pengutronix.de can: mcp251xfd: mcp251xfd_irq(): add missing can_rx_offload_threaded_irq_finish() in case of bus off
Stephane Grosjean s.grosjean@peak-system.com can: peak_usb: always ask for BERR reporting for PCAN-USB devices
Sean Christopherson seanjc@google.com KVM: nVMX: Handle dynamic MSR intercept toggling
Sean Christopherson seanjc@google.com KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use
Sean Christopherson seanjc@google.com KVM: x86: Add helper to consolidate core logic of SET_CPUID{2} flows
David Woodhouse dwmw2@infradead.org KVM: x86: Fix recording of guest steal time / preempted status
Mark Rutland mark.rutland@arm.com KVM: arm64: Extract ESR_ELx.EC only
Yang Yingliang yangyingliang@huawei.com iio: core: check return value when calling dev_set_name()
Yang Yingliang yangyingliang@huawei.com iio: core: fix double free in iio_device_unregister_sysfs()
Henrik Grimler henrik@grimler.se power: supply: max17042_battery: use VFSOC for capacity when no rsns
Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm power: supply: max17042_battery: Prevent int underflow in set_soc_threshold
Eugene Syromiatnikov esyr@redhat.com mctp: handle the struct sockaddr_mctp padding fields
Miquel Raynal miquel.raynal@bootlin.com mtd: rawnand: socrates: Keep the driver compatible with on-die ECC engines
Meng Li Meng.Li@windriver.com soc: fsl: dpio: use the combined functions to protect critical zone
Meng Li Meng.Li@windriver.com soc: fsl: dpio: replace smp_processor_id with raw_smp_processor_id
David Virag virag.david003@gmail.com soc: samsung: exynos-pmu: Fix compilation when nothing selects CONFIG_MFD_CORE
Eric W. Biederman ebiederm@xmission.com signal: Add SA_IMMUTABLE to ensure forced siganls do not get changed
Eric W. Biederman ebiederm@xmission.com signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT
Wolfram Sang wsa+renesas@sang-engineering.com memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode
Eric W. Biederman ebiederm@xmission.com signal: Remove the bogus sigkill_pending in ptrace_stop
Dmitry Osipenko digetx@gmail.com ASoC: tegra: Restore AC97 support
Dmitry Osipenko digetx@gmail.com ASoC: tegra: Set default card name for Trimslice
Alok Prasad palok@marvell.com RDMA/qedr: Fix NULL deref for query_qp on the GSI QP
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Fix Intel ICX IIO event constraints
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Fix invalid unit check
Kan Liang kan.liang@linux.intel.com perf/x86/intel/uncore: Support extra IMC channel on Ice Lake server
Marek Vasut marex@denx.de rsi: Fix module dev_oper_mode parameter description
Martin Fuzzey martin.fuzzey@flowbird.group rsi: fix rate mask set leading to P2P failure
Martin Fuzzey martin.fuzzey@flowbird.group rsi: fix key enabled check causing unwanted encryption for vap_id > 0
Martin Fuzzey martin.fuzzey@flowbird.group rsi: fix occasional initialisation failure with BT coex
Benjamin Li benl@squareup.com wcn36xx: handle connection loss indication
Christian König christian.koenig@amd.com dma-buf: fix and rework dma_buf_poll v7
Reimar Döffinger Reimar.Doeffinger@gmx.de libata: fix checking of DMA state
Jonas Dreßler verdre@v0yd.nl mwifiex: Try waking the firmware until we get an interrupt
Jonas Dreßler verdre@v0yd.nl mwifiex: Read a PCI register after writing the TX ring write pointer
Rafael J. Wysocki rafael.j.wysocki@intel.com PM: sleep: Do not let "syscore" devices runtime-suspend during system transitions
Loic Poulain loic.poulain@linaro.org wcn36xx: Fix (QoS) null data frame bitrate/modulation
Loic Poulain loic.poulain@linaro.org wcn36xx: Fix tx_status mechanism
Loic Poulain loic.poulain@linaro.org wcn36xx: Fix HT40 capability for 2Ghz band
Maximilian Luz luzmaximilian@gmail.com HID: surface-hid: Allow driver matching for target ID 1 devices
Maximilian Luz luzmaximilian@gmail.com HID: surface-hid: Use correct event registry for managing HID events
Felix Fietkau nbd@nbd.name mt76: mt7615: fix skb use-after-free on mac reset
Maximilian Luz luzmaximilian@gmail.com platform/surface: aggregator_registry: Add support for Surface Laptop Studio
Lukas Wunner lukas@wunner.de ifb: Depend on netfilter alternatively to tc
Austin Kim austin.kim@lge.com evm: mark evm_fixmode as __ro_after_init
Johan Hovold johan@kernel.org rtl8187: fix control-message timeouts
Ingmar Klein ingmar_klein@web.de PCI: Mark Atheros QCA6174 to avoid bus reset
Johan Hovold johan@kernel.org ath10k: fix division by zero in send path
Johan Hovold johan@kernel.org ath10k: fix control-message timeout
Johan Hovold johan@kernel.org ath6kl: fix control-message timeout
Johan Hovold johan@kernel.org ath6kl: fix division by zero in send path
Johan Hovold johan@kernel.org mwifiex: fix division by zero in fw download path
Eric Badger ebadger@purestorage.com EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell
Krzysztof Kozlowski krzysztof.kozlowski@canonical.com regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default-dvs-idx property
Krzysztof Kozlowski krzysztof.kozlowski@canonical.com regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is disabled
Zev Weiss zev@bewilderbeest.net hwmon: (pmbus/lm25066) Add offset coefficients
Guoqing Jiang guoqing.jiang@linux.dev md/raid1: only allocate write behind bio for WriteMostly device
Corey Minyard cminyard@mvista.com ipmi:watchdog: Set panic count to proper value on a panic
Ondrej Mosnacek omosnace@redhat.com selinux: fix race condition when computing ocontext SIDs
Masami Hiramatsu mhiramat@kernel.org ia64: kprobes: Fix to pass correct trampoline address to the handler
Laurent Vivier lvivier@redhat.com KVM: PPC: Tick accounting should defer vtime accounting 'til after IRQ handling
Andreas Gruenbacher agruenba@redhat.com powerpc/kvm: Fix kvm_use_magic_page
Sean Christopherson seanjc@google.com KVM: VMX: Unregister posted interrupt wakeup handler on hardware unsetup
Sean Christopherson seanjc@google.com KVM: x86/mmu: Drop a redundant, broken remote TLB flush
Anand Jain anand.jain@oracle.com btrfs: call btrfs_check_rw_degradable only if there is a missing device
Filipe Manana fdmanana@suse.com btrfs: fix lost error handling when replaying directory deletes
Li Zhang zhanglikernel@gmail.com btrfs: clear MISSING device status bit in btrfs_close_one_device
Peter Zijlstra peterz@infradead.org x86/iopl: Fake iopl(3) CLI/STI usage
Sean Christopherson seanjc@google.com x86/irq: Ensure PI wakeup handler is unregistered before module unload
Jane Malalane jane.malalane@citrix.com x86/cpu: Fix migration safety with X86_BUG_NULL_SEL
Tom Lendacky thomas.lendacky@amd.com x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c
Miklos Szeredi mszeredi@redhat.com fuse: fix page stealing
yangerkun yangerkun@huawei.com ext4: refresh the ext4_ext_path struct after dropping i_data_sem.
yangerkun yangerkun@huawei.com ext4: ensure enough credits in ext4_ext_shift_path_extents
Shaoying Xu shaoyi@amazon.com ext4: fix lazy initialization next schedule time computation in more granular unit
Eric Whitney enwlinux@gmail.com Revert "ext4: enforce buffer head state assertion in ext4_da_map_blocks"
Takashi Iwai tiwai@suse.de ALSA: timer: Unconditionally unlink slave instances, too
Wang Wensheng wangwensheng4@huawei.com ALSA: timer: Fix use-after-free problem
Takashi Iwai tiwai@suse.de ALSA: PCM: Fix NULL dereference at mmap checks
Takashi Iwai tiwai@suse.de ALSA: pci: rme: Fix unaligned buffer addresses
Austin Kim austin.kim@lge.com ALSA: synth: missing check for possible NULL after the call to kstrdup
Takashi Iwai tiwai@suse.de ALSA: hda: Free card instance properly at probe errors
Alexander Tsoy alexander@tsoy.me ALSA: usb-audio: Add registration quirk for JBL Quantum 400
Jason Ormes skryking@gmail.com ALSA: usb-audio: Line6 HX-Stomp XL USB_ID for 48k-fixed quirk
Pavel Skripkin paskripkin@gmail.com ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume
Takashi Iwai tiwai@suse.de ALSA: mixer: oss: Fix racy access to slots
Johan Hovold johan@kernel.org ALSA: line6: fix control and interrupt message timeouts
Johan Hovold johan@kernel.org ALSA: 6fire: fix control and bulk message timeouts
Johan Hovold johan@kernel.org ALSA: ua101: fix division by zero at probe
Kai-Heng Feng kai.heng.feng@canonical.com ALSA: hda/realtek: Add quirk for HP EliteBook 840 G7 mute LED
Takashi Iwai tiwai@suse.de ALSA: hda/realtek: Add quirk for ASUS UX550VE
Jaroslav Kysela perex@perex.cz ALSA: hda/realtek: Add a quirk for Acer Spin SP513-54N
Jeremy Soller jeremy@system76.com ALSA: hda/realtek: Headset fixup for Clevo NH77HJQ
Tim Crawford tcrawford@system76.com ALSA: hda/realtek: Add quirk for Clevo PC70HS
Takashi Iwai tiwai@suse.de ALSA: hda/realtek: Add a quirk for HP OMEN 15 mute LED
Johnathon Clark john.clark@cantab.net ALSA: hda/realtek: Fix mic mute LED for the HP Spectre x360 14
Ricardo Ribalda ribalda@chromium.org media: v4l2-ioctl: Fix check_ext_ctrls
Sean Young sean@mess.org media: ir-kbd-i2c: improve responsiveness of hauppauge zilog receivers
Chen-Yu Tsai wenst@chromium.org media: rkvdec: Support dynamic resolution changes
Sean Young sean@mess.org media: ite-cir: IR receiver stop working after receive overflow
Chen-Yu Tsai wenst@chromium.org media: rkvdec: Do not override sizeimage for output format
Tang Bin tangbin@cmss.chinamobile.com crypto: s5p-sss - Add error handling in s5p_aes_probe()
jing yangyang cgel.zte@gmail.com firmware/psci: fix application of sizeof to pointer
Dan Carpenter dan.carpenter@oracle.com tpm: Check for integer overflow in tpm2_map_response_body()
Helge Deller deller@gmx.de parisc: Fix ptrace check on syscall return
Helge Deller deller@gmx.de parisc: Fix set_fixmap() on PA1.x CPUs
Pavel Begunkov asml.silence@gmail.com io-wq: remove worker to owner tw dependency
Sungjong Seo sj1557.seo@samsung.com exfat: fix incorrect loading of i_blocks for large files
Christian Löhle CLoehle@hyperstone.com mmc: dw_mmc: Dont wait for DRTO on Write RSP error
Derong Liu derong.liu@mediatek.com mmc: mtk-sd: Add wait dma stop done flow
Ziyang Xuan william.xuanziyang@huawei.com char: xillybus: fix msg_ep UAF in xillyusb_probe()
Ben Skeggs bskeggs@redhat.com ce/gf100: fix incorrect CE0 address calculation on some GPUs
Quinn Tran qutran@marvell.com scsi: qla2xxx: Fix use after free in eh_abort path
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file
Arun Easi aeasi@marvell.com scsi: qla2xxx: Fix crash in NVMe abort path
James Smart jsmart2021@gmail.com scsi: lpfc: Fix FCP I/O flush functionality for TMF routines
James Smart jsmart2021@gmail.com scsi: lpfc: Don't release final kref on Fport node while ABTS outstanding
Tadeusz Struk tadeusz.struk@linaro.org scsi: core: Remove command size deduction from scsi_setup_scsi_cmnd()
Ewan D. Milne emilne@redhat.com scsi: core: Avoid leaving shost->last_reset with stale value if EH does not run
Tadeusz Struk tadeusz.struk@linaro.org scsi: scsi_ioctl: Validate command size
Jan Kara jack@suse.cz ocfs2: fix data corruption on truncate
Damien Le Moal damien.lemoal@opensource.wdc.com libata: fix read log timeout value
Takashi Iwai tiwai@suse.de Input: i8042 - Add quirk for Fujitsu Lifebook T725
Phoenix Huang phoenix@emc.com.tw Input: elantench - fix misreporting trackpoint coordinates
Johan Hovold johan@kernel.org Input: iforce - fix control-message timeout
Nehal Bakulchandra Shah Nehal-Bakulchandra.shah@amd.com usb: xhci: Enable runtime-pm by default on AMD Yellow Carp platform
Mathias Nyman mathias.nyman@linux.intel.com xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good delay
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 7 + .../devicetree/bindings/iio/dac/adi,ad5766.yaml | 2 +- .../bindings/regulator/samsung,s5m8767.txt | 23 +- Documentation/filesystems/fscrypt.rst | 10 +- Makefile | 4 +- arch/alpha/include/asm/processor.h | 2 +- arch/alpha/kernel/process.c | 5 +- arch/arc/include/asm/processor.h | 2 +- arch/arc/kernel/stacktrace.c | 4 +- arch/arm/Makefile | 22 +- arch/arm/boot/dts/at91-tse850-3.dts | 2 +- arch/arm/boot/dts/bcm4708-netgear-r6250.dts | 2 +- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 2 +- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 2 +- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 2 +- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 2 +- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 2 +- arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 2 +- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +- arch/arm/boot/dts/bcm94708.dts | 2 +- arch/arm/boot/dts/bcm94709.dts | 2 +- arch/arm/boot/dts/omap3-gta04.dtsi | 2 +- arch/arm/boot/dts/qcom-msm8974.dtsi | 4 +- arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 8 +- arch/arm/boot/dts/stm32mp151.dtsi | 16 +- arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 2 +- arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +- arch/arm/include/asm/processor.h | 2 +- arch/arm/kernel/process.c | 4 +- arch/arm/kernel/stacktrace.c | 3 +- arch/arm/mach-s3c/irq-s3c24xx.c | 22 +- arch/arm/mm/Kconfig | 2 +- arch/arm/mm/kasan_init.c | 2 +- arch/arm/mm/mmu.c | 4 +- arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts | 2 +- .../boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi | 4 +- .../boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 +- arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi | 4 +- .../boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +- .../boot/dts/amlogic/meson-sm1-khadas-vim3l.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 6 +- arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts | 2 +- arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8916.dtsi | 8 +- arch/arm64/boot/dts/qcom/pm8916.dtsi | 1 - arch/arm64/boot/dts/qcom/pmi8994.dtsi | 2 +- .../arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi | 2 +- .../arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi | 8 +- arch/arm64/boot/dts/qcom/sc7180.dtsi | 52 ++--- arch/arm64/boot/dts/qcom/sc7280.dtsi | 8 +- arch/arm64/boot/dts/qcom/sdm845.dtsi | 6 +- .../arm64/boot/dts/renesas/beacon-renesom-som.dtsi | 1 + arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 +- arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 6 +- arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 16 +- arch/arm64/include/asm/esr.h | 1 + arch/arm64/include/asm/pgtable.h | 12 +- arch/arm64/include/asm/processor.h | 2 +- arch/arm64/kernel/cpufeature.c | 10 +- arch/arm64/kernel/process.c | 4 +- arch/arm64/kernel/vdso32/Makefile | 3 +- arch/arm64/kvm/arm.c | 30 ++- arch/arm64/kvm/hyp/hyp-entry.S | 2 +- arch/arm64/kvm/hyp/nvhe/host.S | 2 +- arch/arm64/mm/mmu.c | 5 + arch/csky/include/asm/processor.h | 2 +- arch/csky/kernel/stacktrace.c | 5 +- arch/h8300/include/asm/processor.h | 2 +- arch/h8300/kernel/process.c | 5 +- arch/hexagon/include/asm/processor.h | 2 +- arch/hexagon/kernel/process.c | 4 +- arch/ia64/Kconfig.debug | 2 +- arch/ia64/include/asm/processor.h | 2 +- arch/ia64/kernel/kprobes.c | 9 +- arch/ia64/kernel/process.c | 5 +- arch/m68k/Kconfig.machine | 1 + arch/m68k/include/asm/processor.h | 2 +- arch/m68k/kernel/process.c | 4 +- arch/microblaze/include/asm/processor.h | 2 +- arch/microblaze/kernel/process.c | 2 +- arch/mips/Kbuild.platforms | 2 +- arch/mips/Kconfig | 1 + arch/mips/Makefile | 2 + arch/mips/include/asm/cmpxchg.h | 5 +- arch/mips/include/asm/mips-cm.h | 12 +- arch/mips/include/asm/processor.h | 2 +- arch/mips/kernel/mips-cm.c | 21 +- arch/mips/kernel/process.c | 8 +- arch/mips/kernel/r2300_fpu.S | 4 +- arch/mips/kernel/syscall.c | 9 - arch/mips/lantiq/xway/dma.c | 23 +- arch/nds32/include/asm/processor.h | 2 +- arch/nds32/kernel/process.c | 7 +- arch/nios2/include/asm/processor.h | 2 +- arch/nios2/kernel/process.c | 5 +- arch/openrisc/include/asm/processor.h | 2 +- arch/openrisc/kernel/dma.c | 4 +- arch/openrisc/kernel/process.c | 2 +- arch/openrisc/kernel/smp.c | 6 +- arch/parisc/include/asm/pgtable.h | 10 +- arch/parisc/include/asm/processor.h | 2 +- arch/parisc/kernel/cache.c | 4 +- arch/parisc/kernel/entry.S | 2 +- arch/parisc/kernel/process.c | 5 +- arch/parisc/kernel/smp.c | 19 +- arch/parisc/kernel/unwind.c | 21 +- arch/parisc/kernel/vmlinux.lds.S | 3 +- arch/parisc/mm/fixmap.c | 5 +- arch/parisc/mm/init.c | 4 +- arch/powerpc/Kconfig | 6 +- arch/powerpc/include/asm/nohash/32/pgtable.h | 19 +- arch/powerpc/include/asm/nohash/32/pte-8xx.h | 22 ++ arch/powerpc/include/asm/nohash/64/pgtable.h | 5 - arch/powerpc/include/asm/nohash/pte-book3e.h | 18 +- arch/powerpc/include/asm/paravirt.h | 18 +- arch/powerpc/include/asm/processor.h | 2 +- arch/powerpc/kernel/firmware.c | 7 +- arch/powerpc/kernel/head_booke.h | 15 +- arch/powerpc/kernel/interrupt.c | 2 +- arch/powerpc/kernel/kvm.c | 2 +- arch/powerpc/kernel/process.c | 9 +- arch/powerpc/kvm/book3s_hv.c | 30 ++- arch/powerpc/kvm/booke.c | 16 +- arch/powerpc/lib/feature-fixups.c | 11 + arch/powerpc/mm/mem.c | 2 +- arch/powerpc/mm/nohash/tlb_low_64e.S | 8 +- arch/powerpc/mm/pgtable_32.c | 2 +- arch/powerpc/net/bpf_jit_comp.c | 2 +- arch/powerpc/perf/power10-events-list.h | 8 +- arch/powerpc/perf/power10-pmu.c | 44 ++-- arch/powerpc/platforms/44x/fsp2.c | 2 + arch/powerpc/platforms/85xx/Makefile | 4 +- arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c | 7 +- arch/powerpc/platforms/85xx/smp.c | 12 +- arch/powerpc/platforms/book3s/vas-api.c | 4 +- arch/powerpc/platforms/powernv/opal-prd.c | 12 +- arch/powerpc/platforms/pseries/mobility.c | 34 +++ arch/powerpc/xmon/xmon.c | 3 +- arch/riscv/include/asm/processor.h | 2 +- arch/riscv/kernel/stacktrace.c | 12 +- arch/s390/include/asm/processor.h | 2 +- arch/s390/kernel/perf_cpum_cf.c | 4 +- arch/s390/kernel/process.c | 4 +- arch/s390/kernel/uv.c | 2 +- arch/s390/kvm/priv.c | 2 + arch/s390/kvm/pv.c | 21 +- arch/s390/mm/gmap.c | 11 +- arch/s390/mm/pgtable.c | 70 ++++-- arch/sh/include/asm/processor_32.h | 2 +- arch/sh/kernel/cpu/fpu.c | 10 +- arch/sh/kernel/process_32.c | 5 +- arch/sparc/boot/Makefile | 8 +- arch/sparc/include/asm/processor_32.h | 2 +- arch/sparc/include/asm/processor_64.h | 2 +- arch/sparc/kernel/process_32.c | 5 +- arch/sparc/kernel/process_64.c | 5 +- arch/um/include/asm/processor-generic.h | 2 +- arch/um/kernel/process.c | 5 +- arch/x86/crypto/aesni-intel_glue.c | 2 +- arch/x86/events/intel/core.c | 5 +- arch/x86/events/intel/ds.c | 5 +- arch/x86/events/intel/uncore_discovery.h | 2 +- arch/x86/events/intel/uncore_snbep.c | 16 +- arch/x86/hyperv/hv_init.c | 5 +- arch/x86/include/asm/insn-eval.h | 1 + arch/x86/include/asm/irq_stack.h | 37 ++- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/include/asm/page_64_types.h | 2 +- arch/x86/include/asm/processor.h | 3 +- arch/x86/include/asm/stacktrace.h | 10 + arch/x86/include/asm/traps.h | 6 +- arch/x86/kernel/cpu/amd.c | 2 + arch/x86/kernel/cpu/common.c | 44 +++- arch/x86/kernel/cpu/cpu.h | 1 + arch/x86/kernel/cpu/hygon.c | 2 + arch/x86/kernel/cpu/mce/intel.c | 5 +- arch/x86/kernel/dumpstack_64.c | 6 + arch/x86/kernel/irq.c | 4 +- arch/x86/kernel/process.c | 66 ++---- arch/x86/kernel/traps.c | 60 +++-- arch/x86/kvm/cpuid.c | 47 ++-- arch/x86/kvm/mmu/mmu.c | 6 +- arch/x86/kvm/vmx/nested.c | 103 ++++---- arch/x86/kvm/vmx/vmx.c | 68 +----- arch/x86/kvm/vmx/vmx.h | 63 +++++ arch/x86/kvm/x86.c | 108 ++++++--- arch/x86/lib/insn-eval.c | 2 +- arch/x86/lib/insn.c | 5 +- arch/x86/mm/fault.c | 20 +- arch/x86/mm/mem_encrypt_identity.c | 9 + arch/xtensa/include/asm/processor.h | 2 +- arch/xtensa/kernel/process.c | 5 +- block/blk-cgroup.c | 10 + block/blk-mq.c | 5 +- block/blk-wbt.c | 3 + block/blk-zoned.c | 15 +- block/blk.h | 6 + block/genhd.c | 8 +- block/ioctl.c | 24 +- crypto/Kconfig | 2 +- crypto/algapi.c | 73 ++++-- crypto/api.c | 52 ++++- crypto/internal.h | 10 + crypto/pcrypt.c | 12 +- crypto/tcrypt.c | 5 +- drivers/acpi/ac.c | 19 ++ drivers/acpi/acpica/acglobal.h | 2 + drivers/acpi/acpica/hwesleep.c | 8 +- drivers/acpi/acpica/hwsleep.c | 11 +- drivers/acpi/acpica/hwxfsleep.c | 7 + drivers/acpi/battery.c | 2 +- drivers/acpi/glue.c | 25 ++ drivers/acpi/internal.h | 1 + drivers/acpi/pmic/intel_pmic.c | 51 ++-- drivers/acpi/power.c | 86 +++---- drivers/acpi/resource.c | 56 ++++- drivers/acpi/scan.c | 6 + drivers/ata/libata-core.c | 2 +- drivers/ata/libata-eh.c | 8 + drivers/auxdisplay/ht16k33.c | 66 +++--- drivers/auxdisplay/img-ascii-lcd.c | 10 + drivers/base/component.c | 5 +- drivers/base/core.c | 4 +- drivers/base/power/main.c | 93 +++++--- drivers/block/ataflop.c | 141 ++++++----- drivers/block/floppy.c | 9 +- drivers/block/nbd.c | 24 +- drivers/block/zram/zram_drv.c | 2 +- drivers/bluetooth/btmtkuart.c | 13 +- drivers/bluetooth/hci_h5.c | 28 ++- drivers/bus/ti-sysc.c | 65 +++++- drivers/char/hw_random/mtk-rng.c | 9 +- drivers/char/ipmi/ipmi_msghandler.c | 10 +- drivers/char/ipmi/ipmi_watchdog.c | 25 +- drivers/char/ipmi/kcs_bmc_serio.c | 4 +- drivers/char/tpm/tpm2-space.c | 3 + drivers/char/tpm/tpm_tis_core.c | 26 ++- drivers/char/tpm/tpm_tis_core.h | 4 + drivers/char/tpm/tpm_tis_spi_main.c | 1 + drivers/char/xillybus/xillyusb.c | 1 + drivers/clk/at91/clk-master.c | 6 +- drivers/clk/at91/clk-sam9x60-pll.c | 4 +- drivers/clk/at91/pmc.c | 5 + drivers/clk/mvebu/ap-cpu-clk.c | 14 +- drivers/clocksource/Kconfig | 1 + drivers/cpufreq/cpufreq.c | 7 + drivers/cpufreq/intel_pstate.c | 35 ++- drivers/cpuidle/sysfs.c | 5 +- drivers/crypto/caam/caampkc.c | 19 +- drivers/crypto/caam/regs.h | 3 + drivers/crypto/ccree/cc_driver.c | 3 +- drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c | 1 + drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 31 +++ drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 10 + drivers/crypto/qat/qat_common/adf_accel_devices.h | 1 + drivers/crypto/qat/qat_common/adf_init.c | 5 + drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 13 ++ drivers/crypto/qat/qat_common/adf_vf_isr.c | 6 + drivers/crypto/s5p-sss.c | 2 + drivers/cxl/pci.c | 2 +- drivers/dma-buf/dma-buf.c | 153 ++++++------ drivers/dma/at_xdmac.c | 53 +++-- drivers/dma/bestcomm/ata.c | 2 +- drivers/dma/bestcomm/bestcomm.c | 22 +- drivers/dma/bestcomm/fec.c | 4 +- drivers/dma/bestcomm/gen_bd.c | 4 +- drivers/dma/dmaengine.h | 2 +- drivers/dma/idxd/device.c | 3 +- drivers/dma/idxd/dma.c | 5 +- drivers/dma/idxd/init.c | 14 +- drivers/dma/stm32-dma.c | 23 +- drivers/dma/tegra210-adma.c | 2 +- drivers/dma/ti/k3-udma.c | 32 ++- drivers/edac/amd64_edac.c | 22 +- drivers/edac/sb_edac.c | 2 +- drivers/firmware/psci/psci_checker.c | 2 +- drivers/firmware/qcom_scm.c | 2 +- drivers/gpio/gpio-realtek-otto.c | 2 +- drivers/gpu/drm/Kconfig | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 15 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c | 24 +- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 24 +- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 24 +- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 24 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 32 +-- drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 19 +- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 28 +-- drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 44 ++-- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 8 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 17 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 + drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 7 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 18 +- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 +- .../display/dc/dml/dcn20/display_rq_dlg_calc_20.c | 6 +- .../display/dc/dml/dcn20/display_rq_dlg_calc_20.h | 4 +- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 6 +- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.h | 4 +- .../display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 62 ++--- .../display/dc/dml/dcn21/display_rq_dlg_calc_21.h | 4 +- .../display/dc/dml/dcn30/display_rq_dlg_calc_30.c | 72 +++--- .../display/dc/dml/dcn30/display_rq_dlg_calc_30.h | 4 +- .../display/dc/dml/dcn31/display_rq_dlg_calc_31.c | 68 +++--- .../display/dc/dml/dcn31/display_rq_dlg_calc_31.h | 4 +- .../gpu/drm/amd/display/dc/dml/display_mode_lib.h | 4 +- .../gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 8 +- .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 10 +- .../gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c | 2 + .../gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h | 13 ++ .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 12 +- .../gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 4 + .../gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 14 +- drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 89 +++---- drivers/gpu/drm/bridge/analogix/anx7625.c | 12 +- drivers/gpu/drm/bridge/ite-it66121.c | 21 +- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 9 +- drivers/gpu/drm/bridge/nwl-dsi.c | 35 +++ drivers/gpu/drm/drm_panel_orientation_quirks.c | 35 ++- drivers/gpu/drm/drm_plane_helper.c | 1 - drivers/gpu/drm/i915/display/intel_fb.c | 5 +- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +- drivers/gpu/drm/imx/imx-drm-core.c | 2 - drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 8 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 + drivers/gpu/drm/msm/dsi/dsi.h | 2 + drivers/gpu/drm/msm/dsi/dsi_host.c | 72 +++--- drivers/gpu/drm/msm/dsi/dsi_manager.c | 16 ++ drivers/gpu/drm/msm/msm_gem.c | 5 +- drivers/gpu/drm/msm/msm_gpu.c | 2 +- drivers/gpu/drm/msm/msm_submitqueue.c | 1 + drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- drivers/gpu/drm/nouveau/nouveau_svm.c | 4 + drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 3 +- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/sun4i/sun8i_csc.h | 4 +- drivers/gpu/drm/ttm/ttm_bo_vm.c | 99 +------- drivers/gpu/drm/v3d/v3d_gem.c | 4 +- drivers/gpu/drm/virtio/virtgpu_vq.c | 8 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 - drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 72 +----- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 3 - drivers/hid/hid-u2fzero.c | 10 +- drivers/hid/surface-hid/surface_hid.c | 4 +- drivers/hwmon/hwmon.c | 6 +- drivers/hwmon/pmbus/lm25066.c | 25 +- drivers/hwtracing/coresight/coresight-cti-core.c | 2 +- drivers/hwtracing/coresight/coresight-trbe.c | 10 +- drivers/i2c/busses/i2c-i801.c | 5 +- drivers/i2c/busses/i2c-mt65xx.c | 2 +- drivers/i2c/busses/i2c-xlr.c | 6 +- drivers/iio/accel/st_accel_i2c.c | 4 +- drivers/iio/accel/st_accel_spi.c | 4 +- drivers/iio/adc/ti-tsc2046.c | 2 +- drivers/iio/dac/ad5446.c | 9 +- drivers/iio/dac/ad5766.c | 6 +- drivers/iio/dac/ad5770r.c | 2 +- drivers/iio/gyro/st_gyro_i2c.c | 4 +- drivers/iio/gyro/st_gyro_spi.c | 4 +- drivers/iio/imu/adis.c | 4 +- drivers/iio/industrialio-buffer.c | 28 ++- drivers/iio/industrialio-core.c | 9 +- drivers/iio/magnetometer/st_magn_i2c.c | 4 +- drivers/iio/magnetometer/st_magn_spi.c | 4 +- drivers/iio/pressure/st_pressure_i2c.c | 4 +- drivers/iio/pressure/st_pressure_spi.c | 8 +- drivers/infiniband/core/uverbs_cmd.c | 3 - drivers/infiniband/hw/bnxt_re/qplib_fp.c | 3 +- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +- drivers/infiniband/hw/mlx4/qp.c | 4 +- drivers/infiniband/hw/qedr/verbs.c | 15 +- drivers/infiniband/sw/rxe/rxe_param.h | 2 +- drivers/input/joystick/iforce/iforce-usb.c | 2 +- drivers/input/misc/ariel-pwrbutton.c | 7 + drivers/input/mouse/elantech.c | 13 ++ drivers/input/serio/i8042-x86ia64io.h | 14 ++ drivers/input/touchscreen/st1232.c | 2 +- drivers/iommu/dma-iommu.c | 52 ++--- drivers/iommu/mtk_iommu.c | 4 +- drivers/irqchip/irq-bcm6345-l1.c | 2 +- drivers/irqchip/irq-sifive-plic.c | 8 +- drivers/leds/led-triggers.c | 41 ++-- drivers/mailbox/mtk-cmdq-mailbox.c | 11 +- drivers/md/bcache/btree.c | 2 +- drivers/md/bcache/super.c | 2 +- drivers/md/md.c | 11 +- drivers/md/raid1.c | 2 +- drivers/media/common/videobuf2/videobuf2-core.c | 42 ++-- .../media/common/videobuf2/videobuf2-dma-contig.c | 36 +-- drivers/media/common/videobuf2/videobuf2-dma-sg.c | 33 +-- drivers/media/common/videobuf2/videobuf2-vmalloc.c | 30 +-- drivers/media/dvb-frontends/mn88443x.c | 18 +- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/imx258.c | 12 +- drivers/media/i2c/ir-kbd-i2c.c | 1 + drivers/media/i2c/mt9p031.c | 28 ++- drivers/media/i2c/tda1997x.c | 8 +- drivers/media/pci/cx23885/cx23885-alsa.c | 3 +- drivers/media/pci/ivtv/ivtvfb.c | 4 +- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 27 ++- drivers/media/platform/allegro-dvt/allegro-core.c | 9 + drivers/media/platform/atmel/atmel-isc-base.c | 25 +- drivers/media/platform/atmel/atmel-isc.h | 2 + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 39 ++-- drivers/media/platform/atmel/atmel-sama7g5-isc.c | 22 +- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 6 + drivers/media/platform/meson/ge2d/ge2d.c | 6 +- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 8 +- drivers/media/platform/mtk-vpu/mtk_vpu.c | 5 +- drivers/media/platform/qcom/venus/pm_helpers.c | 8 +- drivers/media/platform/rcar-vin/rcar-csi2.c | 2 + drivers/media/platform/rcar-vin/rcar-dma.c | 3 +- drivers/media/platform/s5p-mfc/s5p_mfc.c | 6 +- drivers/media/platform/stm32/stm32-dcmi.c | 19 +- .../media/platform/sunxi/sun6i-csi/sun6i_video.c | 6 +- drivers/media/radio/radio-wl1273.c | 2 +- drivers/media/radio/si470x/radio-si470x-i2c.c | 2 +- drivers/media/radio/si470x/radio-si470x-usb.c | 2 +- drivers/media/rc/ir_toy.c | 2 +- drivers/media/rc/ite-cir.c | 2 +- drivers/media/rc/mceusb.c | 1 + drivers/media/spi/cxd2880-spi.c | 2 +- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 1 + drivers/media/usb/dvb-usb/az6027.c | 1 + drivers/media/usb/dvb-usb/dibusb-common.c | 2 +- drivers/media/usb/em28xx/em28xx-cards.c | 5 +- drivers/media/usb/em28xx/em28xx-core.c | 5 +- drivers/media/usb/tm6000/tm6000-video.c | 3 +- drivers/media/usb/ttusb-dec/ttusb_dec.c | 10 +- drivers/media/usb/uvc/uvc_driver.c | 7 +- drivers/media/usb/uvc/uvc_v4l2.c | 7 +- drivers/media/usb/uvc/uvc_video.c | 5 + drivers/media/v4l2-core/v4l2-ioctl.c | 67 ++++-- drivers/memory/fsl_ifc.c | 13 +- drivers/memory/renesas-rpc-if.c | 113 ++++++--- drivers/memstick/core/ms_block.c | 2 +- drivers/memstick/host/jmb38x_ms.c | 2 +- drivers/memstick/host/r592.c | 8 +- drivers/mfd/Kconfig | 1 + drivers/mfd/altera-sysmgr.c | 2 +- drivers/mfd/dln2.c | 18 ++ drivers/mfd/mfd-core.c | 2 + drivers/mfd/motorola-cpcap.c | 8 + drivers/mfd/sprd-sc27xx-spi.c | 7 + drivers/mmc/host/dw_mmc.c | 3 +- drivers/mmc/host/moxart-mmc.c | 16 +- drivers/mmc/host/mtk-sd.c | 5 + drivers/mmc/host/mxs-mmc.c | 10 + drivers/mmc/host/sdhci-omap.c | 18 +- drivers/most/most_usb.c | 5 +- drivers/mtd/mtdcore.c | 4 +- drivers/mtd/nand/raw/ams-delta.c | 12 +- drivers/mtd/nand/raw/arasan-nand-controller.c | 15 ++ drivers/mtd/nand/raw/au1550nd.c | 12 +- drivers/mtd/nand/raw/fsmc_nand.c | 4 +- drivers/mtd/nand/raw/gpio.c | 12 +- drivers/mtd/nand/raw/intel-nand-controller.c | 5 + drivers/mtd/nand/raw/mpc5121_nfc.c | 12 +- drivers/mtd/nand/raw/orion_nand.c | 12 +- drivers/mtd/nand/raw/pasemi_nand.c | 12 +- drivers/mtd/nand/raw/plat_nand.c | 12 +- drivers/mtd/nand/raw/socrates_nand.c | 12 +- drivers/mtd/nand/raw/xway_nand.c | 12 +- drivers/mtd/spi-nor/controllers/hisi-sfc.c | 1 - drivers/net/Kconfig | 2 +- drivers/net/bonding/bond_sysfs_slave.c | 36 +-- drivers/net/can/dev/bittiming.c | 2 +- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 6 +- drivers/net/can/usb/etas_es58x/es58x_core.c | 6 +- drivers/net/can/usb/peak_usb/pcan_usb.c | 17 +- drivers/net/dsa/lantiq_gswip.c | 28 ++- drivers/net/dsa/mv88e6xxx/chip.c | 5 +- drivers/net/dsa/ocelot/felix.c | 9 +- drivers/net/dsa/rtl8366.c | 2 +- drivers/net/dsa/rtl8366rb.c | 2 +- drivers/net/ethernet/amd/xgbe/xgbe-common.h | 8 + drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 20 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 +- drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 13 +- drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h | 13 -- drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 7 +- drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 2 + .../chelsio/inline_crypto/chtls/chtls_cm.c | 2 +- .../chelsio/inline_crypto/chtls/chtls_cm.h | 2 +- drivers/net/ethernet/dec/tulip/winbond-840.c | 2 +- drivers/net/ethernet/fealnx.c | 2 +- drivers/net/ethernet/freescale/enetc/enetc_qos.c | 18 +- drivers/net/ethernet/google/gve/gve.h | 17 +- drivers/net/ethernet/google/gve/gve_adminq.h | 1 + drivers/net/ethernet/google/gve/gve_main.c | 48 +++- drivers/net/ethernet/google/gve/gve_rx.c | 7 +- drivers/net/ethernet/google/gve/gve_tx.c | 23 +- drivers/net/ethernet/google/gve/gve_tx_dqo.c | 84 +++---- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 20 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 10 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 6 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 77 +++--- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 4 +- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 10 +- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 4 +- drivers/net/ethernet/ibm/ibmvnic.c | 21 +- drivers/net/ethernet/intel/ice/ice.h | 7 +- drivers/net/ethernet/intel/ice/ice_base.c | 2 +- drivers/net/ethernet/intel/ice/ice_devlink.c | 109 ++++++--- drivers/net/ethernet/intel/ice/ice_devlink.h | 6 +- drivers/net/ethernet/intel/ice/ice_lib.c | 3 +- drivers/net/ethernet/intel/ice/ice_main.c | 4 +- drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 22 +- drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h | 9 + drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +- drivers/net/ethernet/litex/litex_liteeth.c | 1 - drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 38 +-- drivers/net/ethernet/marvell/octeontx2/Kconfig | 1 + .../net/ethernet/marvell/octeontx2/nic/otx2_pf.c | 78 ++++--- drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 18 +- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 + .../ethernet/mellanox/mlx5/core/sf/dev/driver.c | 2 + .../net/ethernet/netronome/nfp/nfp_net_common.c | 8 +- drivers/net/ethernet/qlogic/qede/qede_main.c | 12 +- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 2 - drivers/net/ethernet/ti/cpsw_ale.c | 6 +- drivers/net/ethernet/ti/davinci_emac.c | 16 +- drivers/net/ifb.c | 2 + drivers/net/phy/micrel.c | 9 +- drivers/net/phy/phy.c | 7 +- drivers/net/phy/phylink.c | 7 +- drivers/net/vrf.c | 28 ++- drivers/net/wireless/ath/ath10k/core.c | 11 +- drivers/net/wireless/ath/ath10k/coredump.c | 11 +- drivers/net/wireless/ath/ath10k/coredump.h | 7 + drivers/net/wireless/ath/ath10k/mac.c | 37 ++- drivers/net/wireless/ath/ath10k/qmi.c | 3 +- drivers/net/wireless/ath/ath10k/sdio.c | 5 +- drivers/net/wireless/ath/ath10k/snoc.c | 77 ++++++ drivers/net/wireless/ath/ath10k/snoc.h | 5 + drivers/net/wireless/ath/ath10k/usb.c | 7 +- drivers/net/wireless/ath/ath10k/wmi.c | 4 + drivers/net/wireless/ath/ath10k/wmi.h | 3 + drivers/net/wireless/ath/ath11k/dbring.c | 16 +- drivers/net/wireless/ath/ath11k/dp_rx.c | 13 +- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/ath/ath11k/qmi.c | 4 +- drivers/net/wireless/ath/ath11k/reg.c | 11 +- drivers/net/wireless/ath/ath11k/reg.h | 2 +- drivers/net/wireless/ath/ath11k/wmi.c | 40 ++-- drivers/net/wireless/ath/ath11k/wmi.h | 3 +- drivers/net/wireless/ath/ath6kl/usb.c | 7 +- drivers/net/wireless/ath/ath9k/main.c | 4 +- drivers/net/wireless/ath/dfs_pattern_detector.c | 10 +- drivers/net/wireless/ath/wcn36xx/dxe.c | 49 ++-- drivers/net/wireless/ath/wcn36xx/hal.h | 32 +++ drivers/net/wireless/ath/wcn36xx/main.c | 21 +- drivers/net/wireless/ath/wcn36xx/smd.c | 126 +++++++++- drivers/net/wireless/ath/wcn36xx/smd.h | 1 + drivers/net/wireless/ath/wcn36xx/txrx.c | 64 ++--- drivers/net/wireless/ath/wcn36xx/txrx.h | 3 +- drivers/net/wireless/broadcom/b43/phy_g.c | 2 +- drivers/net/wireless/broadcom/b43legacy/radio.c | 2 +- .../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 10 + drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 13 +- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 3 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 +- drivers/net/wireless/marvell/libertas/if_usb.c | 2 + drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 + drivers/net/wireless/marvell/mwifiex/11n.c | 5 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 32 +-- drivers/net/wireless/marvell/mwifiex/pcie.c | 36 ++- drivers/net/wireless/marvell/mwifiex/usb.c | 16 ++ drivers/net/wireless/marvell/mwl8k.c | 2 +- drivers/net/wireless/mediatek/mt76/debugfs.c | 10 +- drivers/net/wireless/mediatek/mt76/mt76.h | 8 +- .../net/wireless/mediatek/mt76/mt7615/debugfs.c | 29 ++- drivers/net/wireless/mediatek/mt76/mt7615/init.c | 6 +- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 60 ++--- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 +- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 18 +- .../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 30 ++- .../net/wireless/mediatek/mt76/mt76_connac_mcu.h | 8 +- drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 13 +- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 10 +- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 3 +- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 22 +- .../net/wireless/mediatek/mt76/mt7921/debugfs.c | 36 ++- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 13 ++ drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 68 +++++- drivers/net/wireless/mediatek/mt76/mt7921/mac.h | 8 + drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 22 +- drivers/net/wireless/mediatek/mt76/mt7921/mcu.h | 10 +- drivers/net/wireless/mediatek/mt76/mt7921/regs.h | 8 +- drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 +- .../net/wireless/realtek/rtl818x/rtl8187/rtl8225.c | 14 +- drivers/net/wireless/realtek/rtw88/fw.c | 7 +- drivers/net/wireless/realtek/rtw88/reg.h | 1 + drivers/net/wireless/rsi/rsi_91x_core.c | 2 + drivers/net/wireless/rsi/rsi_91x_hal.c | 10 +- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 74 ++---- drivers/net/wireless/rsi/rsi_91x_main.c | 17 +- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 24 +- drivers/net/wireless/rsi/rsi_91x_sdio.c | 5 +- drivers/net/wireless/rsi/rsi_91x_usb.c | 5 +- drivers/net/wireless/rsi/rsi_hal.h | 11 + drivers/net/wireless/rsi/rsi_main.h | 15 +- drivers/nfc/pn533/pn533.c | 6 +- drivers/nvdimm/btt.c | 1 - drivers/nvdimm/pmem.c | 13 +- drivers/nvme/host/multipath.c | 9 +- drivers/nvme/host/rdma.c | 2 + drivers/nvme/target/configfs.c | 2 + drivers/nvme/target/rdma.c | 24 ++ drivers/nvme/target/tcp.c | 16 ++ drivers/of/unittest.c | 16 +- drivers/opp/of.c | 2 +- drivers/pci/controller/cadence/pci-j721e.c | 2 +- drivers/pci/controller/cadence/pcie-cadence-plat.c | 2 + drivers/pci/controller/dwc/pcie-uniphier.c | 26 +-- drivers/pci/controller/pci-aardvark.c | 251 +++++++++++++++++--- drivers/pci/msi.c | 36 +-- drivers/pci/pci-bridge-emul.c | 13 ++ drivers/pci/pci.c | 8 + drivers/pci/quirks.c | 1 + drivers/phy/microchip/sparx5_serdes.c | 4 +- drivers/phy/qualcomm/phy-qcom-qmp.c | 2 +- drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 +- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 2 +- drivers/phy/ti/phy-gmii-sel.c | 2 + drivers/pinctrl/core.c | 2 + drivers/pinctrl/pinctrl-equilibrium.c | 7 +- drivers/pinctrl/renesas/core.c | 2 +- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 +- .../platform/surface/surface_aggregator_registry.c | 54 +++++ drivers/platform/x86/thinkpad_acpi.c | 2 +- drivers/platform/x86/wmi.c | 9 +- drivers/power/reset/at91-reset.c | 4 +- drivers/power/supply/bq27xxx_battery_i2c.c | 3 +- drivers/power/supply/max17040_battery.c | 2 + drivers/power/supply/max17042_battery.c | 12 +- drivers/power/supply/rt5033_battery.c | 2 +- drivers/regulator/s5m8767.c | 21 +- drivers/remoteproc/imx_rproc.c | 41 ++-- drivers/remoteproc/remoteproc_core.c | 8 +- drivers/remoteproc/remoteproc_coredump.c | 2 +- drivers/remoteproc/remoteproc_elf_loader.c | 4 +- drivers/rtc/rtc-ds1302.c | 7 + drivers/rtc/rtc-ds1390.c | 7 + drivers/rtc/rtc-mcp795.c | 7 + drivers/rtc/rtc-pcf2123.c | 9 + drivers/rtc/rtc-rv3032.c | 4 +- drivers/s390/char/tape_std.c | 3 +- drivers/s390/cio/css.c | 4 +- drivers/s390/cio/device_ops.c | 12 +- drivers/s390/crypto/ap_queue.c | 2 + drivers/scsi/csiostor/csio_lnode.c | 2 +- drivers/scsi/dc395x.c | 1 + drivers/scsi/hosts.c | 1 + drivers/scsi/lpfc/lpfc_els.c | 12 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 10 +- drivers/scsi/lpfc/lpfc_nvme.c | 5 +- drivers/scsi/lpfc/lpfc_scsi.c | 7 + drivers/scsi/lpfc/lpfc_sli.c | 101 ++++++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 11 +- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- drivers/scsi/pm8001/pm8001_sas.h | 3 +- drivers/scsi/pm8001/pm80xx_hwi.c | 53 ++++- drivers/scsi/qedf/qedf_main.c | 2 + drivers/scsi/qla2xxx/qla_attr.c | 24 +- drivers/scsi/qla2xxx/qla_edif.c | 259 ++++++++++++--------- drivers/scsi/qla2xxx/qla_edif.h | 3 +- drivers/scsi/qla2xxx/qla_edif_bsg.h | 2 +- drivers/scsi/qla2xxx/qla_gbl.h | 4 +- drivers/scsi/qla2xxx/qla_init.c | 77 ++++-- drivers/scsi/qla2xxx/qla_mr.c | 23 -- drivers/scsi/qla2xxx/qla_nvme.c | 14 +- drivers/scsi/qla2xxx/qla_os.c | 37 +-- drivers/scsi/qla2xxx/qla_target.c | 1 + drivers/scsi/scsi_error.c | 25 ++ drivers/scsi/scsi_ioctl.c | 2 + drivers/scsi/scsi_lib.c | 3 +- drivers/scsi/scsi_sysfs.c | 1 + drivers/scsi/ufs/ufshcd-pltfrm.c | 4 +- drivers/scsi/ufs/ufshcd.c | 186 +-------------- drivers/scsi/ufs/ufshcd.h | 14 -- drivers/scsi/ufs/ufshpb.c | 31 ++- drivers/scsi/ufs/ufshpb.h | 1 - drivers/soc/fsl/dpaa2-console.c | 1 + drivers/soc/fsl/dpio/dpio-service.c | 2 +- drivers/soc/fsl/dpio/qbman-portal.c | 9 +- drivers/soc/qcom/apr.c | 2 + drivers/soc/qcom/llcc-qcom.c | 2 +- drivers/soc/qcom/rpmhpd.c | 20 +- drivers/soc/qcom/socinfo.c | 4 +- drivers/soc/samsung/Kconfig | 1 + drivers/soc/tegra/pmc.c | 2 +- drivers/soundwire/bus.c | 2 +- drivers/soundwire/debugfs.c | 2 +- drivers/spi/atmel-quadspi.c | 2 +- drivers/spi/spi-bcm-qspi.c | 8 +- drivers/spi/spi-mtk-nor.c | 2 +- drivers/spi/spi-rpc-if.c | 4 +- drivers/spi/spi-stm32-qspi.c | 2 +- drivers/spi/spi.c | 41 ++++ drivers/staging/ks7010/Kconfig | 3 + drivers/staging/media/atomisp/i2c/atomisp-lm3554.c | 37 +-- drivers/staging/media/imx/imx-media-dev-common.c | 2 + drivers/staging/media/ipu3/ipu3-v4l2.c | 7 +- drivers/staging/media/rkvdec/rkvdec-h264.c | 5 +- drivers/staging/media/rkvdec/rkvdec.c | 40 ++-- drivers/staging/most/dim2/Makefile | 2 +- drivers/staging/most/dim2/dim2.c | 24 +- drivers/staging/most/dim2/sysfs.c | 49 ---- drivers/staging/most/dim2/sysfs.h | 11 - drivers/staging/r8188eu/core/rtw_mlme.c | 2 + drivers/target/target_core_tmr.c | 17 +- drivers/target/target_core_transport.c | 30 ++- .../intel/int340x_thermal/processor_thermal_mbox.c | 1 + drivers/thermal/qcom/Kconfig | 2 +- drivers/thermal/qcom/tsens.c | 29 ++- drivers/thermal/thermal_core.c | 16 +- drivers/tty/serial/8250/8250_dw.c | 2 +- drivers/tty/serial/8250/8250_port.c | 21 +- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 2 + drivers/tty/serial/imx.c | 4 +- drivers/tty/serial/serial_core.c | 16 +- drivers/tty/serial/xilinx_uartps.c | 3 +- drivers/usb/chipidea/core.c | 23 +- drivers/usb/dwc2/drd.c | 24 +- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 8 +- drivers/usb/gadget/legacy/hid.c | 4 +- drivers/usb/host/xhci-hub.c | 3 +- drivers/usb/host/xhci-pci.c | 16 ++ drivers/usb/misc/iowarrior.c | 8 +- drivers/usb/musb/Kconfig | 2 +- drivers/usb/serial/keyspan.c | 15 +- drivers/usb/typec/Kconfig | 4 +- drivers/vdpa/mlx5/net/mlx5_vnet.c | 1 - drivers/video/backlight/backlight.c | 6 - drivers/video/fbdev/chipsfb.c | 2 +- drivers/video/fbdev/efifb.c | 21 +- drivers/virtio/virtio_ring.c | 14 +- drivers/watchdog/Kconfig | 2 +- drivers/watchdog/f71808e_wdt.c | 4 +- drivers/xen/balloon.c | 86 +++++-- drivers/xen/xen-pciback/conf_space_capability.c | 2 +- fs/btrfs/disk-io.c | 3 +- fs/btrfs/reflink.c | 2 +- fs/btrfs/tree-log.c | 4 +- fs/btrfs/volumes.c | 14 +- fs/ceph/mdsmap.c | 4 - fs/cifs/cifsglob.h | 3 +- fs/cifs/connect.c | 21 +- fs/cifs/file.c | 35 ++- fs/cifs/fs_context.c | 8 + fs/cifs/fs_context.h | 1 + fs/crypto/fscrypt_private.h | 5 +- fs/crypto/hkdf.c | 11 +- fs/crypto/keysetup.c | 57 ++++- fs/erofs/decompressor.c | 1 - fs/erofs/zdata.c | 13 +- fs/erofs/zpvec.h | 13 +- fs/exfat/inode.c | 2 +- fs/ext4/extents.c | 63 +++-- fs/ext4/inode.c | 15 +- fs/ext4/super.c | 9 +- fs/f2fs/compress.c | 1 + fs/f2fs/inode.c | 2 +- fs/f2fs/namei.c | 2 +- fs/f2fs/super.c | 2 + fs/fuse/dev.c | 14 +- fs/gfs2/glock.c | 24 +- fs/io-wq.c | 88 +++++-- fs/io_uring.c | 4 +- fs/jfs/jfs_mount.c | 51 ++-- fs/ksmbd/Kconfig | 1 + fs/ksmbd/server.c | 1 + fs/ksmbd/smb2misc.c | 6 +- fs/ksmbd/smb2pdu.c | 11 +- fs/nfs/dir.c | 9 +- fs/nfs/direct.c | 2 +- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 4 +- fs/nfs/inode.c | 13 +- fs/nfs/nfs3xdr.c | 2 +- fs/nfs/nfs4idmap.c | 2 +- fs/nfs/nfs4proc.c | 15 +- fs/nfs/pnfs.h | 2 +- fs/nfs/pnfs_nfs.c | 6 +- fs/nfs/proc.c | 2 +- fs/nfs/write.c | 26 +-- fs/ocfs2/file.c | 8 +- fs/open.c | 16 +- fs/orangefs/dcache.c | 4 +- fs/overlayfs/copy_up.c | 23 +- fs/overlayfs/file.c | 16 +- fs/overlayfs/inode.c | 5 +- fs/proc/stat.c | 4 +- fs/proc/uptime.c | 14 +- fs/quota/quota_tree.c | 15 ++ fs/tracefs/inode.c | 3 +- include/drm/ttm/ttm_bo_api.h | 3 +- include/linux/blkdev.h | 2 - include/linux/bpf-cgroup.h | 1 + include/linux/console.h | 2 + include/linux/cpufreq.h | 2 +- include/linux/dma-buf.h | 2 +- include/linux/dsa/ocelot.h | 1 + include/linux/ethtool_netlink.h | 3 + include/linux/filter.h | 5 +- include/linux/fortify-string.h | 5 +- include/linux/kernel_stat.h | 1 + include/linux/leds.h | 2 +- include/linux/libata.h | 2 +- include/linux/msi.h | 2 +- include/linux/nfs_fs.h | 1 + include/linux/posix-timers.h | 2 + include/linux/rpmsg.h | 2 +- include/linux/sched.h | 1 + include/linux/sched/task.h | 3 +- include/linux/sched/task_stack.h | 4 + include/linux/seq_file.h | 2 +- include/linux/signal_types.h | 3 + include/linux/skmsg.h | 18 +- include/linux/surface_aggregator/controller.h | 4 +- include/linux/tpm.h | 1 + include/media/videobuf2-core.h | 37 +-- include/memory/renesas-rpc-if.h | 1 + include/net/inet_connection_sock.h | 2 +- include/net/llc.h | 4 +- include/net/neighbour.h | 12 +- include/net/sch_generic.h | 4 + include/net/sctp/sctp.h | 7 +- include/net/sock.h | 2 +- include/net/strparser.h | 20 +- include/net/tcp.h | 17 +- include/rdma/ib_verbs.h | 7 +- include/scsi/scsi_cmnd.h | 2 +- include/scsi/scsi_host.h | 1 + include/sound/soc-topology.h | 3 +- include/uapi/asm-generic/signal-defs.h | 1 + include/uapi/linux/ethtool_netlink.h | 4 +- include/uapi/linux/pci_regs.h | 6 + init/main.c | 4 +- kernel/bpf/trampoline.c | 6 +- kernel/bpf/verifier.c | 4 +- kernel/cgroup/cgroup.c | 31 ++- kernel/cgroup/rstat.c | 2 - kernel/debug/kdb/kdb_bt.c | 16 +- kernel/debug/kdb/kdb_main.c | 37 +-- kernel/debug/kdb/kdb_private.h | 4 +- kernel/debug/kdb/kdb_support.c | 118 ++-------- kernel/fork.c | 3 +- kernel/irq/msi.c | 4 +- kernel/kprobes.c | 3 +- kernel/locking/lockdep.c | 4 +- kernel/locking/rwsem.c | 53 +++-- kernel/power/energy_model.c | 23 +- kernel/power/swap.c | 7 +- kernel/rcu/rcutorture.c | 48 +++- kernel/rcu/tasks.h | 3 +- kernel/rcu/tree.c | 2 +- kernel/rcu/tree_exp.h | 2 +- kernel/rcu/tree_plugin.h | 8 +- kernel/sched/core.c | 62 +++-- kernel/scs.c | 1 + kernel/signal.c | 26 +-- kernel/time/posix-cpu-timers.c | 19 +- kernel/trace/ftrace.c | 23 +- kernel/trace/ring_buffer.c | 5 + kernel/trace/trace.c | 73 +++--- kernel/trace/trace.h | 3 + kernel/trace/trace_boot.c | 4 + kernel/trace/trace_dynevent.c | 2 +- kernel/trace/trace_event_perf.c | 6 +- kernel/trace/trace_events.c | 42 ++-- kernel/trace/trace_events_synth.c | 4 +- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_hwlat.c | 6 +- kernel/trace/trace_kprobe.c | 8 +- kernel/trace/trace_osnoise.c | 14 +- kernel/trace/trace_printk.c | 2 +- kernel/trace/trace_recursion_record.c | 4 +- kernel/trace/trace_stack.c | 6 +- kernel/trace/trace_stat.c | 6 +- kernel/trace/trace_uprobe.c | 4 +- kernel/trace/tracing_map.c | 40 ++-- kernel/workqueue.c | 15 +- lib/crypto/sm4.c | 4 +- lib/decompress_unxz.c | 2 +- lib/dynamic_debug.c | 12 + lib/iov_iter.c | 5 +- lib/test_bpf.c | 37 ++- lib/xz/xz_dec_lzma2.c | 21 +- lib/xz/xz_dec_stream.c | 6 +- mm/filemap.c | 1 - mm/memcontrol.c | 27 +-- mm/oom_kill.c | 23 +- mm/zsmalloc.c | 7 +- net/8021q/vlan.c | 3 - net/8021q/vlan_dev.c | 3 + net/9p/client.c | 2 + net/bluetooth/l2cap_sock.c | 10 +- net/bluetooth/sco.c | 36 +-- net/bridge/br_private.h | 2 + net/can/j1939/main.c | 7 + net/can/j1939/transport.c | 11 + net/core/dev.c | 2 + net/core/filter.c | 58 ++++- net/core/neighbour.c | 48 ++-- net/core/net-sysfs.c | 55 +++++ net/core/net_namespace.c | 4 + net/core/skmsg.c | 43 +++- net/core/stream.c | 3 - net/dccp/dccp.h | 2 +- net/dccp/proto.c | 14 +- net/dsa/port.c | 2 + net/dsa/switch.c | 4 +- net/dsa/tag_ocelot.c | 3 + net/ethtool/pause.c | 3 +- net/ipv4/af_inet.c | 16 +- net/ipv4/inet_connection_sock.c | 4 +- net/ipv4/inet_hashtables.c | 2 +- net/ipv4/proc.c | 2 +- net/ipv4/tcp.c | 40 +++- net/ipv4/tcp_bpf.c | 48 +++- net/ipv6/addrconf.c | 3 + net/ipv6/af_inet6.c | 21 +- net/ipv6/udp.c | 2 +- net/mac80211/s1g.c | 8 +- net/mctp/af_mctp.c | 13 ++ net/mptcp/options.c | 8 +- net/mptcp/protocol.c | 43 +++- net/netfilter/nf_conntrack_proto_udp.c | 7 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netfilter/nft_dynset.c | 11 +- net/rxrpc/rtt.c | 2 +- net/sched/sch_generic.c | 9 + net/sched/sch_mq.c | 24 ++ net/sched/sch_mqprio.c | 23 ++ net/sched/sch_taprio.c | 27 ++- net/sctp/output.c | 13 +- net/sctp/transport.c | 11 +- net/smc/af_smc.c | 18 +- net/strparser/strparser.c | 10 +- net/sunrpc/addr.c | 40 ++-- net/sunrpc/xprt.c | 28 +-- net/vmw_vsock/af_vsock.c | 2 + net/wireless/core.c | 10 + samples/bpf/xdp_redirect_cpu_user.c | 6 +- samples/kprobes/kretprobe_example.c | 2 +- scripts/leaking_addresses.pl | 3 +- security/apparmor/label.c | 4 +- security/integrity/evm/evm_main.c | 2 +- security/integrity/ima/ima_policy.c | 27 ++- security/selinux/ss/services.c | 162 ++++++------- security/smack/smackfs.c | 11 +- sound/core/memalloc.c | 7 +- sound/core/oss/mixer_oss.c | 44 +++- sound/core/timer.c | 17 +- sound/firewire/oxfw/oxfw-stream.c | 7 +- sound/firewire/oxfw/oxfw.c | 8 + sound/firewire/oxfw/oxfw.h | 5 + sound/pci/hda/hda_intel.c | 52 ++--- sound/pci/hda/patch_realtek.c | 36 +++ sound/pci/rme9652/hdsp.c | 41 ++-- sound/pci/rme9652/rme9652.c | 41 ++-- sound/soc/codecs/cs42l42.c | 27 ++- sound/soc/codecs/wcd9335.c | 2 +- sound/soc/sh/rcar/core.c | 1 + sound/soc/sof/topology.c | 9 + sound/soc/tegra/tegra_asoc_machine.c | 60 ++++- sound/soc/tegra/tegra_asoc_machine.h | 1 + sound/synth/emux/emux.c | 2 +- sound/usb/6fire/comm.c | 2 +- sound/usb/6fire/firmware.c | 6 +- sound/usb/card.h | 1 + sound/usb/endpoint.c | 7 +- sound/usb/format.c | 1 + sound/usb/line6/driver.c | 14 +- sound/usb/line6/driver.h | 2 +- sound/usb/line6/podhd.c | 6 +- sound/usb/line6/toneport.c | 2 +- sound/usb/misc/ua101.c | 4 +- sound/usb/quirks.c | 1 + tools/arch/x86/lib/insn.c | 5 +- tools/bpf/bpftool/prog.c | 16 +- tools/include/asm-generic/unaligned.h | 23 ++ tools/lib/bpf/bpf.c | 4 +- tools/lib/bpf/bpf_core_read.h | 2 +- tools/lib/bpf/btf.c | 22 +- tools/lib/bpf/libbpf.c | 8 +- tools/lib/bpf/skel_internal.h | 6 +- tools/objtool/arch/x86/decode.c | 20 ++ tools/objtool/check.c | 159 +++++++------ tools/objtool/include/objtool/arch.h | 1 + tools/perf/util/bpf-event.c | 4 +- tools/perf/util/intel-pt-decoder/Build | 2 + .../testing/selftests/bpf/prog_tests/perf_buffer.c | 4 +- tools/testing/selftests/bpf/prog_tests/sk_lookup.c | 4 +- tools/testing/selftests/bpf/prog_tests/test_ima.c | 3 +- tools/testing/selftests/bpf/progs/strobemeta.h | 11 + tools/testing/selftests/bpf/test_progs.c | 4 +- .../selftests/bpf/test_xdp_redirect_multi.sh | 62 ++--- .../testing/selftests/bpf/verifier/array_access.c | 2 +- tools/testing/selftests/bpf/xdp_redirect_multi.c | 4 +- tools/testing/selftests/core/close_range_test.c | 2 +- tools/testing/selftests/kvm/lib/x86_64/svm.c | 14 +- .../selftests/kvm/x86_64/mmio_warning_test.c | 2 +- tools/testing/selftests/net/Makefile | 9 +- tools/testing/selftests/net/fib_nexthops.sh | 1 + .../selftests/net/forwarding/bridge_igmp.sh | 12 +- .../testing/selftests/net/forwarding/bridge_mld.sh | 12 +- tools/testing/selftests/net/gre_gso.sh | 9 +- tools/testing/selftests/net/mptcp/mptcp_join.sh | 2 +- tools/testing/selftests/net/udpgso_bench_rx.c | 11 +- tools/testing/selftests/sched/cs_prctl_test.c | 28 ++- tools/tracing/latency/latency-collector.c | 2 +- 1028 files changed, 8826 insertions(+), 5203 deletions(-)
From: Mathias Nyman mathias.nyman@linux.intel.com
commit e1959faf085b004e6c3afaaaa743381f00e7c015 upstream.
Some USB 3.1 enumeration issues were reported after the hub driver removed the minimum 100ms limit for the power-on-good delay.
Since commit 90d28fb53d4a ("usb: core: reduce power-on-good delay time of root hub") the hub driver sets the power-on-delay based on the bPwrOn2PwrGood value in the hub descriptor.
xhci driver has a 20ms bPwrOn2PwrGood value for both roothubs based on xhci spec section 5.4.8, but it's clearly not enough for the USB 3.1 devices, causing enumeration issues.
Tests indicate full 100ms delay is needed.
Reported-by: Walt Jr. Brake mr.yming81@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Fixes: 90d28fb53d4a ("usb: core: reduce power-on-good delay time of root hub") Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20211105160036.549516-1-mathias.nyman@linux.intel.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -257,7 +257,6 @@ static void xhci_common_hub_descriptor(s { u16 temp;
- desc->bPwrOn2PwrGood = 10; /* xhci section 5.4.9 says 20ms max */ desc->bHubContrCurrent = 0;
desc->bNbrPorts = ports; @@ -292,6 +291,7 @@ static void xhci_usb2_hub_descriptor(str desc->bDescriptorType = USB_DT_HUB; temp = 1 + (ports / 8); desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * temp; + desc->bPwrOn2PwrGood = 10; /* xhci section 5.4.8 says 20ms */
/* The Device Removable bits are reported on a byte granularity. * If the port doesn't exist within that byte, the bit is set to 0. @@ -344,6 +344,7 @@ static void xhci_usb3_hub_descriptor(str xhci_common_hub_descriptor(xhci, desc, ports); desc->bDescriptorType = USB_DT_SS_HUB; desc->bDescLength = USB_DT_SS_HUB_SIZE; + desc->bPwrOn2PwrGood = 50; /* usb 3.1 may fail if less than 100ms */
/* header decode latency should be zero for roothubs, * see section 4.23.5.2.
From: Nehal Bakulchandra Shah Nehal-Bakulchandra.shah@amd.com
commit 660a92a59b9e831a0407e41ff62875656d30006e upstream.
AMD's Yellow Carp platform supports runtime power management for XHCI Controllers, so enable the same by default for all XHCI Controllers.
[ regrouped and aligned the PCI_DEVICE_ID definitions -Mathias]
Cc: stable stable@vger.kernel.org Reviewed-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Reviewed-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Nehal Bakulchandra Shah Nehal-Bakulchandra.shah@amd.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20211014121200.75433-2-mathias.nyman@linux.intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-pci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
--- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -65,6 +65,13 @@ #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc +#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 0x161a +#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 0x161b +#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 0x161d +#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 0x161e +#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 0x15d6 +#define PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6 0x15d7 + #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 @@ -317,6 +324,15 @@ static void xhci_pci_quirks(struct devic pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_4)) xhci->quirks |= XHCI_NO_SOFT_RETRY;
+ if (pdev->vendor == PCI_VENDOR_ID_AMD && + (pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_1 || + pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_2 || + pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_3 || + pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_4 || + pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_5 || + pdev->device == PCI_DEVICE_ID_AMD_YELLOW_CARP_XHCI_6)) + xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + if (xhci->quirks & XHCI_RESET_ON_RESUME) xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "QUIRK: Resetting on resume");
From: Johan Hovold johan@kernel.org
commit 744d0090a5f6dfa4c81b53402ccdf08313100429 upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: 487358627825 ("Input: iforce - use DMA-safe buffer when getting IDs from USB") Signed-off-by: Johan Hovold johan@kernel.org Cc: stable@vger.kernel.org # 5.3 Link: https://lore.kernel.org/r/20211025115501.5190-1-johan@kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/input/joystick/iforce/iforce-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -92,7 +92,7 @@ static int iforce_usb_get_id(struct ifor id, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE, - 0, 0, buf, IFORCE_MAX_LENGTH, HZ); + 0, 0, buf, IFORCE_MAX_LENGTH, 1000); if (status < 0) { dev_err(&iforce_usb->intf->dev, "usb_submit_urb failed: %d\n", status);
From: Phoenix Huang phoenix@emc.com.tw
commit be896bd3b72b44126c55768f14c22a8729b0992e upstream.
Some firmwares occasionally report bogus data from trackpoint, with X or Y displacement being too large (outside of [-127, 127] range). Let's drop such packets so that we do not generate jumps.
Signed-off-by: Phoenix Huang phoenix@emc.com.tw Tested-by: Yufei Du yufeidu@cs.unc.edu Link: https://lore.kernel.org/r/20210729010940.5752-1-phoenix@emc.com.tw Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/input/mouse/elantech.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -517,6 +517,19 @@ static void elantech_report_trackpoint(s case 0x16008020U: case 0x26800010U: case 0x36808000U: + + /* + * This firmware misreport coordinates for trackpoint + * occasionally. Discard packets outside of [-127, 127] range + * to prevent cursor jumps. + */ + if (packet[4] == 0x80 || packet[5] == 0x80 || + packet[1] >> 7 == packet[4] >> 7 || + packet[2] >> 7 == packet[5] >> 7) { + elantech_debug("discarding packet [%6ph]\n", packet); + break; + + } x = packet[4] - (int)((packet[1]^0x80) << 1); y = (int)((packet[2]^0x80) << 1) - packet[5];
From: Takashi Iwai tiwai@suse.de
commit 16e28abb7290c4ca3b3a0f333ba067f34bb18c86 upstream.
Fujitsu Lifebook T725 laptop requires, like a few other similar models, the nomux and notimeout options to probe the touchpad properly. This patch adds the corresponding quirk entries.
BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1191980 Tested-by: Neal Gompa ngompa13@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/r/20211103070019.13374-1-tiwai@suse.de Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/input/serio/i8042-x86ia64io.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -273,6 +273,13 @@ static const struct dmi_system_id __init }, }, { + /* Fujitsu Lifebook T725 laptop */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), + }, + }, + { /* Fujitsu Lifebook U745 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), @@ -841,6 +848,13 @@ static const struct dmi_system_id __init }, }, { + /* Fujitsu Lifebook T725 laptop */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), + }, + }, + { /* Fujitsu U574 laptop */ /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ .matches = {
From: Damien Le Moal damien.lemoal@opensource.wdc.com
commit 68dbbe7d5b4fde736d104cbbc9a2fce875562012 upstream.
Some ATA drives are very slow to respond to READ_LOG_EXT and READ_LOG_DMA_EXT commands issued from ata_dev_configure() when the device is revalidated right after resuming a system or inserting the ATA adapter driver (e.g. ahci). The default 5s timeout (ATA_EH_CMD_DFL_TIMEOUT) used for these commands is too short, causing errors during the device configuration. Ex:
... ata9: SATA max UDMA/133 abar m524288@0x9d200000 port 0x9d200400 irq 209 ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300) ata9.00: ATA-9: XXX XXXXXXXXXXXXXXX, XXXXXXXX, max UDMA/133 ata9.00: qc timeout (cmd 0x2f) ata9.00: Read log page 0x00 failed, Emask 0x4 ata9.00: Read log page 0x00 failed, Emask 0x40 ata9.00: NCQ Send/Recv Log not supported ata9.00: Read log page 0x08 failed, Emask 0x40 ata9.00: 27344764928 sectors, multi 16: LBA48 NCQ (depth 32), AA ata9.00: Read log page 0x00 failed, Emask 0x40 ata9.00: ATA Identify Device Log not supported ata9.00: failed to set xfermode (err_mask=0x40) ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300) ata9.00: configured for UDMA/133 ...
The timeout error causes a soft reset of the drive link, followed in most cases by a successful revalidation as that give enough time to the drive to become fully ready to quickly process the read log commands. However, in some cases, this also fails resulting in the device being dropped.
Fix this by using adding the ata_eh_revalidate_timeouts entries for the READ_LOG_EXT and READ_LOG_DMA_EXT commands. This defines a timeout increased to 15s, retriable one time.
Reported-by: Geert Uytterhoeven geert@linux-m68k.org Tested-by: Geert Uytterhoeven geert+renesas@glider.be Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal damien.lemoal@opensource.wdc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-eh.c | 8 ++++++++ include/linux/libata.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -93,6 +93,12 @@ static const unsigned long ata_eh_identi ULONG_MAX, };
+static const unsigned long ata_eh_revalidate_timeouts[] = { + 15000, /* Some drives are slow to read log pages when waking-up */ + 15000, /* combined time till here is enough even for media access */ + ULONG_MAX, +}; + static const unsigned long ata_eh_flush_timeouts[] = { 15000, /* be generous with flush */ 15000, /* ditto */ @@ -129,6 +135,8 @@ static const struct ata_eh_cmd_timeout_e ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), .timeouts = ata_eh_identify_timeouts, }, + { .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT), + .timeouts = ata_eh_revalidate_timeouts, }, { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), .timeouts = ata_eh_other_timeouts, }, { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -394,7 +394,7 @@ enum { /* This should match the actual table size of * ata_eh_cmd_timeout_table in libata-eh.c. */ - ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 6, + ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 7,
/* Horkage types. May be set by libata or controller on drives (some horkage may be drive/controller pair dependent */
From: Jan Kara jack@suse.cz
commit 839b63860eb3835da165642923120d305925561d upstream.
Patch series "ocfs2: Truncate data corruption fix".
As further testing has shown, commit 5314454ea3f ("ocfs2: fix data corruption after conversion from inline format") didn't fix all the data corruption issues the customer started observing after 6dbf7bb55598 ("fs: Don't invalidate page buffers in block_write_full_page()") This time I have tracked them down to two bugs in ocfs2 truncation code.
One bug (truncating page cache before clearing tail cluster and setting i_size) could cause data corruption even before 6dbf7bb55598, but before that commit it needed a race with page fault, after 6dbf7bb55598 it started to be pretty deterministic.
Another bug (zeroing pages beyond old i_size) used to be harmless inefficiency before commit 6dbf7bb55598. But after commit 6dbf7bb55598 in combination with the first bug it resulted in deterministic data corruption.
Although fixing only the first problem is needed to stop data corruption, I've fixed both issues to make the code more robust.
This patch (of 2):
ocfs2_truncate_file() did unmap invalidate page cache pages before zeroing partial tail cluster and setting i_size. Thus some pages could be left (and likely have left if the cluster zeroing happened) in the page cache beyond i_size after truncate finished letting user possibly see stale data once the file was extended again. Also the tail cluster zeroing was not guaranteed to finish before truncate finished causing possible stale data exposure. The problem started to be particularly easy to hit after commit 6dbf7bb55598 "fs: Don't invalidate page buffers in block_write_full_page()" stopped invalidation of pages beyond i_size from page writeback path.
Fix these problems by unmapping and invalidating pages in the page cache after the i_size is reduced and tail cluster is zeroed out.
Link: https://lkml.kernel.org/r/20211025150008.29002-1-jack@suse.cz Link: https://lkml.kernel.org/r/20211025151332.11301-1-jack@suse.cz Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") Signed-off-by: Jan Kara jack@suse.cz Reviewed-by: Joseph Qi joseph.qi@linux.alibaba.com Cc: Mark Fasheh mark@fasheh.com Cc: Joel Becker jlbec@evilplan.org Cc: Junxiao Bi junxiao.bi@oracle.com Cc: Changwei Ge gechangwei@live.cn Cc: Gang He ghe@suse.com Cc: Jun Piao piaojun@huawei.com 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 --- fs/ocfs2/file.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -476,10 +476,11 @@ int ocfs2_truncate_file(struct inode *in * greater than page size, so we have to truncate them * anyway. */ - unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); - truncate_inode_pages(inode->i_mapping, new_i_size);
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { + unmap_mapping_range(inode->i_mapping, + new_i_size + PAGE_SIZE - 1, 0, 1); + truncate_inode_pages(inode->i_mapping, new_i_size); status = ocfs2_truncate_inline(inode, di_bh, new_i_size, i_size_read(inode), 1); if (status) @@ -498,6 +499,9 @@ int ocfs2_truncate_file(struct inode *in goto bail_unlock_sem; }
+ unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); + truncate_inode_pages(inode->i_mapping, new_i_size); + status = ocfs2_commit_truncate(osb, inode, di_bh); if (status < 0) { mlog_errno(status);
From: Tadeusz Struk tadeusz.struk@linaro.org
commit 20aaef52eb08f1d987d46ad26edb8f142f74d83a upstream.
Need to make sure the command size is valid before copying the command from user space.
Link: https://lore.kernel.org/r/20211103170659.22151-1-tadeusz.struk@linaro.org Cc: Bart Van Assche bvanassche@acm.org Cc: Christoph Hellwig hch@lst.de Cc: James E.J. Bottomley jejb@linux.ibm.com Cc: Martin K. Petersen martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # 5.15, 5.14, 5.10 Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/scsi_ioctl.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -347,6 +347,8 @@ static int scsi_fill_sghdr_rq(struct scs { struct scsi_request *req = scsi_req(rq);
+ if (hdr->cmd_len < 6) + return -EMSGSIZE; if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) return -EFAULT; if (!scsi_cmd_allowed(req->cmd, mode))
From: Ewan D. Milne emilne@redhat.com
commit 5ae17501bc62a49b0b193dcce003f16375f16654 upstream.
The changes to issue the abort from the scmd->abort_work instead of the EH thread introduced a problem if eh_deadline is used. If aborting the command(s) is successful, and there are never any scmds added to the shost->eh_cmd_q, there is no code path which will reset the ->last_reset value back to zero.
The effect of this is that after a successful abort with no EH thread activity, a subsequent timeout, perhaps a long time later, might immediately be considered past a user-set eh_deadline time, and the host will be reset with no attempt at recovery.
Fix this by resetting ->last_reset back to zero in scmd_eh_abort_handler() if it is determined that the EH thread will not run to do this.
Thanks to Gopinath Marappan for investigating this problem.
Link: https://lore.kernel.org/r/20211029194311.17504-2-emilne@redhat.com Fixes: e494f6a72839 ("[SCSI] improved eh timeout handler") Cc: stable@vger.kernel.org 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/hosts.c | 1 + drivers/scsi/scsi_error.c | 25 +++++++++++++++++++++++++ drivers/scsi/scsi_lib.c | 1 + include/scsi/scsi_cmnd.h | 2 +- include/scsi/scsi_host.h | 1 + 5 files changed, 29 insertions(+), 1 deletion(-)
--- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -388,6 +388,7 @@ struct Scsi_Host *scsi_host_alloc(struct shost->shost_state = SHOST_CREATED; INIT_LIST_HEAD(&shost->__devices); INIT_LIST_HEAD(&shost->__targets); + INIT_LIST_HEAD(&shost->eh_abort_list); INIT_LIST_HEAD(&shost->eh_cmd_q); INIT_LIST_HEAD(&shost->starved_list); init_waitqueue_head(&shost->host_wait); --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -135,6 +135,23 @@ static bool scsi_eh_should_retry_cmd(str return true; }
+static void scsi_eh_complete_abort(struct scsi_cmnd *scmd, struct Scsi_Host *shost) +{ + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + list_del_init(&scmd->eh_entry); + /* + * If the abort succeeds, and there is no further + * EH action, clear the ->last_reset time. + */ + if (list_empty(&shost->eh_abort_list) && + list_empty(&shost->eh_cmd_q)) + if (shost->eh_deadline != -1) + shost->last_reset = 0; + spin_unlock_irqrestore(shost->host_lock, flags); +} + /** * scmd_eh_abort_handler - Handle command aborts * @work: command to be aborted. @@ -152,6 +169,7 @@ scmd_eh_abort_handler(struct work_struct container_of(work, struct scsi_cmnd, abort_work.work); struct scsi_device *sdev = scmd->device; enum scsi_disposition rtn; + unsigned long flags;
if (scsi_host_eh_past_deadline(sdev->host)) { SCSI_LOG_ERROR_RECOVERY(3, @@ -175,12 +193,14 @@ scmd_eh_abort_handler(struct work_struct SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_WARNING, scmd, "retry aborted command\n")); + scsi_eh_complete_abort(scmd, sdev->host); scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY); return; } else { SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_WARNING, scmd, "finish aborted command\n")); + scsi_eh_complete_abort(scmd, sdev->host); scsi_finish_command(scmd); return; } @@ -193,6 +213,9 @@ scmd_eh_abort_handler(struct work_struct } }
+ spin_lock_irqsave(sdev->host->host_lock, flags); + list_del_init(&scmd->eh_entry); + spin_unlock_irqrestore(sdev->host->host_lock, flags); scsi_eh_scmd_add(scmd); }
@@ -223,6 +246,8 @@ scsi_abort_command(struct scsi_cmnd *scm spin_lock_irqsave(shost->host_lock, flags); if (shost->eh_deadline != -1 && !shost->last_reset) shost->last_reset = jiffies; + BUG_ON(!list_empty(&scmd->eh_entry)); + list_add_tail(&scmd->eh_entry, &shost->eh_abort_list); spin_unlock_irqrestore(shost->host_lock, flags);
scmd->eh_eflags |= SCSI_EH_ABORT_SCHEDULED; --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1143,6 +1143,7 @@ void scsi_init_command(struct scsi_devic cmd->sense_buffer = buf; cmd->prot_sdb = prot; cmd->flags = flags; + INIT_LIST_HEAD(&cmd->eh_entry); INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); cmd->jiffies_at_alloc = jiffies_at_alloc; cmd->retries = retries; --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -68,7 +68,7 @@ struct scsi_pointer { struct scsi_cmnd { struct scsi_request req; struct scsi_device *device; - struct list_head eh_entry; /* entry for the host eh_cmd_q */ + struct list_head eh_entry; /* entry for the host eh_abort_list/eh_cmd_q */ struct delayed_work abort_work;
struct rcu_head rcu; --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -556,6 +556,7 @@ struct Scsi_Host {
struct mutex scan_mutex;/* serialize scanning activity */
+ struct list_head eh_abort_list; struct list_head eh_cmd_q; struct task_struct * ehandler; /* Error recovery thread. */ struct completion * eh_action; /* Wait for specific actions on the
From: Tadeusz Struk tadeusz.struk@linaro.org
commit 703535e6ae1e94c89a9c1396b4c7b6b41160ef0c upstream.
No need to deduce command size in scsi_setup_scsi_cmnd() anymore as appropriate checks have been added to scsi_fill_sghdr_rq() function and the cmd_len should never be zero here. The code to do that wasn't correct anyway, as it used uninitialized cmd->cmnd, which caused a null-ptr-deref if the command size was zero as in the trace below. Fix this by removing the unneeded code.
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 PID: 1822 Comm: repro Not tainted 5.15.0 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/01/2014 Call Trace: blk_mq_dispatch_rq_list+0x7c7/0x12d0 __blk_mq_sched_dispatch_requests+0x244/0x380 blk_mq_sched_dispatch_requests+0xf0/0x160 __blk_mq_run_hw_queue+0xe8/0x160 __blk_mq_delay_run_hw_queue+0x252/0x5d0 blk_mq_run_hw_queue+0x1dd/0x3b0 blk_mq_sched_insert_request+0x1ff/0x3e0 blk_execute_rq_nowait+0x173/0x1e0 blk_execute_rq+0x15c/0x540 sg_io+0x97c/0x1370 scsi_ioctl+0xe16/0x28e0 sd_ioctl+0x134/0x170 blkdev_ioctl+0x362/0x6e0 block_ioctl+0xb0/0xf0 vfs_ioctl+0xa7/0xf0 do_syscall_64+0x3d/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae ---[ end trace 8b086e334adef6d2 ]--- Kernel panic - not syncing: Fatal exception
Link: https://lore.kernel.org/r/20211103170659.22151-2-tadeusz.struk@linaro.org Fixes: 2ceda20f0a99 ("scsi: core: Move command size detection out of the fast path") Cc: Bart Van Assche bvanassche@acm.org Cc: Christoph Hellwig hch@lst.de Cc: James E.J. Bottomley jejb@linux.ibm.com Cc: Martin K. Petersen martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org # 5.15, 5.14, 5.10 Reported-by: syzbot+5516b30f5401d4dcbcae@syzkaller.appspotmail.com Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Tadeusz Struk tadeusz.struk@linaro.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/scsi_lib.c | 2 -- 1 file changed, 2 deletions(-)
--- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1175,8 +1175,6 @@ static blk_status_t scsi_setup_scsi_cmnd }
cmd->cmd_len = scsi_req(req)->cmd_len; - if (cmd->cmd_len == 0) - cmd->cmd_len = scsi_command_size(cmd->cmnd); cmd->cmnd = scsi_req(req)->cmd; cmd->transfersize = blk_rq_bytes(req); cmd->allowed = scsi_req(req)->retries;
From: James Smart jsmart2021@gmail.com
commit 982fc3965d1350d3332e04046b0e101006184ba9 upstream.
In a rarely executed path, FLOGI failure, there is a refcounting error. If FLOGI completed with an error, typically a timeout, the initial completion handler would remove the job reference. However, the job completion isn't the actual end of the job/exchange as the timeout usually initiates an ABTS, and upon that ABTS completion, a final completion is sent. The driver removes the reference again in the final completion. Thus the imbalance.
In the buggy cases, if there was a link bounce while the delayed response is outstanding, the fport node may be referenced again but there was no additional reference as it is already present. The delayed completion then occurs and removes the last reference freeing the node and causing issues in the link up processed that is using the node.
Fix this scenario by removing the snippet that removed the reference in the initial FLOGI completion. The bad snippet was poorly trying to identify the FLOGI as OK to do so by realizing the node was not registered with either SCSI or NVMe transport.
Link: https://lore.kernel.org/r/20210910233159.115896-3-jsmart2021@gmail.com Fixes: 618e2ee146d4 ("scsi: lpfc: Fix FLOGI failure due to accessing a freed node") Cc: stable@vger.kernel.org # v5.13+ Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/lpfc/lpfc_els.c | 11 +++++------ drivers/scsi/lpfc/lpfc_hbadisc.c | 10 ++++++---- drivers/scsi/lpfc/lpfc_nvme.c | 5 +++-- 3 files changed, 14 insertions(+), 12 deletions(-)
--- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1059,9 +1059,10 @@ stop_rr_fcf_flogi:
lpfc_printf_vlog(vport, KERN_WARNING, LOG_TRACE_EVENT, "0150 FLOGI failure Status:x%x/x%x " - "xri x%x TMO:x%x\n", + "xri x%x TMO:x%x refcnt %d\n", irsp->ulpStatus, irsp->un.ulpWord[4], - cmdiocb->sli4_xritag, irsp->ulpTimeout); + cmdiocb->sli4_xritag, irsp->ulpTimeout, + kref_read(&ndlp->kref));
/* If this is not a loop open failure, bail out */ if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT && @@ -1122,12 +1123,12 @@ stop_rr_fcf_flogi: /* FLOGI completes successfully */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0101 FLOGI completes successfully, I/O tag:x%x, " - "xri x%x Data: x%x x%x x%x x%x x%x x%x x%x\n", + "xri x%x Data: x%x x%x x%x x%x x%x x%x x%x %d\n", cmdiocb->iotag, cmdiocb->sli4_xritag, irsp->un.ulpWord[4], sp->cmn.e_d_tov, sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution, vport->port_state, vport->fc_flag, - sp->cmn.priority_tagging); + sp->cmn.priority_tagging, kref_read(&ndlp->kref));
if (sp->cmn.priority_tagging) vport->vmid_flag |= LPFC_VMID_ISSUE_QFPA; @@ -1205,8 +1206,6 @@ flogifail: phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock);
- if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) - lpfc_nlp_put(ndlp); if (!lpfc_error_lost_link(irsp)) { /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4449,8 +4449,9 @@ lpfc_register_remote_port(struct lpfc_vp fc_remote_port_rolechg(rport, rport_ids.roles);
lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "3183 %s rport x%px DID x%x, role x%x\n", - __func__, rport, rport->port_id, rport->roles); + "3183 %s rport x%px DID x%x, role x%x refcnt %d\n", + __func__, rport, rport->port_id, rport->roles, + kref_read(&ndlp->kref));
if ((rport->scsi_target_id != -1) && (rport->scsi_target_id < LPFC_MAX_TARGET)) { @@ -4475,8 +4476,9 @@ lpfc_unregister_remote_port(struct lpfc_
lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, "3184 rport unregister x%06x, rport x%px " - "xptflg x%x\n", - ndlp->nlp_DID, rport, ndlp->fc4_xpt_flags); + "xptflg x%x refcnt %d\n", + ndlp->nlp_DID, rport, ndlp->fc4_xpt_flags, + kref_read(&ndlp->kref));
fc_remote_port_delete(rport); lpfc_nlp_put(ndlp); --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -209,8 +209,9 @@ lpfc_nvme_remoteport_delete(struct nvme_ * calling state machine to remove the node. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6146 remoteport delete of remoteport x%px\n", - remoteport); + "6146 remoteport delete of remoteport x%px, ndlp x%px " + "DID x%x xflags x%x\n", + remoteport, ndlp, ndlp->nlp_DID, ndlp->fc4_xpt_flags); spin_lock_irq(&ndlp->lock);
/* The register rebind might have occurred before the delete
From: James Smart jsmart2021@gmail.com
commit cd8a36a90babf958082b87bc6b4df5dd70901eba upstream.
A prior patch inadvertently caused lpfc_sli_sum_iocb() to exclude counting of outstanding aborted I/Os and ABORT IOCBs. Thus, lpfc_reset_flush_io_context() called from any TMF routine does not properly wait to flush all outstanding FCP IOCBs leading to a block layer crash on an invalid scsi_cmnd->request pointer.
kernel BUG at ../block/blk-core.c:1489! RIP: 0010:blk_requeue_request+0xaf/0xc0 ... Call Trace: <IRQ> __scsi_queue_insert+0x90/0xe0 [scsi_mod] blk_done_softirq+0x7e/0x90 __do_softirq+0xd2/0x280 irq_exit+0xd5/0xe0 do_IRQ+0x4c/0xd0 common_interrupt+0x87/0x87 </IRQ>
Fix by separating out the LPFC_IO_FCP, LPFC_IO_ON_TXCMPLQ, LPFC_DRIVER_ABORTED, and CMD_ABORT_XRI_CN || CMD_CLOSE_XRI_CN checks into a new lpfc_sli_validate_fcp_iocb_for_abort() routine when determining to build an ABORT iocb.
Restore lpfc_reset_flush_io_context() functionality by including counting of outstanding aborted IOCBs and ABORT IOCBs in lpfc_sli_sum_iocb().
Link: https://lore.kernel.org/r/20210910233159.115896-9-jsmart2021@gmail.com Fixes: e1364711359f ("scsi: lpfc: Fix illegal memory access on Abort IOCBs") Cc: stable@vger.kernel.org # v5.12+ Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/lpfc/lpfc_sli.c | 101 +++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 23 deletions(-)
--- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -12488,15 +12488,54 @@ lpfc_sli_hba_iocb_abort(struct lpfc_hba }
/** - * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN + * lpfc_sli_validate_fcp_iocb_for_abort - filter iocbs appropriate for FCP aborts + * @iocbq: Pointer to iocb object. + * @vport: Pointer to driver virtual port object. + * + * This function acts as an iocb filter for functions which abort FCP iocbs. + * + * Return values + * -ENODEV, if a null iocb or vport ptr is encountered + * -EINVAL, if the iocb is not an FCP I/O, not on the TX cmpl queue, premarked as + * driver already started the abort process, or is an abort iocb itself + * 0, passes criteria for aborting the FCP I/O iocb + **/ +static int +lpfc_sli_validate_fcp_iocb_for_abort(struct lpfc_iocbq *iocbq, + struct lpfc_vport *vport) +{ + IOCB_t *icmd = NULL; + + /* No null ptr vports */ + if (!iocbq || iocbq->vport != vport) + return -ENODEV; + + /* iocb must be for FCP IO, already exists on the TX cmpl queue, + * can't be premarked as driver aborted, nor be an ABORT iocb itself + */ + icmd = &iocbq->iocb; + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || + (iocbq->iocb_flag & LPFC_DRIVER_ABORTED) || + (icmd->ulpCommand == CMD_ABORT_XRI_CN || + icmd->ulpCommand == CMD_CLOSE_XRI_CN)) + return -EINVAL; + + return 0; +} + +/** + * lpfc_sli_validate_fcp_iocb - validate commands associated with a SCSI target * @iocbq: Pointer to driver iocb object. * @vport: Pointer to driver virtual port object. * @tgt_id: SCSI ID of the target. * @lun_id: LUN ID of the scsi device. * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST * - * This function acts as an iocb filter for functions which abort or count - * all FCP iocbs pending on a lun/SCSI target/SCSI host. It will return + * This function acts as an iocb filter for validating a lun/SCSI target/SCSI + * host. + * + * It will return * 0 if the filtering criteria is met for the given iocb and will return * 1 if the filtering criteria is not met. * If ctx_cmd == LPFC_CTX_LUN, the function returns 0 only if the @@ -12515,22 +12554,8 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_i lpfc_ctx_cmd ctx_cmd) { struct lpfc_io_buf *lpfc_cmd; - IOCB_t *icmd = NULL; int rc = 1;
- if (!iocbq || iocbq->vport != vport) - return rc; - - if (!(iocbq->iocb_flag & LPFC_IO_FCP) || - !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || - iocbq->iocb_flag & LPFC_DRIVER_ABORTED) - return rc; - - icmd = &iocbq->iocb; - if (icmd->ulpCommand == CMD_ABORT_XRI_CN || - icmd->ulpCommand == CMD_CLOSE_XRI_CN) - return rc; - lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq);
if (lpfc_cmd->pCmd == NULL) @@ -12585,17 +12610,33 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vpo { struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *iocbq; + IOCB_t *icmd = NULL; int sum, i; + unsigned long iflags;
- spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i];
- if (lpfc_sli_validate_fcp_iocb (iocbq, vport, tgt_id, lun_id, - ctx_cmd) == 0) + if (!iocbq || iocbq->vport != vport) + continue; + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ)) + continue; + + /* Include counting outstanding aborts */ + icmd = &iocbq->iocb; + if (icmd->ulpCommand == CMD_ABORT_XRI_CN || + icmd->ulpCommand == CMD_CLOSE_XRI_CN) { + sum++; + continue; + } + + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, + ctx_cmd) == 0) sum++; } - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags);
return sum; } @@ -12662,7 +12703,11 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * * This function sends an abort command for every SCSI command * associated with the given virtual port pending on the ring - * filtered by lpfc_sli_validate_fcp_iocb function. + * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then + * lpfc_sli_validate_fcp_iocb function. The ordering for validation before + * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort + * followed by lpfc_sli_validate_fcp_iocb. + * * When abort_cmd == LPFC_CTX_LUN, the function sends abort only to the * FCP iocbs associated with lun specified by tgt_id and lun_id * parameters @@ -12694,6 +12739,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *v for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i];
+ if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport)) + continue; + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, abort_cmd) != 0) continue; @@ -12726,7 +12774,11 @@ lpfc_sli_abort_iocb(struct lpfc_vport *v * * This function sends an abort command for every SCSI command * associated with the given virtual port pending on the ring - * filtered by lpfc_sli_validate_fcp_iocb function. + * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then + * lpfc_sli_validate_fcp_iocb function. The ordering for validation before + * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort + * followed by lpfc_sli_validate_fcp_iocb. + * * When taskmgmt_cmd == LPFC_CTX_LUN, the function sends abort only to the * FCP iocbs associated with lun specified by tgt_id and lun_id * parameters @@ -12764,6 +12816,9 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vpor for (i = 1; i <= phba->sli.last_iotag; i++) { iocbq = phba->sli.iocbq_lookup[i];
+ if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport)) + continue; + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, cmd) != 0) continue;
From: Arun Easi aeasi@marvell.com
commit e6e22e6cc2962d3f3d71914b47f7fbc454670e8a upstream.
System crash was seen when I/O was run against an NVMe target and aborts were occurring.
Crash stack is:
-- relevant crash stack -- BUG: kernel NULL pointer dereference, address: 0000000000000010 : #6 [ffffae1f8666bdd0] page_fault at ffffffffa740122e [exception RIP: qla_nvme_abort_work+339] RIP: ffffffffc0f592e3 RSP: ffffae1f8666be80 RFLAGS: 00010297 RAX: 0000000000000000 RBX: ffff9b581fc8af80 RCX: ffffffffc0f83bd0 RDX: 0000000000000001 RSI: ffff9b5839c6c7c8 RDI: 0000000008000000 RBP: ffff9b6832f85000 R8: ffffffffc0f68160 R9: ffffffffc0f70652 R10: ffffae1f862ffdc8 R11: 0000000000000300 R12: 000000000000010d R13: 0000000000000000 R14: ffff9b5839cea000 R15: 0ffff9b583fab170 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #7 [ffffae1f8666be98] process_one_work at ffffffffa6aba184 #8 [ffffae1f8666bed8] worker_thread at ffffffffa6aba39d #9 [ffffae1f8666bf10] kthread at ffffffffa6ac06ed
The crash was due to a stale SRB structure access after it was aborted. Fix the issue by removing stale access.
Link: https://lore.kernel.org/r/20210908164622.19240-5-njavali@marvell.com Fixes: 2cabf10dbbe3 ("scsi: qla2xxx: Fix hang on NVMe command timeouts") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Arun Easi aeasi@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_nvme.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -228,6 +228,8 @@ static void qla_nvme_abort_work(struct w fc_port_t *fcport = sp->fcport; struct qla_hw_data *ha = fcport->vha->hw; int rval, abts_done_called = 1; + bool io_wait_for_abort_done; + uint32_t handle;
ql_dbg(ql_dbg_io, fcport->vha, 0xffff, "%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n", @@ -244,12 +246,20 @@ static void qla_nvme_abort_work(struct w goto out; }
+ /* + * sp may not be valid after abort_command if return code is either + * SUCCESS or ERR_FROM_FW codes, so cache the value here. + */ + io_wait_for_abort_done = ql2xabts_wait_nvme && + QLA_ABTS_WAIT_ENABLED(sp); + handle = sp->handle; + rval = ha->isp_ops->abort_command(sp);
ql_dbg(ql_dbg_io, fcport->vha, 0x212b, "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n", __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted", - sp, sp->handle, fcport, rval); + sp, handle, fcport, rval);
/* * If async tmf is enabled, the abort callback is called only on @@ -264,7 +274,7 @@ static void qla_nvme_abort_work(struct w * are waited until ABTS complete. This kref is decreased * at qla24xx_abort_sp_done function. */ - if (abts_done_called && ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp)) + if (abts_done_called && io_wait_for_abort_done) return; out: /* kref_get was done before work was schedule. */
From: Arun Easi aeasi@marvell.com
commit 3ef68d4f0c9e7cb589ae8b70f07d77f528105331 upstream.
Kernel crashes when accessing port_speed sysfs file. The issue happens on a CNA when the local array was accessed beyond bounds. Fix this by changing the lookup.
BUG: unable to handle kernel paging request at 0000000000004000 PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 15 PID: 455213 Comm: sosreport Kdump: loaded Not tainted 4.18.0-305.7.1.el8_4.x86_64 #1 RIP: 0010:string_nocheck+0x12/0x70 Code: 00 00 4c 89 e2 be 20 00 00 00 48 89 ef e8 86 9a 00 00 4c 01 e3 eb 81 90 49 89 f2 48 89 ce 48 89 f8 48 c1 fe 30 66 85 f6 74 4f <44> 0f b6 0a 45 84 c9 74 46 83 ee 01 41 b8 01 00 00 00 48 8d 7c 37 RSP: 0018:ffffb5141c1afcf0 EFLAGS: 00010286 RAX: ffff8bf4009f8000 RBX: ffff8bf4009f9000 RCX: ffff0a00ffffff04 RDX: 0000000000004000 RSI: ffffffffffffffff RDI: ffff8bf4009f8000 RBP: 0000000000004000 R08: 0000000000000001 R09: ffffb5141c1afb84 R10: ffff8bf4009f9000 R11: ffffb5141c1afce6 R12: ffff0a00ffffff04 R13: ffffffffc08e21aa R14: 0000000000001000 R15: ffffffffc08e21aa FS: 00007fc4ebfff700(0000) GS:ffff8c717f7c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000004000 CR3: 000000edfdee6006 CR4: 00000000001706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: string+0x40/0x50 vsnprintf+0x33c/0x520 scnprintf+0x4d/0x90 qla2x00_port_speed_show+0xb5/0x100 [qla2xxx] dev_attr_show+0x1c/0x40 sysfs_kf_seq_show+0x9b/0x100 seq_read+0x153/0x410 vfs_read+0x91/0x140 ksys_read+0x4f/0xb0 do_syscall_64+0x5b/0x1a0 entry_SYSCALL_64_after_hwframe+0x65/0xca
Link: https://lore.kernel.org/r/20210908164622.19240-7-njavali@marvell.com Fixes: 4910b524ac9e ("scsi: qla2xxx: Add support for setting port speed") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Arun Easi aeasi@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_attr.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1868,6 +1868,18 @@ qla2x00_port_speed_store(struct device * return strlen(buf); }
+static const struct { + u16 rate; + char *str; +} port_speed_str[] = { + { PORT_SPEED_4GB, "4" }, + { PORT_SPEED_8GB, "8" }, + { PORT_SPEED_16GB, "16" }, + { PORT_SPEED_32GB, "32" }, + { PORT_SPEED_64GB, "64" }, + { PORT_SPEED_10GB, "10" }, +}; + static ssize_t qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1875,7 +1887,8 @@ qla2x00_port_speed_show(struct device *d struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); struct qla_hw_data *ha = vha->hw; ssize_t rval; - char *spd[7] = {"0", "0", "0", "4", "8", "16", "32"}; + u16 i; + char *speed = "Unknown";
rval = qla2x00_get_data_rate(vha); if (rval != QLA_SUCCESS) { @@ -1884,7 +1897,14 @@ qla2x00_port_speed_show(struct device *d return -EINVAL; }
- return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); + for (i = 0; i < ARRAY_SIZE(port_speed_str); i++) { + if (port_speed_str[i].rate != ha->link_data_rate) + continue; + speed = port_speed_str[i].str; + break; + } + + return scnprintf(buf, PAGE_SIZE, "%s\n", speed); }
static ssize_t
From: Quinn Tran qutran@marvell.com
commit 3d33b303d4f3b74a71bede5639ebba3cfd2a2b4d upstream.
In eh_abort path driver prematurely exits the call to upper layer. Check whether command is aborted / completed by firmware before exiting the call.
9 [ffff8b1ebf803c00] page_fault at ffffffffb0389778 [exception RIP: qla2x00_status_entry+0x48d] RIP: ffffffffc04fa62d RSP: ffff8b1ebf803cb0 RFLAGS: 00010082 RAX: 00000000ffffffff RBX: 00000000000e0000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 00000000000013d8 RDI: fffff3253db78440 RBP: ffff8b1ebf803dd0 R8: ffff8b1ebcd9b0c0 R9: 0000000000000000 R10: ffff8b1e38a30808 R11: 0000000000001000 R12: 00000000000003e9 R13: 0000000000000000 R14: ffff8b1ebcd9d740 R15: 0000000000000028 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 10 [ffff8b1ebf803cb0] enqueue_entity at ffffffffafce708f 11 [ffff8b1ebf803d00] enqueue_task_fair at ffffffffafce7b88 12 [ffff8b1ebf803dd8] qla24xx_process_response_queue at ffffffffc04fc9a6 [qla2xxx] 13 [ffff8b1ebf803e78] qla24xx_msix_rsp_q at ffffffffc04ff01b [qla2xxx] 14 [ffff8b1ebf803eb0] __handle_irq_event_percpu at ffffffffafd50714
Link: https://lore.kernel.org/r/20210908164622.19240-10-njavali@marvell.com Fixes: f45bca8c5052 ("scsi: qla2xxx: Fix double scsi_done for abort path") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Co-developed-by: David Jeffery djeffery@redhat.com Signed-off-by: David Jeffery djeffery@redhat.com Co-developed-by: Laurence Oberman loberman@redhat.com Signed-off-by: Laurence Oberman loberman@redhat.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/qla2xxx/qla_os.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1258,6 +1258,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) uint32_t ratov_j; struct qla_qpair *qpair; unsigned long flags; + int fast_fail_status = SUCCESS;
if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, @@ -1266,9 +1267,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) return FAILED; }
+ /* Save any FAST_IO_FAIL value to return later if abort succeeds */ ret = fc_block_scsi_eh(cmd); if (ret != 0) - return ret; + fast_fail_status = ret;
sp = scsi_cmd_priv(cmd); qpair = sp->qpair; @@ -1276,7 +1278,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) vha->cmd_timeout_cnt++;
if ((sp->fcport && sp->fcport->deleted) || !qpair) - return SUCCESS; + return fast_fail_status != SUCCESS ? fast_fail_status : FAILED;
spin_lock_irqsave(qpair->qp_lock_ptr, flags); sp->comp = ∁ @@ -1311,7 +1313,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) __func__, ha->r_a_tov/10); ret = FAILED; } else { - ret = SUCCESS; + ret = fast_fail_status; } break; default:
From: Ben Skeggs bskeggs@redhat.com
commit 93f43ed81abec8c805e1b77eb1d20dbc51a24dc4 upstream.
The code which constructs the modules for each engine present on the GPU passes -1 for 'instance' on non-instanced engines, which affects how the name for a sub-device is generated. This is then stored as 'instance 0' in nvkm_subdev.inst, so code can potentially be shared with earlier GPUs that only had a single instance of an engine.
However, GF100's CE constructor uses this value to calculate the address of its falcon before it's translated, resulting in CE0 getting the wrong address.
This slightly modifies the approach, always passing a valid instance for engines that *can* have multiple copies, and having the code for earlier GPUs explicitly ask for non-instanced name generation.
Bug: https://gitlab.freedesktop.org/drm/nouveau/-/issues/91
Fixes: 50551b15c760 ("drm/nouveau/ce: switch to instanced constructor") Cc: stable@vger.kernel.org # v5.12+ Signed-off-by: Ben Skeggs bskeggs@redhat.com Reviewed-by: Karol Herbst kherbst@redhat.com Tested-by: Karol Herbst kherbst@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20211103011057.15344-1-skeggsb... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c | 2 +- drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c @@ -78,6 +78,6 @@ int gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_engine **pengine) { - return nvkm_falcon_new_(>215_ce, device, type, inst, + return nvkm_falcon_new_(>215_ce, device, type, -1, (device->chipset != 0xaf), 0x104000, pengine); } --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -3147,8 +3147,7 @@ nvkm_device_ctor(const struct nvkm_devic WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \ for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \ if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \ - int inst = (device->chip->ptr.inst == 1) ? -1 : (j); \ - ret = device->chip->ptr.ctor(device, (type), inst, &device->ptr[j]); \ + ret = device->chip->ptr.ctor(device, (type), (j), &device->ptr[j]); \ subdev = nvkm_device_subdev(device, (type), (j)); \ if (ret) { \ nvkm_subdev_del(&subdev); \
From: Ziyang Xuan william.xuanziyang@huawei.com
commit 15c9a359094ec6251578b02387436bc64f11a477 upstream.
When endpoint_alloc() return failed in xillyusb_setup_base_eps(), 'xdev->msg_ep' will be freed but not set to NULL. That lets program enter fail handling to cleanup_dev() in xillyusb_probe(). Check for 'xdev->msg_ep' is invalid in cleanup_dev() because 'xdev->msg_ep' did not set to NULL when was freed. So the UAF problem for 'xdev->msg_ep' is triggered.
================================================================== BUG: KASAN: use-after-free in fifo_mem_release+0x1f4/0x210 CPU: 0 PID: 166 Comm: kworker/0:2 Not tainted 5.15.0-rc5+ #19 Call Trace: dump_stack_lvl+0xe2/0x152 print_address_description.constprop.0+0x21/0x140 ? fifo_mem_release+0x1f4/0x210 kasan_report.cold+0x7f/0x11b ? xillyusb_probe+0x530/0x700 ? fifo_mem_release+0x1f4/0x210 fifo_mem_release+0x1f4/0x210 ? __sanitizer_cov_trace_pc+0x1d/0x50 endpoint_dealloc+0x35/0x2b0 cleanup_dev+0x90/0x120 xillyusb_probe+0x59a/0x700 ...
Freed by task 166: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 __kasan_slab_free+0x109/0x140 kfree+0x117/0x4c0 xillyusb_probe+0x606/0x700
Set 'xdev->msg_ep' to NULL after being freed in xillyusb_setup_base_eps() to fix the UAF problem.
Fixes: a53d1202aef1 ("char: xillybus: Add driver for XillyUSB (Xillybus variant for USB)") Cc: stable stable@vger.kernel.org Acked-by: Eli Billauer eli.billauer@gmail.com Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Link: https://lore.kernel.org/r/20211016052047.1611983-1-william.xuanziyang@huawei... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/xillybus/xillyusb.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/char/xillybus/xillyusb.c +++ b/drivers/char/xillybus/xillyusb.c @@ -1912,6 +1912,7 @@ static int xillyusb_setup_base_eps(struc
dealloc: endpoint_dealloc(xdev->msg_ep); /* Also frees FIFO mem if allocated */ + xdev->msg_ep = NULL; return -ENOMEM; }
From: Derong Liu derong.liu@mediatek.com
commit 43e5fee317f4b0a48992b8b07935b1a3ac20ce84 upstream.
We found this issue on a 5G platform, during CMDQ error handling, if DMA status is active when it call msdc_reset_hw(), it means mmc host hw reset and DMA transfer will be parallel, mmc host may access sram region unexpectedly. According to the programming guide of mtk-sd host, it needs to wait for dma stop done after set dma stop.
This change should be applied to all SoCs.
Signed-off-by: Derong Liu derong.liu@mediatek.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210827071537.1034-1-derong.liu@mediatek.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/mtk-sd.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -8,6 +8,7 @@ #include <linux/clk.h> #include <linux/delay.h> #include <linux/dma-mapping.h> +#include <linux/iopoll.h> #include <linux/ioport.h> #include <linux/irq.h> #include <linux/of_address.h> @@ -2330,6 +2331,7 @@ static void msdc_cqe_enable(struct mmc_h static void msdc_cqe_disable(struct mmc_host *mmc, bool recovery) { struct msdc_host *host = mmc_priv(mmc); + unsigned int val = 0;
/* disable cmdq irq */ sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INT_CMDQ); @@ -2339,6 +2341,9 @@ static void msdc_cqe_disable(struct mmc_ if (recovery) { sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, 1); + if (WARN_ON(readl_poll_timeout(host->base + MSDC_DMA_CFG, val, + !(val & MSDC_DMA_CFG_STS), 1, 3000))) + return; msdc_reset_hw(host); } }
From: Christian Löhle CLoehle@hyperstone.com
commit 43592c8736e84025d7a45e61a46c3fa40536a364 upstream.
Only wait for DRTO on reads, otherwise the driver hangs.
The driver prevents sending CMD12 on response errors like CRCs. According to the comment this is because some cards have problems with this during the UHS tuning sequence. Unfortunately this workaround currently also applies for any command with data. On reads this will set the drto timer, which then triggers after a while. On writes this will not set any timer and the tasklet will not be scheduled again.
I cannot test for the UHS workarounds need, but even if so, it should at most apply to reads. I have observed many hangs when CMD25 response contained a CRC error. This patch fixes this without touching the actual UHS tuning workaround.
Signed-off-by: Christian Loehle cloehle@hyperstone.com Reviewed-by: Jaehoon Chung jh80.chung@samsung.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/af8f8b8674ba4fcc9a781019e4aeb72c@hyperstone.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mmc/host/dw_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2086,7 +2086,8 @@ static void dw_mci_tasklet_func(struct t * delayed. Allowing the transfer to take place * avoids races and keeps things simple. */ - if (err != -ETIMEDOUT) { + if (err != -ETIMEDOUT && + host->dir_status == DW_MCI_RECV_STATUS) { state = STATE_SENDING_DATA; continue; }
From: Sungjong Seo sj1557.seo@samsung.com
commit 0c336d6e33f4bedc443404c89f43c91c8bd9ee11 upstream.
When calculating i_blocks, there was a mistake that was masked with a 32-bit variable. So i_blocks for files larger than 4 GiB had incorrect values. Mask with a 64-bit variable instead of 32-bit one.
Fixes: 5f2aa075070c ("exfat: add inode operations") Cc: stable@vger.kernel.org # v5.7+ Reported-by: Ganapathi Kamath hgkamath@hotmail.com Signed-off-by: Sungjong Seo sj1557.seo@samsung.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/exfat/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -604,7 +604,7 @@ static int exfat_fill_inode(struct inode exfat_save_attr(inode, info->attr);
inode->i_blocks = ((i_size_read(inode) + (sbi->cluster_size - 1)) & - ~(sbi->cluster_size - 1)) >> inode->i_blkbits; + ~((loff_t)sbi->cluster_size - 1)) >> inode->i_blkbits; inode->i_mtime = info->mtime; inode->i_ctime = info->mtime; ei->i_crtime = info->crtime;
From: Pavel Begunkov asml.silence@gmail.com
commit 1d5f5ea7cb7d15b9fb1cc82673ebb054f02cd7d2 upstream.
INFO: task iou-wrk-6609:6612 blocked for more than 143 seconds. Not tainted 5.15.0-rc5-syzkaller #0 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:iou-wrk-6609 state:D stack:27944 pid: 6612 ppid: 6526 flags:0x00004006 Call Trace: context_switch kernel/sched/core.c:4940 [inline] __schedule+0xb44/0x5960 kernel/sched/core.c:6287 schedule+0xd3/0x270 kernel/sched/core.c:6366 schedule_timeout+0x1db/0x2a0 kernel/time/timer.c:1857 do_wait_for_common kernel/sched/completion.c:85 [inline] __wait_for_common kernel/sched/completion.c:106 [inline] wait_for_common kernel/sched/completion.c:117 [inline] wait_for_completion+0x176/0x280 kernel/sched/completion.c:138 io_worker_exit fs/io-wq.c:183 [inline] io_wqe_worker+0x66d/0xc40 fs/io-wq.c:597 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
io-wq worker may submit a task_work to the master task and upon io_worker_exit() wait for the tw to get executed. The problem appears when the master task is waiting in coredump.c:
468 freezer_do_not_count(); 469 wait_for_completion(&core_state->startup); 470 freezer_count();
Apparently having some dependency on children threads getting everything stuck. Workaround it by cancelling the taks_work callback that causes it before going into io_worker_exit() waiting.
p.s. probably a better option is to not submit tw elevating the refcount in the first place, but let's leave this excercise for the future.
Cc: stable@vger.kernel.org Reported-and-tested-by: syzbot+27d62ee6f256b186883e@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/142a716f4ed936feae868959059154362bfa8c19.163550945... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io-wq.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-)
--- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -140,6 +140,7 @@ static void io_wqe_dec_running(struct io static bool io_acct_cancel_pending_work(struct io_wqe *wqe, struct io_wqe_acct *acct, struct io_cb_cancel_data *match); +static void create_worker_cb(struct callback_head *cb);
static bool io_worker_get(struct io_worker *worker) { @@ -174,9 +175,44 @@ static void io_worker_ref_put(struct io_ complete(&wq->worker_done); }
+static void io_worker_cancel_cb(struct io_worker *worker) +{ + struct io_wqe_acct *acct = io_wqe_get_acct(worker); + struct io_wqe *wqe = worker->wqe; + struct io_wq *wq = wqe->wq; + + atomic_dec(&acct->nr_running); + raw_spin_lock(&worker->wqe->lock); + acct->nr_workers--; + raw_spin_unlock(&worker->wqe->lock); + io_worker_ref_put(wq); + clear_bit_unlock(0, &worker->create_state); + io_worker_release(worker); +} + +static bool io_task_worker_match(struct callback_head *cb, void *data) +{ + struct io_worker *worker; + + if (cb->func != create_worker_cb) + return false; + worker = container_of(cb, struct io_worker, create_work); + return worker == data; +} + static void io_worker_exit(struct io_worker *worker) { struct io_wqe *wqe = worker->wqe; + struct io_wq *wq = wqe->wq; + + while (1) { + struct callback_head *cb = task_work_cancel_match(wq->task, + io_task_worker_match, worker); + + if (!cb) + break; + io_worker_cancel_cb(worker); + }
if (refcount_dec_and_test(&worker->ref)) complete(&worker->ref_done); @@ -1150,17 +1186,9 @@ static void io_wq_exit_workers(struct io
while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) { struct io_worker *worker; - struct io_wqe_acct *acct;
worker = container_of(cb, struct io_worker, create_work); - acct = io_wqe_get_acct(worker); - atomic_dec(&acct->nr_running); - raw_spin_lock(&worker->wqe->lock); - acct->nr_workers--; - raw_spin_unlock(&worker->wqe->lock); - io_worker_ref_put(wq); - clear_bit_unlock(0, &worker->create_state); - io_worker_release(worker); + io_worker_cancel_cb(worker); }
rcu_read_lock();
From: Helge Deller deller@gmx.de
commit 6e866a462867b60841202e900f10936a0478608c upstream.
Fix a kernel crash which happens on PA1.x CPUs while initializing the FTRACE/KPROBE breakpoints. The PTE table entries for the fixmap area were not created correctly.
Signed-off-by: Helge Deller deller@gmx.de Fixes: ccfbc68d41c2 ("parisc: add set_fixmap()/clear_fixmap()") Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/mm/fixmap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
--- a/arch/parisc/mm/fixmap.c +++ b/arch/parisc/mm/fixmap.c @@ -20,12 +20,9 @@ void notrace set_fixmap(enum fixed_addre pte_t *pte;
if (pmd_none(*pmd)) - pmd = pmd_alloc(NULL, pud, vaddr); - - pte = pte_offset_kernel(pmd, vaddr); - if (pte_none(*pte)) pte = pte_alloc_kernel(pmd, vaddr);
+ pte = pte_offset_kernel(pmd, vaddr); set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX)); flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); }
From: Helge Deller deller@gmx.de
commit 8779e05ba8aaffec1829872ef9774a71f44f6580 upstream.
The TIF_XXX flags are stored in the flags field in the thread_info struct (TI_FLAGS), not in the flags field of the task_struct structure (TASK_FLAGS).
It seems this bug didn't generate any important side-effects, otherwise it wouldn't have went unnoticed for 12 years (since v2.6.32).
Signed-off-by: Helge Deller deller@gmx.de Fixes: ecd3d4bc06e48 ("parisc: stop using task->ptrace for {single,block}step flags") Cc: Kyle McMartin kyle@mcmartin.ca Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -1834,7 +1834,7 @@ syscall_restore: LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
/* Are we being ptraced? */ - ldw TASK_FLAGS(%r1),%r19 + LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 ldi _TIF_SYSCALL_TRACE_MASK,%r2 and,COND(=) %r19,%r2,%r0 b,n syscall_restore_rfi
From: Dan Carpenter dan.carpenter@oracle.com
commit a0bcce2b2a169e10eb265c8f0ebdd5ae4c875670 upstream.
The "4 * be32_to_cpu(data->count)" multiplication can potentially overflow which would lead to memory corruption. Add a check for that.
Cc: stable@vger.kernel.org Fixes: 745b361e989a ("tpm: infrastructure for TPM spaces") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/tpm/tpm2-space.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/char/tpm/tpm2-space.c +++ b/drivers/char/tpm/tpm2-space.c @@ -455,6 +455,9 @@ static int tpm2_map_response_body(struct if (be32_to_cpu(data->capability) != TPM2_CAP_HANDLES) return 0;
+ if (be32_to_cpu(data->count) > (UINT_MAX - TPM_HEADER_SIZE - 9) / 4) + return -EFAULT; + if (len != TPM_HEADER_SIZE + 9 + 4 * be32_to_cpu(data->count)) return -EFAULT;
From: jing yangyang cgel.zte@gmail.com
commit 2ac5fb35cd520ab1851c9a4816c523b65276052f upstream.
sizeof when applied to a pointer typed expression gives the size of the pointer.
./drivers/firmware/psci/psci_checker.c:158:41-47: ERROR application of sizeof to pointer
This issue was detected with the help of Coccinelle.
Fixes: 7401056de5f8 ("drivers/firmware: psci_checker: stash and use topology_core_cpumask for hotplug tests") Cc: stable@vger.kernel.org Reported-by: Zeal Robot zealci@zte.com.cn Acked-by: Mark Rutland mark.rutland@arm.com Reviewed-by: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: jing yangyang jing.yangyang@zte.com.cn Signed-off-by: Gustavo A. R. Silva gustavoars@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firmware/psci/psci_checker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/firmware/psci/psci_checker.c +++ b/drivers/firmware/psci/psci_checker.c @@ -155,7 +155,7 @@ static int alloc_init_cpu_groups(cpumask if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return -ENOMEM;
- cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups), + cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups), GFP_KERNEL); if (!cpu_groups) { free_cpumask_var(tmp);
From: Tang Bin tangbin@cmss.chinamobile.com
commit a472cc0dde3eb057db71c80f102556eeced03805 upstream.
The function s5p_aes_probe() does not perform sufficient error checking after executing platform_get_resource(), thus fix it.
Fixes: c2afad6c6105 ("crypto: s5p-sss - Add HASH support for Exynos") Cc: stable@vger.kernel.org Signed-off-by: Tang Bin tangbin@cmss.chinamobile.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/crypto/s5p-sss.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -2171,6 +2171,8 @@ static int s5p_aes_probe(struct platform
variant = find_s5p_sss_version(pdev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL;
/* * Note: HASH and PRNG uses the same registers in secss, avoid
From: Chen-Yu Tsai wenst@chromium.org
commit 298d8e8f7bcf023aceb60232d59b983255fec0df upstream.
The rkvdec H.264 decoder currently overrides sizeimage for the output format. This causes issues when userspace requires and requests a larger buffer, but ends up with one of insufficient size.
Instead, only provide a default size if none was requested. This fixes the video_decode_accelerator_tests from Chromium failing on the first frame due to insufficient buffer space. It also aligns the behavior of the rkvdec driver with the Hantro and Cedrus drivers.
Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver") Cc: stable@vger.kernel.org Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/rkvdec/rkvdec-h264.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/staging/media/rkvdec/rkvdec-h264.c +++ b/drivers/staging/media/rkvdec/rkvdec-h264.c @@ -1015,8 +1015,9 @@ static int rkvdec_h264_adjust_fmt(struct struct v4l2_pix_format_mplane *fmt = &f->fmt.pix_mp;
fmt->num_planes = 1; - fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * - RKVDEC_H264_MAX_DEPTH_IN_BYTES; + if (!fmt->plane_fmt[0].sizeimage) + fmt->plane_fmt[0].sizeimage = fmt->width * fmt->height * + RKVDEC_H264_MAX_DEPTH_IN_BYTES; return 0; }
From: Sean Young sean@mess.org
commit fdc881783099c6343921ff017450831c8766d12a upstream.
On an Intel NUC6iSYK, no IR is reported after a receive overflow.
When a receiver overflow occurs, this condition is only cleared by reading the fifo. Make sure we read anything in the fifo.
Fixes: 28c7afb07ccf ("media: ite-cir: check for receive overflow") Suggested-by: Bryan Pass bryan.pass@gmail.com Tested-by: Bryan Pass bryan.pass@gmail.com Cc: stable@vger.kernel.org> Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/rc/ite-cir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -242,7 +242,7 @@ static irqreturn_t ite_cir_isr(int irq, }
/* check for the receive interrupt */ - if (iflags & ITE_IRQ_RX_FIFO) { + if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) { /* read the FIFO bytes */ rx_bytes = dev->params->get_rx_bytes(dev, rx_buf, ITE_RX_FIFO_LEN);
From: Chen-Yu Tsai wenst@chromium.org
commit 0887e9e152efbd3601d6c907e90033d25067277d upstream.
The mem-to-mem stateless decoder API specifies support for dynamic resolution changes. In particular, the decoder should accept format changes on the OUTPUT queue even when buffers have been allocated, as long as it is not streaming.
Relax restrictions for S_FMT as described in the previous paragraph, and as long as the codec format remains the same. This aligns it with the Hantro and Cedrus decoders. This change was mostly based on commit ae02d49493b5 ("media: hantro: Fix s_fmt for dynamic resolution changes").
Since rkvdec_s_fmt() is now just a wrapper around the output/capture variants without any additional shared functionality, drop the wrapper and call the respective functions directly.
Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver") Cc: stable@vger.kernel.org Signed-off-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Nicolas Dufresne nicolas.dufresne@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/media/rkvdec/rkvdec.c | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-)
--- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -280,31 +280,20 @@ static int rkvdec_try_output_fmt(struct return 0; }
-static int rkvdec_s_fmt(struct file *file, void *priv, - struct v4l2_format *f, - int (*try_fmt)(struct file *, void *, - struct v4l2_format *)) +static int rkvdec_s_capture_fmt(struct file *file, void *priv, + struct v4l2_format *f) { struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); struct vb2_queue *vq; + int ret;
- if (!try_fmt) - return -EINVAL; - - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); + /* Change not allowed if queue is busy */ + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (vb2_is_busy(vq)) return -EBUSY;
- return try_fmt(file, priv, f); -} - -static int rkvdec_s_capture_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct rkvdec_ctx *ctx = fh_to_rkvdec_ctx(priv); - int ret; - - ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_capture_fmt); + ret = rkvdec_try_capture_fmt(file, priv, f); if (ret) return ret;
@@ -319,10 +308,21 @@ static int rkvdec_s_output_fmt(struct fi struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; const struct rkvdec_coded_fmt_desc *desc; struct v4l2_format *cap_fmt; - struct vb2_queue *peer_vq; + struct vb2_queue *peer_vq, *vq; int ret;
/* + * In order to support dynamic resolution change, the decoder admits + * a resolution change, as long as the pixelformat remains. Can't be + * done if streaming. + */ + vq = v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (vb2_is_streaming(vq) || + (vb2_is_busy(vq) && + f->fmt.pix_mp.pixelformat != ctx->coded_fmt.fmt.pix_mp.pixelformat)) + return -EBUSY; + + /* * Since format change on the OUTPUT queue will reset the CAPTURE * queue, we can't allow doing so when the CAPTURE queue has buffers * allocated. @@ -331,7 +331,7 @@ static int rkvdec_s_output_fmt(struct fi if (vb2_is_busy(peer_vq)) return -EBUSY;
- ret = rkvdec_s_fmt(file, priv, f, rkvdec_try_output_fmt); + ret = rkvdec_try_output_fmt(file, priv, f); if (ret) return ret;
From: Sean Young sean@mess.org
commit c73ba202a851c0b611ef2c25e568fadeff5e667f upstream.
The IR receiver has two issues:
- Sometimes there is no response to a button press - Sometimes a button press is repeated when it should not have been
Hanging the polling interval fixes this behaviour.
Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=994050
Cc: stable@vger.kernel.org Suggested-by: Joaquín Alberto Calderón Pozo kini_calderon@hotmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/i2c/ir-kbd-i2c.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -791,6 +791,7 @@ static int ir_probe(struct i2c_client *c rc_proto = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_RC6_6A_32; ir_codes = RC_MAP_HAUPPAUGE; + ir->polling_interval = 125; probe_tx = true; break; }
From: Ricardo Ribalda ribalda@chromium.org
commit 861f92cb9160b14beef0ada047384c2340701ee2 upstream.
Drivers that do not use the ctrl-framework use this function instead.
Fix the following issues:
- Do not check for multiple classes when getting the DEF_VAL. - Return -EINVAL for request_api calls - Default value cannot be changed, return EINVAL as soon as possible. - Return the right error_idx [If an error is found when validating the list of controls passed with VIDIOC_G_EXT_CTRLS, then error_idx shall be set to ctrls->count to indicate to userspace that no actual hardware was touched. It would have been much nicer of course if error_idx could point to the control index that failed the validation, but sadly that's not how the API was designed.]
Fixes v4l2-compliance: Control ioctls (Input 0): warn: v4l2-test-controls.cpp(834): error_idx should be equal to count warn: v4l2-test-controls.cpp(855): error_idx should be equal to count fail: v4l2-test-controls.cpp(813): doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls) test VIDIOC_G/S/TRY_EXT_CTRLS: FAIL Buffer ioctls (Input 0): fail: v4l2-test-buffers.cpp(1994): ret != EINVAL && ret != EBADR && ret != ENOTTY test Requests: FAIL
Cc: stable@vger.kernel.org Fixes: 6fa6f831f095 ("media: v4l2-ctrls: add core request support") Suggested-by: Hans Verkuil hverkuil-cisco@xs4all.nl Reviewed-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/v4l2-core/v4l2-ioctl.c | 60 ++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 21 deletions(-)
--- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -869,7 +869,7 @@ static void v4l_print_default(const void pr_cont("driver-specific ioctl\n"); }
-static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) +static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) { __u32 i;
@@ -878,23 +878,41 @@ static int check_ext_ctrls(struct v4l2_e for (i = 0; i < c->count; i++) c->controls[i].reserved2[0] = 0;
- /* V4L2_CID_PRIVATE_BASE cannot be used as control class - when using extended controls. - Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL - is it allowed for backwards compatibility. - */ - if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE) - return 0; - if (!c->which) - return 1; + switch (c->which) { + case V4L2_CID_PRIVATE_BASE: + /* + * V4L2_CID_PRIVATE_BASE cannot be used as control class + * when using extended controls. + * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL + * is it allowed for backwards compatibility. + */ + if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL) + return false; + break; + case V4L2_CTRL_WHICH_DEF_VAL: + /* Default value cannot be changed */ + if (ioctl == VIDIOC_S_EXT_CTRLS || + ioctl == VIDIOC_TRY_EXT_CTRLS) { + c->error_idx = c->count; + return false; + } + return true; + case V4L2_CTRL_WHICH_CUR_VAL: + return true; + case V4L2_CTRL_WHICH_REQUEST_VAL: + c->error_idx = c->count; + return false; + } + /* Check that all controls are from the same control class. */ for (i = 0; i < c->count; i++) { if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) { - c->error_idx = i; - return 0; + c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : + c->count; + return false; } } - return 1; + return true; }
static int check_fmt(struct file *file, enum v4l2_buf_type type) @@ -2187,7 +2205,7 @@ static int v4l_g_ctrl(const struct v4l2_ ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) { + if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) { int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
if (ret == 0) @@ -2221,7 +2239,7 @@ static int v4l_s_ctrl(const struct v4l2_ ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) + if (check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) return ops->vidioc_s_ext_ctrls(file, fh, &ctrls); return -EINVAL; } @@ -2243,8 +2261,8 @@ static int v4l_g_ext_ctrls(const struct vfd, vfd->v4l2_dev->mdev, p); if (ops->vidioc_g_ext_ctrls == NULL) return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) : - -EINVAL; + return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ? + ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL; }
static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, @@ -2264,8 +2282,8 @@ static int v4l_s_ext_ctrls(const struct vfd, vfd->v4l2_dev->mdev, p); if (ops->vidioc_s_ext_ctrls == NULL) return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) : - -EINVAL; + return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ? + ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL; }
static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, @@ -2285,8 +2303,8 @@ static int v4l_try_ext_ctrls(const struc vfd, vfd->v4l2_dev->mdev, p); if (ops->vidioc_try_ext_ctrls == NULL) return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) : - -EINVAL; + return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ? + ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL; }
/*
From: Johnathon Clark john.clark@cantab.net
commit 5fc462c3aaad601d5089fd5588a5799896a6937d upstream.
On the 'HP Spectre x360 Convertible 14-ea0xx' the microphone mute led is controlled by GPIO 0x04. The speaker mute LED does not seem to be exposed by GPIO and is there not set.
[ a slight coding-style fix by tiwai ]
Fixes: c3bb2b521944 ("ALSA: hda/realtek: Quirk for HP Spectre x360 14 amp setup") Signed-off-by: Johnathon Clark john.clark@cantab.net Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211020131253.35894-1-john.clark@cantab.net Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4355,6 +4355,16 @@ static void alc287_fixup_hp_gpio_led(str alc_fixup_hp_gpio_led(codec, action, 0x10, 0); }
+static void alc245_fixup_hp_gpio_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) + spec->micmute_led_polarity = 1; + alc_fixup_hp_gpio_led(codec, action, 0, 0x04); +} + /* turn on/off mic-mute LED per capture hook via VREF change */ static int vref_micmute_led_set(struct led_classdev *led_cdev, enum led_brightness brightness) @@ -6709,6 +6719,7 @@ enum { ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK, ALC287_FIXUP_HP_GPIO_LED, ALC256_FIXUP_HP_HEADSET_MIC, + ALC245_FIXUP_HP_GPIO_LED, ALC236_FIXUP_DELL_AIO_HEADSET_MIC, ALC282_FIXUP_ACER_DISABLE_LINEOUT, ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST, @@ -7333,6 +7344,8 @@ static const struct hda_fixup alc269_fix [ALC245_FIXUP_HP_X360_AMP] = { .type = HDA_FIXUP_FUNC, .v.func = alc245_fixup_hp_x360_amp, + .chained = true, + .chain_id = ALC245_FIXUP_HP_GPIO_LED }, [ALC288_FIXUP_DELL_HEADSET_MODE] = { .type = HDA_FIXUP_FUNC, @@ -8432,6 +8445,10 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc256_fixup_tongfang_reset_persistent_settings, }, + [ALC245_FIXUP_HP_GPIO_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc245_fixup_hp_gpio_led, + }, };
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
From: Takashi Iwai tiwai@suse.de
commit 375f8426ed994addd2be4d76febc946a6fdd8280 upstream.
HP OMEN 15 laptop requires the quirk to fiddle with COEF 0x0b bit 2 for toggling the mute LED. It's already implemented for other HP laptops, and we just need to add a proper fixup entry.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214735 Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211028070911.18891-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8634,6 +8634,7 @@ static const struct snd_pci_quirk alc269 ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8783, "HP ZBook Fury 15 G7 Mobile Workstation", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x8788, "HP OMEN 15", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x87c8, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e5, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87e7, "HP ProBook 450 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
From: Tim Crawford tcrawford@system76.com
commit dbfe83507cf4ea66ce4efee2ac14c5ad420e31d3 upstream.
Apply the PB51ED PCI quirk to the Clevo PC70HS. Fixes audio output from the internal speakers.
Signed-off-by: Tim Crawford tcrawford@system76.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211101162134.5336-1-tcrawford@system76.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2539,6 +2539,7 @@ static const struct snd_pci_quirk alc882 SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), + SND_PCI_QUIRK(0x1558, 0x67f1, "Clevo PC70H[PRS]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170SM", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x7715, "Clevo X170KM-G", ALC1220_FIXUP_CLEVO_PB51ED),
From: Jeremy Soller jeremy@system76.com
commit 1278cc5ac2f96bab50dd55c8c05e0a6a77ce323e upstream.
On Clevo NH77HJ, NH77HP, and their 15" variants, there is a headset microphone input attached to 0x19 that does not have a jack detect. In order to get it working, the pin configuration needs to be set correctly, and a new ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE fixup is applied. This is similar to the existing System76 quirk for ALC293, but for ALC256.
Signed-off-by: Jeremy Soller jeremy@system76.com Signed-off-by: Tim Crawford tcrawford@system76.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211102172104.10610-1-tcrawford@system76.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6739,6 +6739,7 @@ enum { ALC287_FIXUP_YOGA7_14ITL_SPEAKERS, ALC287_FIXUP_13S_GEN2_SPEAKERS, ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS, + ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE, };
static const struct hda_fixup alc269_fixups[] = { @@ -8450,6 +8451,15 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc245_fixup_hp_gpio_led, }, + [ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x03a11120 }, /* use as headset mic, without its own jack detect */ + { } + }, + .chained = true, + .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, + }, };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -8750,11 +8760,15 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1558, 0x40a1, "Clevo NL40GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40c1, "Clevo NL40[CZ]U", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x40d1, "Clevo NL41DU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x5015, "Clevo NH5[58]H[HJK]Q", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x5017, "Clevo NH7[79]H[HJK]Q", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50a3, "Clevo NJ51GU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50b3, "Clevo NK50S[BEZ]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50b6, "Clevo NK50S5", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50b8, "Clevo NK50SZ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50d5, "Clevo NP50D5", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x50e1, "Clevo NH5[58]HPQ", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x50e2, "Clevo NH7[79]HPQ", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50f0, "Clevo NH50A[CDF]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50f2, "Clevo NH50E[PR]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x50f3, "Clevo NH58DPQ", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
From: Jaroslav Kysela perex@perex.cz
commit 2a5bb694488bb6593066d46881bfd9d07edd1628 upstream.
Another model requires ALC255_FIXUP_ACER_MIC_NO_PRESENCE fixup.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=211853 Signed-off-by: Jaroslav Kysela perex@perex.cz Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211104155726.2090997-1-perex@perex.cz Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8496,6 +8496,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1025, 0x1308, "Acer Aspire Z24-890", ALC286_FIXUP_ACER_AIO_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), + SND_PCI_QUIRK(0x1025, 0x141f, "Acer Spin SP513-54N", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC),
From: Takashi Iwai tiwai@suse.de
commit 4fad4fb9871b43389e4f4bead18ec693064697bb upstream.
ASUS UX550VE (SSID 1043:1970) requires a similar workaround for managing the routing of the 4 speakers like some other ASUS models. Add a corresponding quirk entry for fixing it.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=212641 Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211107083339.18013-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8698,6 +8698,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x18f1, "Asus FX505DT", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x194e, "ASUS UX563FD", ALC294_FIXUP_ASUS_HPE), + SND_PCI_QUIRK(0x1043, 0x1970, "ASUS UX550VE", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1982, "ASUS B1400CEPE", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
From: Kai-Heng Feng kai.heng.feng@canonical.com
commit c058493df7edcef8f48c1494d9a84218519f966b upstream.
The mute and micmute LEDs don't work on HP EliteBook 840 G7. The same quirk for other HP laptops can let LEDs work, so apply it.
Signed-off-by: Kai-Heng Feng kai.heng.feng@canonical.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211110144033.118451-1-kai.heng.feng@canonical.co... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8636,6 +8636,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8728, "HP EliteBook 840 G7", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_AMP_INIT),
From: Johan Hovold johan@kernel.org
commit 55f261b73a7e1cb254577c3536cef8f415de220a upstream.
Add the missing endpoint max-packet sanity check to probe() to avoid division by zero in alloc_stream_buffers() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing).
Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")).
Fixes: 63978ab3e3e9 ("sound: add Edirol UA-101 support") Cc: stable@vger.kernel.org # 2.6.34 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211026095401.26522-1-johan@kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/misc/ua101.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -1000,7 +1000,7 @@ static int detect_usb_format(struct ua10 fmt_playback->bSubframeSize * ua->playback.channels;
epd = &ua->intf[INTF_CAPTURE]->altsetting[1].endpoint[0].desc; - if (!usb_endpoint_is_isoc_in(epd)) { + if (!usb_endpoint_is_isoc_in(epd) || usb_endpoint_maxp(epd) == 0) { dev_err(&ua->dev->dev, "invalid capture endpoint\n"); return -ENXIO; } @@ -1008,7 +1008,7 @@ static int detect_usb_format(struct ua10 ua->capture.max_packet_bytes = usb_endpoint_maxp(epd);
epd = &ua->intf[INTF_PLAYBACK]->altsetting[1].endpoint[0].desc; - if (!usb_endpoint_is_isoc_out(epd)) { + if (!usb_endpoint_is_isoc_out(epd) || usb_endpoint_maxp(epd) == 0) { dev_err(&ua->dev->dev, "invalid playback endpoint\n"); return -ENXIO; }
From: Johan Hovold johan@kernel.org
commit 9b371c6cc37f954360989eec41c2ddc5a6b83917 upstream.
USB control and bulk message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: c6d43ba816d1 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB") Cc: stable@vger.kernel.org # 2.6.39 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211025121142.6531-2-johan@kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/6fire/comm.c | 2 +- sound/usb/6fire/firmware.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
--- a/sound/usb/6fire/comm.c +++ b/sound/usb/6fire/comm.c @@ -95,7 +95,7 @@ static int usb6fire_comm_send_buffer(u8 int actual_len;
ret = usb_interrupt_msg(dev, usb_sndintpipe(dev, COMM_EP), - buffer, buffer[1] + 2, &actual_len, HZ); + buffer, buffer[1] + 2, &actual_len, 1000); if (ret < 0) return ret; else if (actual_len != buffer[1] + 2) --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -160,7 +160,7 @@ static int usb6fire_fw_ezusb_write(struc { return usb_control_msg_send(device, 0, type, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, 0, data, len, HZ, GFP_KERNEL); + value, 0, data, len, 1000, GFP_KERNEL); }
static int usb6fire_fw_ezusb_read(struct usb_device *device, @@ -168,7 +168,7 @@ static int usb6fire_fw_ezusb_read(struct { return usb_control_msg_recv(device, 0, type, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, 0, data, len, HZ, GFP_KERNEL); + value, 0, data, len, 1000, GFP_KERNEL); }
static int usb6fire_fw_fpga_write(struct usb_device *device, @@ -178,7 +178,7 @@ static int usb6fire_fw_fpga_write(struct int ret;
ret = usb_bulk_msg(device, usb_sndbulkpipe(device, FPGA_EP), data, len, - &actual_len, HZ); + &actual_len, 1000); if (ret < 0) return ret; else if (actual_len != len)
From: Johan Hovold johan@kernel.org
commit f4000b58b64344871d7b27c05e73932f137cfef6 upstream.
USB control and interrupt message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: 705ececd1c60 ("Staging: add line6 usb driver") Cc: stable@vger.kernel.org # 2.6.30 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211025121142.6531-3-johan@kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/line6/driver.c | 14 +++++++------- sound/usb/line6/driver.h | 2 +- sound/usb/line6/podhd.c | 6 +++--- sound/usb/line6/toneport.c | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-)
--- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -113,12 +113,12 @@ int line6_send_raw_message(struct usb_li retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, properties->ep_ctrl_w), (char *)frag_buf, frag_size, - &partial, LINE6_TIMEOUT * HZ); + &partial, LINE6_TIMEOUT); } else { retval = usb_bulk_msg(line6->usbdev, usb_sndbulkpipe(line6->usbdev, properties->ep_ctrl_w), (char *)frag_buf, frag_size, - &partial, LINE6_TIMEOUT * HZ); + &partial, LINE6_TIMEOUT); }
if (retval) { @@ -347,7 +347,7 @@ int line6_read_data(struct usb_line6 *li ret = usb_control_msg_send(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, (datalen << 8) | 0x21, address, NULL, 0, - LINE6_TIMEOUT * HZ, GFP_KERNEL); + LINE6_TIMEOUT, GFP_KERNEL); if (ret) { dev_err(line6->ifcdev, "read request failed (error %d)\n", ret); goto exit; @@ -360,7 +360,7 @@ int line6_read_data(struct usb_line6 *li ret = usb_control_msg_recv(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x0012, 0x0000, &len, 1, - LINE6_TIMEOUT * HZ, GFP_KERNEL); + LINE6_TIMEOUT, GFP_KERNEL); if (ret) { dev_err(line6->ifcdev, "receive length failed (error %d)\n", ret); @@ -387,7 +387,7 @@ int line6_read_data(struct usb_line6 *li /* receive the result: */ ret = usb_control_msg_recv(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0013, 0x0000, data, datalen, LINE6_TIMEOUT * HZ, + 0x0013, 0x0000, data, datalen, LINE6_TIMEOUT, GFP_KERNEL); if (ret) dev_err(line6->ifcdev, "read failed (error %d)\n", ret); @@ -417,7 +417,7 @@ int line6_write_data(struct usb_line6 *l
ret = usb_control_msg_send(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - 0x0022, address, data, datalen, LINE6_TIMEOUT * HZ, + 0x0022, address, data, datalen, LINE6_TIMEOUT, GFP_KERNEL); if (ret) { dev_err(line6->ifcdev, @@ -430,7 +430,7 @@ int line6_write_data(struct usb_line6 *l
ret = usb_control_msg_recv(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0012, 0x0000, status, 1, LINE6_TIMEOUT * HZ, + 0x0012, 0x0000, status, 1, LINE6_TIMEOUT, GFP_KERNEL); if (ret) { dev_err(line6->ifcdev, --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -27,7 +27,7 @@ #define LINE6_FALLBACK_INTERVAL 10 #define LINE6_FALLBACK_MAXPACKETSIZE 16
-#define LINE6_TIMEOUT 1 +#define LINE6_TIMEOUT 1000 #define LINE6_BUFSIZE_LISTEN 64 #define LINE6_MIDI_MESSAGE_MAXLEN 256
--- a/sound/usb/line6/podhd.c +++ b/sound/usb/line6/podhd.c @@ -190,7 +190,7 @@ static int podhd_dev_start(struct usb_li ret = usb_control_msg_send(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x11, 0, - NULL, 0, LINE6_TIMEOUT * HZ, GFP_KERNEL); + NULL, 0, LINE6_TIMEOUT, GFP_KERNEL); if (ret) { dev_err(pod->line6.ifcdev, "read request failed (error %d)\n", ret); goto exit; @@ -200,7 +200,7 @@ static int podhd_dev_start(struct usb_li ret = usb_control_msg_recv(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x11, 0x0, - init_bytes, 3, LINE6_TIMEOUT * HZ, GFP_KERNEL); + init_bytes, 3, LINE6_TIMEOUT, GFP_KERNEL); if (ret) { dev_err(pod->line6.ifcdev, "receive length failed (error %d)\n", ret); @@ -220,7 +220,7 @@ static int podhd_dev_start(struct usb_li USB_REQ_SET_FEATURE, USB_TYPE_STANDARD | USB_RECIP_DEVICE | USB_DIR_OUT, 1, 0, - NULL, 0, LINE6_TIMEOUT * HZ, GFP_KERNEL); + NULL, 0, LINE6_TIMEOUT, GFP_KERNEL); exit: return ret; } --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -128,7 +128,7 @@ static int toneport_send_cmd(struct usb_
ret = usb_control_msg_send(usbdev, 0, 0x67, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ, + cmd1, cmd2, NULL, 0, LINE6_TIMEOUT, GFP_KERNEL);
if (ret) {
From: Takashi Iwai tiwai@suse.de
commit 411cef6adfb38a5bb6bd9af3941b28198e7fb680 upstream.
The OSS mixer can reassign the mapping slots dynamically via proc file. Although the addition and deletion of those slots are protected by mixer->reg_mutex, the access to slots aren't, hence this may cause UAF when the slots in use are deleted concurrently.
This patch applies the mixer->reg_mutex in all appropriate code paths (i.e. the ioctl functions) that may access slots.
Reported-by: syzbot+9988f17cf72a1045a189@syzkaller.appspotmail.com Reviewed-by: Jaroslav Kysela perex@perex.cz Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/00000000000036adc005ceca9175@google.com Link: https://lore.kernel.org/r/20211020164846.922-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/core/oss/mixer_oss.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-)
--- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -130,11 +130,13 @@ static int snd_mixer_oss_devmask(struct
if (mixer == NULL) return -EIO; + mutex_lock(&mixer->reg_mutex); for (chn = 0; chn < 31; chn++) { pslot = &mixer->slots[chn]; if (pslot->put_volume || pslot->put_recsrc) result |= 1 << chn; } + mutex_unlock(&mixer->reg_mutex); return result; }
@@ -146,11 +148,13 @@ static int snd_mixer_oss_stereodevs(stru
if (mixer == NULL) return -EIO; + mutex_lock(&mixer->reg_mutex); for (chn = 0; chn < 31; chn++) { pslot = &mixer->slots[chn]; if (pslot->put_volume && pslot->stereo) result |= 1 << chn; } + mutex_unlock(&mixer->reg_mutex); return result; }
@@ -161,6 +165,7 @@ static int snd_mixer_oss_recmask(struct
if (mixer == NULL) return -EIO; + mutex_lock(&mixer->reg_mutex); if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */ result = mixer->mask_recsrc; } else { @@ -172,6 +177,7 @@ static int snd_mixer_oss_recmask(struct result |= 1 << chn; } } + mutex_unlock(&mixer->reg_mutex); return result; }
@@ -182,12 +188,12 @@ static int snd_mixer_oss_get_recsrc(stru
if (mixer == NULL) return -EIO; + mutex_lock(&mixer->reg_mutex); if (mixer->put_recsrc && mixer->get_recsrc) { /* exclusive */ - int err; unsigned int index; - err = mixer->get_recsrc(fmixer, &index); - if (err < 0) - return err; + result = mixer->get_recsrc(fmixer, &index); + if (result < 0) + goto unlock; result = 1 << index; } else { struct snd_mixer_oss_slot *pslot; @@ -202,7 +208,10 @@ static int snd_mixer_oss_get_recsrc(stru } } } - return mixer->oss_recsrc = result; + mixer->oss_recsrc = result; + unlock: + mutex_unlock(&mixer->reg_mutex); + return result; }
static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsrc) @@ -215,6 +224,7 @@ static int snd_mixer_oss_set_recsrc(stru
if (mixer == NULL) return -EIO; + mutex_lock(&mixer->reg_mutex); if (mixer->get_recsrc && mixer->put_recsrc) { /* exclusive input */ if (recsrc & ~mixer->oss_recsrc) recsrc &= ~mixer->oss_recsrc; @@ -240,6 +250,7 @@ static int snd_mixer_oss_set_recsrc(stru } } } + mutex_unlock(&mixer->reg_mutex); return result; }
@@ -251,6 +262,7 @@ static int snd_mixer_oss_get_volume(stru
if (mixer == NULL || slot > 30) return -EIO; + mutex_lock(&mixer->reg_mutex); pslot = &mixer->slots[slot]; left = pslot->volume[0]; right = pslot->volume[1]; @@ -258,15 +270,21 @@ static int snd_mixer_oss_get_volume(stru result = pslot->get_volume(fmixer, pslot, &left, &right); if (!pslot->stereo) right = left; - if (snd_BUG_ON(left < 0 || left > 100)) - return -EIO; - if (snd_BUG_ON(right < 0 || right > 100)) - return -EIO; + if (snd_BUG_ON(left < 0 || left > 100)) { + result = -EIO; + goto unlock; + } + if (snd_BUG_ON(right < 0 || right > 100)) { + result = -EIO; + goto unlock; + } if (result >= 0) { pslot->volume[0] = left; pslot->volume[1] = right; result = (left & 0xff) | ((right & 0xff) << 8); } + unlock: + mutex_unlock(&mixer->reg_mutex); return result; }
@@ -279,6 +297,7 @@ static int snd_mixer_oss_set_volume(stru
if (mixer == NULL || slot > 30) return -EIO; + mutex_lock(&mixer->reg_mutex); pslot = &mixer->slots[slot]; if (left > 100) left = 100; @@ -289,10 +308,13 @@ static int snd_mixer_oss_set_volume(stru if (pslot->put_volume) result = pslot->put_volume(fmixer, pslot, left, right); if (result < 0) - return result; + goto unlock; pslot->volume[0] = left; pslot->volume[1] = right; - return (left & 0xff) | ((right & 0xff) << 8); + result = (left & 0xff) | ((right & 0xff) << 8); + unlock: + mutex_lock(&mixer->reg_mutex); + return result; }
static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int cmd, unsigned long arg)
From: Pavel Skripkin paskripkin@gmail.com
commit 3ab7992018455ac63c33e9b3eaa7264e293e40f4 upstream.
In commit 411cef6adfb3 ("ALSA: mixer: oss: Fix racy access to slots") added mutex protection in snd_mixer_oss_set_volume(). Second mutex_lock() in same function looks like typo, fix it.
Reported-by: syzbot+ace149a75a9a0a399ac7@syzkaller.appspotmail.com Fixes: 411cef6adfb3 ("ALSA: mixer: oss: Fix racy access to slots") Cc: stable@vger.kernel.org Signed-off-by: Pavel Skripkin paskripkin@gmail.com Link: https://lore.kernel.org/r/20211024140315.16704-1-paskripkin@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/core/oss/mixer_oss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -313,7 +313,7 @@ static int snd_mixer_oss_set_volume(stru pslot->volume[1] = right; result = (left & 0xff) | ((right & 0xff) << 8); unlock: - mutex_lock(&mixer->reg_mutex); + mutex_unlock(&mixer->reg_mutex); return result; }
From: Jason Ormes skryking@gmail.com
commit 8f27b689066113a3e579d4df171c980c54368c4e upstream.
Adding the Line6 HX-Stomp XL USB_ID as it needs this fixed frequency quirk as well.
The device is basically just the HX-Stomp with some more buttons on the face. I've done some recording with it after adding it, and it seems to function properly with this fix. The Midi features appear to be working as well.
[ a coding style fix and patch reformat by tiwai ]
Signed-off-by: Jason Ormes skryking@gmail.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211030200405.1358678-1-skryking@gmail.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/format.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -414,6 +414,7 @@ static int line6_parse_audio_format_rate case USB_ID(0x0e41, 0x4242): /* Line6 Helix Rack */ case USB_ID(0x0e41, 0x4244): /* Line6 Helix LT */ case USB_ID(0x0e41, 0x4246): /* Line6 HX-Stomp */ + case USB_ID(0x0e41, 0x4253): /* Line6 HX-Stomp XL */ case USB_ID(0x0e41, 0x4247): /* Line6 Pod Go */ case USB_ID(0x0e41, 0x4248): /* Line6 Helix >= fw 2.82 */ case USB_ID(0x0e41, 0x4249): /* Line6 Helix Rack >= fw 2.82 */
From: Alexander Tsoy alexander@tsoy.me
commit 763d92ed5dece7d439fc28a88b2d2728d525ffd9 upstream.
Add another device ID for JBL Quantum 400. It requires the same quirk as other JBL Quantum devices.
Signed-off-by: Alexander Tsoy alexander@tsoy.me Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211030174308.1011825-1-alexander@tsoy.me Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/usb/quirks.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1749,6 +1749,7 @@ static const struct registration_quirk r REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */ REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */ REG_QUIRK_ENTRY(0x0ecb, 0x1f47, 2), /* JBL Quantum 800 */ + REG_QUIRK_ENTRY(0x0ecb, 0x1f4c, 2), /* JBL Quantum 400 */ REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */ REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */ REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */
From: Takashi Iwai tiwai@suse.de
commit 39173303c83859723dab32c2abfb97296d6af3bf upstream.
The recent change in hda-intel driver to allow repeated probes surfaced a problem that has been hidden until; the probe process in the work calls azx_free() at the error path, and this skips the card free process that eventually releases codec instances. As a result, we get a kernel WARNING like:
snd_hda_intel 0000:00:1f.3: Cannot probe codecs, giving up ------------[ cut here ]------------ WARNING: CPU: 14 PID: 186 at sound/hda/hdac_bus.c:73 ....
For fixing this, we need to call snd_card_free() instead of azx_free(). Additionally, the device drvdata has to be cleared, as the driver binding itself is still active. Then the PM and other driver callbacks will ignore the procedure.
Fixes: c0f1886de7e1 ("ALSA: hda: intel: Allow repeatedly probing on codec configuration errors") Reported-and-tested-by: Scott Branden scott.branden@broadcom.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/063e2397-7edb-5f48-7b0d-618b938d9dd8@broadcom.com Link: https://lore.kernel.org/r/20211110194633.19098-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/hda/hda_intel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2330,7 +2330,8 @@ static int azx_probe_continue(struct azx
out_free: if (err < 0) { - azx_free(chip); + pci_set_drvdata(pci, NULL); + snd_card_free(chip->card); return err; }
From: Austin Kim austin.kim@lge.com
commit d159037abbe3412285c271bdfb9cdf19e62678ff upstream.
If kcalloc() return NULL due to memory starvation, it is possible for kstrdup() to return NULL in similar case. So add null check after the call to kstrdup() is made.
[ minor coding-style fix by tiwai ]
Signed-off-by: Austin Kim austin.kim@lge.com Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211109003742.GA5423@raspberrypi Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/synth/emux/emux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/sound/synth/emux/emux.c +++ b/sound/synth/emux/emux.c @@ -88,7 +88,7 @@ int snd_emux_register(struct snd_emux *e emu->name = kstrdup(name, GFP_KERNEL); emu->voices = kcalloc(emu->max_voices, sizeof(struct snd_emux_voice), GFP_KERNEL); - if (emu->voices == NULL) + if (emu->name == NULL || emu->voices == NULL) return -ENOMEM;
/* create soundfont list */
From: Takashi Iwai tiwai@suse.de
commit 43d35ccc36dad52377dd349b2e3ea803b72c3906 upstream.
The recent fix for setting up the DMA buffer type on RME drivers tried to address the non-standard memory managements and changed the DMA buffer information to the standard snd_dma_buffer object that is allocated at the probe time. However, I overlooked that the RME drivers handle the buffer addresses based on 64k alignment, and the previous conversion broke that silently.
This patch is an attempt to fix the regression. The snd_dma_buffer objects are copied to the original data with the correction to the aligned accesses, and those are passed to snd_pcm_set_runtime_buffer() helpers instead. The original snd_dma_buffer objects are managed by devres, hence they'll be released automagically.
Fixes: 0899a7a23047 ("ALSA: pci: rme: Set up buffer type properly") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211108145752.30572-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/pci/rme9652/hdsp.c | 41 +++++++++++++++++++++++------------------ sound/pci/rme9652/rme9652.c | 41 +++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 36 deletions(-)
--- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -468,8 +468,11 @@ struct hdsp { unsigned char ss_out_channels; u32 io_loopback; /* output loopback channel states*/
- struct snd_dma_buffer *capture_dma_buf; - struct snd_dma_buffer *playback_dma_buf; + /* DMA buffers; those are copied instances from the original snd_dma_buf + * objects (which are managed via devres) for the address alignments + */ + struct snd_dma_buffer capture_dma_buf; + struct snd_dma_buffer playback_dma_buf; unsigned char *capture_buffer; /* suitably aligned address */ unsigned char *playback_buffer; /* suitably aligned address */
@@ -3764,30 +3767,32 @@ static void snd_hdsp_proc_init(struct hd
static int snd_hdsp_initialize_memory(struct hdsp *hdsp) { - unsigned long pb_bus, cb_bus; + struct snd_dma_buffer *capture_dma, *playback_dma;
- hdsp->capture_dma_buf = - snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES); - hdsp->playback_dma_buf = - snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES); - if (!hdsp->capture_dma_buf || !hdsp->playback_dma_buf) { + capture_dma = snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES); + playback_dma = snd_hammerfall_get_buffer(hdsp->pci, HDSP_DMA_AREA_BYTES); + if (!capture_dma || !playback_dma) { dev_err(hdsp->card->dev, "%s: no buffers available\n", hdsp->card_name); return -ENOMEM; }
- /* Align to bus-space 64K boundary */ + /* copy to the own data for alignment */ + hdsp->capture_dma_buf = *capture_dma; + hdsp->playback_dma_buf = *playback_dma;
- cb_bus = ALIGN(hdsp->capture_dma_buf->addr, 0x10000ul); - pb_bus = ALIGN(hdsp->playback_dma_buf->addr, 0x10000ul); + /* Align to bus-space 64K boundary */ + hdsp->capture_dma_buf.addr = ALIGN(capture_dma->addr, 0x10000ul); + hdsp->playback_dma_buf.addr = ALIGN(playback_dma->addr, 0x10000ul);
/* Tell the card where it is */ + hdsp_write(hdsp, HDSP_inputBufferAddress, hdsp->capture_dma_buf.addr); + hdsp_write(hdsp, HDSP_outputBufferAddress, hdsp->playback_dma_buf.addr);
- hdsp_write(hdsp, HDSP_inputBufferAddress, cb_bus); - hdsp_write(hdsp, HDSP_outputBufferAddress, pb_bus); - - hdsp->capture_buffer = hdsp->capture_dma_buf->area + (cb_bus - hdsp->capture_dma_buf->addr); - hdsp->playback_buffer = hdsp->playback_dma_buf->area + (pb_bus - hdsp->playback_dma_buf->addr); + hdsp->capture_dma_buf.area += hdsp->capture_dma_buf.addr - capture_dma->addr; + hdsp->playback_dma_buf.area += hdsp->playback_dma_buf.addr - playback_dma->addr; + hdsp->capture_buffer = hdsp->capture_dma_buf.area; + hdsp->playback_buffer = hdsp->playback_dma_buf.area;
return 0; } @@ -4507,7 +4512,7 @@ static int snd_hdsp_playback_open(struct snd_pcm_set_sync(substream);
runtime->hw = snd_hdsp_playback_subinfo; - snd_pcm_set_runtime_buffer(substream, hdsp->playback_dma_buf); + snd_pcm_set_runtime_buffer(substream, &hdsp->playback_dma_buf);
hdsp->playback_pid = current->pid; hdsp->playback_substream = substream; @@ -4583,7 +4588,7 @@ static int snd_hdsp_capture_open(struct snd_pcm_set_sync(substream);
runtime->hw = snd_hdsp_capture_subinfo; - snd_pcm_set_runtime_buffer(substream, hdsp->capture_dma_buf); + snd_pcm_set_runtime_buffer(substream, &hdsp->capture_dma_buf);
hdsp->capture_pid = current->pid; hdsp->capture_substream = substream; --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -208,8 +208,11 @@ struct snd_rme9652 { unsigned char ds_channels; unsigned char ss_channels; /* different for hammerfall/hammerfall-light */
- struct snd_dma_buffer *playback_dma_buf; - struct snd_dma_buffer *capture_dma_buf; + /* DMA buffers; those are copied instances from the original snd_dma_buf + * objects (which are managed via devres) for the address alignments + */ + struct snd_dma_buffer playback_dma_buf; + struct snd_dma_buffer capture_dma_buf;
unsigned char *capture_buffer; /* suitably aligned address */ unsigned char *playback_buffer; /* suitably aligned address */ @@ -1719,30 +1722,32 @@ static void snd_rme9652_card_free(struct
static int snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652) { - unsigned long pb_bus, cb_bus; + struct snd_dma_buffer *capture_dma, *playback_dma;
- rme9652->capture_dma_buf = - snd_hammerfall_get_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES); - rme9652->playback_dma_buf = - snd_hammerfall_get_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES); - if (!rme9652->capture_dma_buf || !rme9652->playback_dma_buf) { + capture_dma = snd_hammerfall_get_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES); + playback_dma = snd_hammerfall_get_buffer(rme9652->pci, RME9652_DMA_AREA_BYTES); + if (!capture_dma || !playback_dma) { dev_err(rme9652->card->dev, "%s: no buffers available\n", rme9652->card_name); return -ENOMEM; }
- /* Align to bus-space 64K boundary */ + /* copy to the own data for alignment */ + rme9652->capture_dma_buf = *capture_dma; + rme9652->playback_dma_buf = *playback_dma;
- cb_bus = ALIGN(rme9652->capture_dma_buf->addr, 0x10000ul); - pb_bus = ALIGN(rme9652->playback_dma_buf->addr, 0x10000ul); + /* Align to bus-space 64K boundary */ + rme9652->capture_dma_buf.addr = ALIGN(capture_dma->addr, 0x10000ul); + rme9652->playback_dma_buf.addr = ALIGN(playback_dma->addr, 0x10000ul);
/* Tell the card where it is */ + rme9652_write(rme9652, RME9652_rec_buffer, rme9652->capture_dma_buf.addr); + rme9652_write(rme9652, RME9652_play_buffer, rme9652->playback_dma_buf.addr);
- rme9652_write(rme9652, RME9652_rec_buffer, cb_bus); - rme9652_write(rme9652, RME9652_play_buffer, pb_bus); - - rme9652->capture_buffer = rme9652->capture_dma_buf->area + (cb_bus - rme9652->capture_dma_buf->addr); - rme9652->playback_buffer = rme9652->playback_dma_buf->area + (pb_bus - rme9652->playback_dma_buf->addr); + rme9652->capture_dma_buf.area += rme9652->capture_dma_buf.addr - capture_dma->addr; + rme9652->playback_dma_buf.area += rme9652->playback_dma_buf.addr - playback_dma->addr; + rme9652->capture_buffer = rme9652->capture_dma_buf.area; + rme9652->playback_buffer = rme9652->playback_dma_buf.area;
return 0; } @@ -2259,7 +2264,7 @@ static int snd_rme9652_playback_open(str snd_pcm_set_sync(substream);
runtime->hw = snd_rme9652_playback_subinfo; - snd_pcm_set_runtime_buffer(substream, rme9652->playback_dma_buf); + snd_pcm_set_runtime_buffer(substream, &rme9652->playback_dma_buf);
if (rme9652->capture_substream == NULL) { rme9652_stop(rme9652); @@ -2318,7 +2323,7 @@ static int snd_rme9652_capture_open(stru snd_pcm_set_sync(substream);
runtime->hw = snd_rme9652_capture_subinfo; - snd_pcm_set_runtime_buffer(substream, rme9652->capture_dma_buf); + snd_pcm_set_runtime_buffer(substream, &rme9652->capture_dma_buf);
if (rme9652->playback_substream == NULL) { rme9652_stop(rme9652);
From: Takashi Iwai tiwai@suse.de
commit 8e537d5dec34cac746dd6abf6a83e5de3aa471fc upstream.
The recent refactoring of mmap handling caused Oops on some devices that don't use the standard memory allocations. This patch addresses it by allowing snd_dma_buffer_mmap() helper to receive the NULL pointer dmab argument (and return an error appropriately).
Fixes: a202bd1ad86d ("ALSA: core: Move mmap handler into memalloc ops") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211107163911.13534-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/core/memalloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -176,8 +176,11 @@ EXPORT_SYMBOL_GPL(snd_devm_alloc_pages); int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab, struct vm_area_struct *area) { - const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab); + const struct snd_malloc_ops *ops;
+ if (!dmab) + return -ENOENT; + ops = snd_dma_get_ops(dmab); if (ops && ops->mmap) return ops->mmap(dmab, area); else
From: Wang Wensheng wangwensheng4@huawei.com
commit c0317c0e87094f5b5782b6fdef5ae0a4b150496c upstream.
When the timer instance was add into ack_list but was not currently in process, the user could stop it via snd_timer_stop1() without delete it from the ack_list. Then the user could free the timer instance and when it was actually processed UAF occurred.
This issue could be reproduced via testcase snd_timer01 in ltp - running several instances of that testcase at the same time.
What I actually met was that the ack_list of the timer broken and the kernel went into deadloop with irqoff. That could be detected by hardlockup detector on board or when we run it on qemu, we could use gdb to dump the ack_list when the console has no response.
To fix this issue, we delete the timer instance from ack_list and active_list unconditionally in snd_timer_stop1().
Signed-off-by: Wang Wensheng wangwensheng4@huawei.com Suggested-by: Takashi Iwai tiwai@suse.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211103033517.80531-1-wangwensheng4@huawei.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/core/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -624,13 +624,13 @@ static int snd_timer_stop1(struct snd_ti if (!timer) return -EINVAL; spin_lock_irqsave(&timer->lock, flags); + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START))) { result = -EBUSY; goto unlock; } - list_del_init(&timeri->ack_list); - list_del_init(&timeri->active_list); if (timer->card && timer->card->shutdown) goto unlock; if (stop) {
From: Takashi Iwai tiwai@suse.de
commit ffdd98277f0a1d15a67a74ae09bee713df4c0dbc upstream.
Like the previous fix (commit c0317c0e8709 "ALSA: timer: Fix use-after-free problem"), we have to unlink slave timer instances immediately at snd_timer_stop(), too. Otherwise it may leave a stale entry in the list if the slave instance is freed before actually running.
Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211105091517.21733-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/core/timer.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
--- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -665,23 +665,22 @@ static int snd_timer_stop1(struct snd_ti static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop) { unsigned long flags; + bool running;
spin_lock_irqsave(&slave_active_lock, flags); - if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { - spin_unlock_irqrestore(&slave_active_lock, flags); - return -EBUSY; - } + running = timeri->flags & SNDRV_TIMER_IFLG_RUNNING; timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; if (timeri->timer) { spin_lock(&timeri->timer->lock); list_del_init(&timeri->ack_list); list_del_init(&timeri->active_list); - snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : - SNDRV_TIMER_EVENT_PAUSE); + if (running) + snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : + SNDRV_TIMER_EVENT_PAUSE); spin_unlock(&timeri->timer->lock); } spin_unlock_irqrestore(&slave_active_lock, flags); - return 0; + return running ? 0 : -EBUSY; }
/*
From: Eric Whitney enwlinux@gmail.com
commit 3eda41df05d6ad5c825cbc7fef03d563597b1afa upstream.
This reverts commit 948ca5f30e1df0c11eb5b0f410b9ceb97fa77ad9.
Two crash reports from users running variations on 5.15-rc4 kernels suggest that it is premature to enforce the state assertion in the original commit. Both crashes were triggered by BUG calls in that code, indicating that under some rare circumstance the buffer head state did not match a delayed allocated block at the time the block was written out. No reproducer is available. Resolving this problem will require more time than remains in the current release cycle, so reverting the original patch for the time being is necessary to avoid any instability it may cause.
Signed-off-by: Eric Whitney enwlinux@gmail.com Link: https://lore.kernel.org/r/20211012171901.5352-1-enwlinux@gmail.com Fixes: 948ca5f30e1d ("ext4: enforce buffer head state assertion in ext4_da_map_blocks") Signed-off-by: Theodore Ts'o tytso@mit.edu Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/inode.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
--- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1711,16 +1711,13 @@ static int ext4_da_map_blocks(struct ino }
/* - * the buffer head associated with a delayed and not unwritten - * block found in the extent status cache must contain an - * invalid block number and have its BH_New and BH_Delay bits - * set, reflecting the state assigned when the block was - * initially delayed allocated + * Delayed extent could be allocated by fallocate. + * So we need to check it. */ - if (ext4_es_is_delonly(&es)) { - BUG_ON(bh->b_blocknr != invalid_block); - BUG_ON(!buffer_new(bh)); - BUG_ON(!buffer_delay(bh)); + if (ext4_es_is_delayed(&es) && !ext4_es_is_unwritten(&es)) { + map_bh(bh, inode->i_sb, invalid_block); + set_buffer_new(bh); + set_buffer_delay(bh); return 0; }
From: Shaoying Xu shaoyi@amazon.com
commit 39fec6889d15a658c3a3ebb06fd69d3584ddffd3 upstream.
Ext4 file system has default lazy inode table initialization setup once it is mounted. However, it has issue on computing the next schedule time that makes the timeout same amount in jiffies but different real time in secs if with various HZ values. Therefore, fix by measuring the current time in a more granular unit nanoseconds and make the next schedule time independent of the HZ value.
Fixes: bfff68738f1c ("ext4: add support for lazy inode table initialization") Signed-off-by: Shaoying Xu shaoyi@amazon.com Cc: stable@vger.kernel.org Signed-off-by: Theodore Ts'o tytso@mit.edu Link: https://lore.kernel.org/r/20210902164412.9994-2-shaoyi@amazon.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/super.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
--- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3263,9 +3263,9 @@ static int ext4_run_li_request(struct ex struct super_block *sb = elr->lr_super; ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; ext4_group_t group = elr->lr_next_group; - unsigned long timeout = 0; unsigned int prefetch_ios = 0; int ret = 0; + u64 start_time;
if (elr->lr_mode == EXT4_LI_MODE_PREFETCH_BBITMAP) { elr->lr_next_group = ext4_mb_prefetch(sb, group, @@ -3302,14 +3302,13 @@ static int ext4_run_li_request(struct ex ret = 1;
if (!ret) { - timeout = jiffies; + start_time = ktime_get_real_ns(); ret = ext4_init_inode_table(sb, group, elr->lr_timeout ? 0 : 1); trace_ext4_lazy_itable_init(sb, group); if (elr->lr_timeout == 0) { - timeout = (jiffies - timeout) * - EXT4_SB(elr->lr_super)->s_li_wait_mult; - elr->lr_timeout = timeout; + elr->lr_timeout = nsecs_to_jiffies((ktime_get_real_ns() - start_time) * + EXT4_SB(elr->lr_super)->s_li_wait_mult); } elr->lr_next_sched = jiffies + elr->lr_timeout; elr->lr_next_group = group + 1;
From: yangerkun yangerkun@huawei.com
commit 4268496e48dc681cfa53b92357314b5d7221e625 upstream.
Like ext4_ext_rm_leaf, we can ensure that there are enough credits before every call that will consume credits. As part of this fix we fold the functionality of ext4_access_path() into ext4_ext_shift_path_extents(). This change is needed as a preparation for the next bugfix patch.
Cc: stable@kernel.org Link: https://lore.kernel.org/r/20210903062748.4118886-3-yangerkun@huawei.com Signed-off-by: yangerkun yangerkun@huawei.com Reviewed-by: Jan Kara jack@suse.cz Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/extents.c | 49 +++++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 34 deletions(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4978,36 +4978,6 @@ int ext4_get_es_cache(struct inode *inod }
/* - * ext4_access_path: - * Function to access the path buffer for marking it dirty. - * It also checks if there are sufficient credits left in the journal handle - * to update path. - */ -static int -ext4_access_path(handle_t *handle, struct inode *inode, - struct ext4_ext_path *path) -{ - int credits, err; - - if (!ext4_handle_valid(handle)) - return 0; - - /* - * Check if need to extend journal credits - * 3 for leaf, sb, and inode plus 2 (bmap and group - * descriptor) for each block group; assume two block - * groups - */ - credits = ext4_writepage_trans_blocks(inode); - err = ext4_datasem_ensure_credits(handle, inode, 7, credits, 0); - if (err < 0) - return err; - - err = ext4_ext_get_access(handle, inode, path); - return err; -} - -/* * ext4_ext_shift_path_extents: * Shift the extents of a path structure lying between path[depth].p_ext * and EXT_LAST_EXTENT(path[depth].p_hdr), by @shift blocks. @SHIFT tells @@ -5021,6 +4991,7 @@ ext4_ext_shift_path_extents(struct ext4_ int depth, err = 0; struct ext4_extent *ex_start, *ex_last; bool update = false; + int credits, restart_credits; depth = path->p_depth;
while (depth >= 0) { @@ -5030,13 +5001,23 @@ ext4_ext_shift_path_extents(struct ext4_ return -EFSCORRUPTED;
ex_last = EXT_LAST_EXTENT(path[depth].p_hdr); + /* leaf + sb + inode */ + credits = 3; + if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) { + update = true; + /* extent tree + sb + inode */ + credits = depth + 2; + }
- err = ext4_access_path(handle, inode, path + depth); + restart_credits = ext4_writepage_trans_blocks(inode); + err = ext4_datasem_ensure_credits(handle, inode, credits, + restart_credits, 0); if (err) goto out;
- if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) - update = true; + err = ext4_ext_get_access(handle, inode, path + depth); + if (err) + goto out;
while (ex_start <= ex_last) { if (SHIFT == SHIFT_LEFT) { @@ -5067,7 +5048,7 @@ ext4_ext_shift_path_extents(struct ext4_ }
/* Update index too */ - err = ext4_access_path(handle, inode, path + depth); + err = ext4_ext_get_access(handle, inode, path + depth); if (err) goto out;
From: yangerkun yangerkun@huawei.com
commit 1811bc401aa58c7bdb0df3205aa6613b49d32127 upstream.
After we drop i_data sem, we need to reload the ext4_ext_path structure since the extent tree can change once i_data_sem is released.
This addresses the BUG:
[52117.465187] ------------[ cut here ]------------ [52117.465686] kernel BUG at fs/ext4/extents.c:1756! ... [52117.478306] Call Trace: [52117.478565] ext4_ext_shift_extents+0x3ee/0x710 [52117.479020] ext4_fallocate+0x139c/0x1b40 [52117.479405] ? __do_sys_newfstat+0x6b/0x80 [52117.479805] vfs_fallocate+0x151/0x4b0 [52117.480177] ksys_fallocate+0x4a/0xa0 [52117.480533] __x64_sys_fallocate+0x22/0x30 [52117.480930] do_syscall_64+0x35/0x80 [52117.481277] entry_SYSCALL_64_after_hwframe+0x44/0xae [52117.481769] RIP: 0033:0x7fa062f855ca
Cc: stable@kernel.org Link: https://lore.kernel.org/r/20210903062748.4118886-4-yangerkun@huawei.com Signed-off-by: yangerkun yangerkun@huawei.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ext4/extents.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
--- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5012,8 +5012,11 @@ ext4_ext_shift_path_extents(struct ext4_ restart_credits = ext4_writepage_trans_blocks(inode); err = ext4_datasem_ensure_credits(handle, inode, credits, restart_credits, 0); - if (err) + if (err) { + if (err > 0) + err = -EAGAIN; goto out; + }
err = ext4_ext_get_access(handle, inode, path + depth); if (err) @@ -5087,6 +5090,7 @@ ext4_ext_shift_extents(struct inode *ino int ret = 0, depth; struct ext4_extent *extent; ext4_lblk_t stop, *iterator, ex_start, ex_end; + ext4_lblk_t tmp = EXT_MAX_BLOCKS;
/* Let path point to the last extent */ path = ext4_find_extent(inode, EXT_MAX_BLOCKS - 1, NULL, @@ -5140,11 +5144,15 @@ ext4_ext_shift_extents(struct inode *ino * till we reach stop. In case of right shift, iterator points to stop * and it is decreased till we reach start. */ +again: if (SHIFT == SHIFT_LEFT) iterator = &start; else iterator = &stop;
+ if (tmp != EXT_MAX_BLOCKS) + *iterator = tmp; + /* * Its safe to start updating extents. Start and stop are unsigned, so * in case of right shift if extent with 0 block is reached, iterator @@ -5173,6 +5181,7 @@ ext4_ext_shift_extents(struct inode *ino } }
+ tmp = *iterator; if (SHIFT == SHIFT_LEFT) { extent = EXT_LAST_EXTENT(path[depth].p_hdr); *iterator = le32_to_cpu(extent->ee_block) + @@ -5191,6 +5200,9 @@ ext4_ext_shift_extents(struct inode *ino } ret = ext4_ext_shift_path_extents(path, shift, inode, handle, SHIFT); + /* iterator can be NULL which means we should break */ + if (ret == -EAGAIN) + goto again; if (ret) break; }
From: Miklos Szeredi mszeredi@redhat.com
commit 712a951025c0667ff00b25afc360f74e639dfabe upstream.
It is possible to trigger a crash by splicing anon pipe bufs to the fuse device.
The reason for this is that anon_pipe_buf_release() will reuse buf->page if the refcount is 1, but that page might have already been stolen and its flags modified (e.g. PG_lru added).
This happens in the unlikely case of fuse_dev_splice_write() getting around to calling pipe_buf_release() after a page has been stolen, added to the page cache and removed from the page cache.
Fix by calling pipe_buf_release() right after the page was inserted into the page cache. In this case the page has an elevated refcount so any release function will know that the page isn't reusable.
Reported-by: Frank Dinoff fdinoff@google.com Link: https://lore.kernel.org/r/CAAmZXrsGg2xsP1CK+cbuEMumtrqdvD-NKnWzhNcvn71RV3c1y... Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device") Cc: stable@vger.kernel.org # v2.6.35 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/dev.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
--- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -847,6 +847,12 @@ static int fuse_try_move_page(struct fus
replace_page_cache_page(oldpage, newpage);
+ /* + * Release while we have extra ref on stolen page. Otherwise + * anon_pipe_buf_release() might think the page can be reused. + */ + pipe_buf_release(cs->pipe, buf); + get_page(newpage);
if (!(buf->flags & PIPE_BUF_FLAG_LRU)) @@ -2031,8 +2037,12 @@ static ssize_t fuse_dev_splice_write(str
pipe_lock(pipe); out_free: - for (idx = 0; idx < nbuf; idx++) - pipe_buf_release(pipe, &bufs[idx]); + for (idx = 0; idx < nbuf; idx++) { + struct pipe_buffer *buf = &bufs[idx]; + + if (buf->ops) + pipe_buf_release(pipe, buf); + } pipe_unlock(pipe);
kvfree(bufs);
On Mon, Nov 15, 2021 at 7:04 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
From: Miklos Szeredi mszeredi@redhat.com
commit 712a951025c0667ff00b25afc360f74e639dfabe upstream.
It is possible to trigger a crash by splicing anon pipe bufs to the fuse device.
The reason for this is that anon_pipe_buf_release() will reuse buf->page if the refcount is 1, but that page might have already been stolen and its flags modified (e.g. PG_lru added).
This happens in the unlikely case of fuse_dev_splice_write() getting around to calling pipe_buf_release() after a page has been stolen, added to the page cache and removed from the page cache.
Fix by calling pipe_buf_release() right after the page was inserted into the page cache. In this case the page has an elevated refcount so any release function will know that the page isn't reusable.
Reported-by: Frank Dinoff fdinoff@google.com Link: https://lore.kernel.org/r/CAAmZXrsGg2xsP1CK+cbuEMumtrqdvD-NKnWzhNcvn71RV3c1y... Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device") Cc: stable@vger.kernel.org # v2.6.35 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
It appears this patch causes a rather serious regression in flatpacks using portals to access files. Reverting this patch restores expected behavior. I have asked users in the Fedora bug to test with 5.16-rc2 to see if we are just missing a dependent patch in stable, or if this is broken there as well, but no response yet.:
https://bugzilla.redhat.com/show_bug.cgi?id=2025285 https://github.com/flatpak/flatpak/issues/4595
Justin
Justin
On Tue, Nov 23, 2021 at 7:29 PM Justin Forbes jmforbes@linuxtx.org wrote:
On Mon, Nov 15, 2021 at 7:04 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
From: Miklos Szeredi mszeredi@redhat.com
commit 712a951025c0667ff00b25afc360f74e639dfabe upstream.
It is possible to trigger a crash by splicing anon pipe bufs to the fuse device.
The reason for this is that anon_pipe_buf_release() will reuse buf->page if the refcount is 1, but that page might have already been stolen and its flags modified (e.g. PG_lru added).
This happens in the unlikely case of fuse_dev_splice_write() getting around to calling pipe_buf_release() after a page has been stolen, added to the page cache and removed from the page cache.
Fix by calling pipe_buf_release() right after the page was inserted into the page cache. In this case the page has an elevated refcount so any release function will know that the page isn't reusable.
Reported-by: Frank Dinoff fdinoff@google.com Link: https://lore.kernel.org/r/CAAmZXrsGg2xsP1CK+cbuEMumtrqdvD-NKnWzhNcvn71RV3c1y... Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device") Cc: stable@vger.kernel.org # v2.6.35 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
It appears this patch causes a rather serious regression in flatpacks using portals to access files. Reverting this patch restores expected behavior. I have asked users in the Fedora bug to test with 5.16-rc2 to see if we are just missing a dependent patch in stable, or if this is broken there as well, but no response yet.:
https://bugzilla.redhat.com/show_bug.cgi?id=2025285 https://github.com/flatpak/flatpak/issues/4595
Hi,
Thanks for the report. Can someone with the reproducer try the attached patch?
I think the race there is unlikely but possible.
Thanks, Miklos
On Tue, Nov 23, 2021 at 1:22 PM Miklos Szeredi mszeredi@redhat.com wrote:
On Tue, Nov 23, 2021 at 7:29 PM Justin Forbes jmforbes@linuxtx.org wrote:
On Mon, Nov 15, 2021 at 7:04 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
From: Miklos Szeredi mszeredi@redhat.com
commit 712a951025c0667ff00b25afc360f74e639dfabe upstream.
It is possible to trigger a crash by splicing anon pipe bufs to the fuse device.
The reason for this is that anon_pipe_buf_release() will reuse buf->page if the refcount is 1, but that page might have already been stolen and its flags modified (e.g. PG_lru added).
This happens in the unlikely case of fuse_dev_splice_write() getting around to calling pipe_buf_release() after a page has been stolen, added to the page cache and removed from the page cache.
Fix by calling pipe_buf_release() right after the page was inserted into the page cache. In this case the page has an elevated refcount so any release function will know that the page isn't reusable.
Reported-by: Frank Dinoff fdinoff@google.com Link: https://lore.kernel.org/r/CAAmZXrsGg2xsP1CK+cbuEMumtrqdvD-NKnWzhNcvn71RV3c1y... Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device") Cc: stable@vger.kernel.org # v2.6.35 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
It appears this patch causes a rather serious regression in flatpacks using portals to access files. Reverting this patch restores expected behavior. I have asked users in the Fedora bug to test with 5.16-rc2 to see if we are just missing a dependent patch in stable, or if this is broken there as well, but no response yet.:
https://bugzilla.redhat.com/show_bug.cgi?id=2025285 https://github.com/flatpak/flatpak/issues/4595
Hi,
Thanks for the report. Can someone with the reproducer try the attached patch?
I think the race there is unlikely but possible.
Thanks, did a scratch build for that and dropped it in the bug. Only one user has reported back, but the report was that it did not fix the issue. I have also gotten confirmation now that the issue is occuring with 5.16-rc2.
Thanks, Justin
On Wed, Nov 24, 2021 at 1:40 AM Justin Forbes jmforbes@linuxtx.org wrote:
Thanks, did a scratch build for that and dropped it in the bug. Only one user has reported back, but the report was that it did not fix the issue. I have also gotten confirmation now that the issue is occuring with 5.16-rc2.
Okay.
Morning light brings clarity to the mind. Here's a patch that should definitely fix this bug, as well as the very unlikely race of the page being truncated from the page cache before pipe_buf_release() is called.
Please test.
Thanks, Miklos
On Wed, Nov 24, 2021 at 3:23 AM Miklos Szeredi mszeredi@redhat.com wrote:
On Wed, Nov 24, 2021 at 1:40 AM Justin Forbes jmforbes@linuxtx.org wrote:
Thanks, did a scratch build for that and dropped it in the bug. Only one user has reported back, but the report was that it did not fix the issue. I have also gotten confirmation now that the issue is occuring with 5.16-rc2.
Okay.
Morning light brings clarity to the mind. Here's a patch that should definitely fix this bug, as well as the very unlikely race of the page being truncated from the page cache before pipe_buf_release() is called.
Please test.
Thanks, did a scratch build. and multiple users have reported back saying that this patch does in fact fix the issue.
Justin
From: Tom Lendacky thomas.lendacky@amd.com
commit e7d445ab26db833d6640d4c9a08bee176777cc82 upstream.
When runtime support for converting between 4-level and 5-level pagetables was added to the kernel, the SME code that built pagetables was updated to use the pagetable functions, e.g. p4d_offset(), etc., in order to simplify the code. However, the use of the pagetable functions in early boot code requires the use of the USE_EARLY_PGTABLE_L5 #define in order to ensure that the proper definition of pgtable_l5_enabled() is used.
Without the #define, pgtable_l5_enabled() is #defined as cpu_feature_enabled(X86_FEATURE_LA57). In early boot, the CPU features have not yet been discovered and populated, so pgtable_l5_enabled() will return false even when 5-level paging is enabled. This causes the SME code to always build 4-level pagetables to perform the in-place encryption. If 5-level paging is enabled, switching to the SME pagetables results in a page-fault that kills the boot.
Adding the #define results in pgtable_l5_enabled() using the __pgtable_l5_enabled variable set in early boot and the SME code building pagetables for the proper paging level.
Fixes: aad983913d77 ("x86/mm/encrypt: Simplify sme_populate_pgd() and sme_populate_pgd_large()") Signed-off-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: stable@vger.kernel.org # 4.18.x Link: https://lkml.kernel.org/r/2cb8329655f5c753905812d951e212022a480475.163431865... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/mm/mem_encrypt_identity.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -27,6 +27,15 @@ #undef CONFIG_PARAVIRT_XXL #undef CONFIG_PARAVIRT_SPINLOCKS
+/* + * This code runs before CPU feature bits are set. By default, the + * pgtable_l5_enabled() function uses bit X86_FEATURE_LA57 to determine if + * 5-level paging is active, so that won't work here. USE_EARLY_PGTABLE_L5 + * is provided to handle this situation and, instead, use a variable that + * has been set by the early boot code. + */ +#define USE_EARLY_PGTABLE_L5 + #include <linux/kernel.h> #include <linux/mm.h> #include <linux/mem_encrypt.h>
From: Jane Malalane jane.malalane@citrix.com
commit 415de44076640483648d6c0f6d645a9ee61328ad upstream.
Currently, Linux probes for X86_BUG_NULL_SEL unconditionally which makes it unsafe to migrate in a virtualised environment as the properties across the migration pool might differ.
To be specific, the case which goes wrong is:
1. Zen1 (or earlier) and Zen2 (or later) in a migration pool 2. Linux boots on Zen2, probes and finds the absence of X86_BUG_NULL_SEL 3. Linux is then migrated to Zen1
Linux is now running on a X86_BUG_NULL_SEL-impacted CPU while believing that the bug is fixed.
The only way to address the problem is to fully trust the "no longer affected" CPUID bit when virtualised, because in the above case it would be clear deliberately to indicate the fact "you might migrate to somewhere which has this behaviour".
Zen3 adds the NullSelectorClearsBase CPUID bit to indicate that loading a NULL segment selector zeroes the base and limit fields, as well as just attributes. Zen2 also has this behaviour but doesn't have the NSCB bit.
[ bp: Minor touchups. ]
Signed-off-by: Jane Malalane jane.malalane@citrix.com Signed-off-by: Borislav Petkov bp@suse.de CC: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20211021104744.24126-1-jane.malalane@citrix.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/cpu/amd.c | 2 + arch/x86/kernel/cpu/common.c | 44 ++++++++++++++++++++++++++++++++++++------- arch/x86/kernel/cpu/cpu.h | 1 arch/x86/kernel/cpu/hygon.c | 2 + 4 files changed, 42 insertions(+), 7 deletions(-)
--- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -989,6 +989,8 @@ static void init_amd(struct cpuinfo_x86 if (cpu_has(c, X86_FEATURE_IRPERF) && !cpu_has_amd_erratum(c, amd_erratum_1054)) msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); + + check_null_seg_clears_base(c); }
#ifdef CONFIG_X86_32 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1396,9 +1396,8 @@ void __init early_cpu_init(void) early_identify_cpu(&boot_cpu_data); }
-static void detect_null_seg_behavior(struct cpuinfo_x86 *c) +static bool detect_null_seg_behavior(void) { -#ifdef CONFIG_X86_64 /* * Empirically, writing zero to a segment selector on AMD does * not clear the base, whereas writing zero to a segment @@ -1419,10 +1418,43 @@ static void detect_null_seg_behavior(str wrmsrl(MSR_FS_BASE, 1); loadsegment(fs, 0); rdmsrl(MSR_FS_BASE, tmp); - if (tmp != 0) - set_cpu_bug(c, X86_BUG_NULL_SEG); wrmsrl(MSR_FS_BASE, old_base); -#endif + return tmp == 0; +} + +void check_null_seg_clears_base(struct cpuinfo_x86 *c) +{ + /* BUG_NULL_SEG is only relevant with 64bit userspace */ + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + /* Zen3 CPUs advertise Null Selector Clears Base in CPUID. */ + if (c->extended_cpuid_level >= 0x80000021 && + cpuid_eax(0x80000021) & BIT(6)) + return; + + /* + * CPUID bit above wasn't set. If this kernel is still running + * as a HV guest, then the HV has decided not to advertize + * that CPUID bit for whatever reason. For example, one + * member of the migration pool might be vulnerable. Which + * means, the bug is present: set the BUG flag and return. + */ + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) { + set_cpu_bug(c, X86_BUG_NULL_SEG); + return; + } + + /* + * Zen2 CPUs also have this behaviour, but no CPUID bit. + * 0x18 is the respective family for Hygon. + */ + if ((c->x86 == 0x17 || c->x86 == 0x18) && + detect_null_seg_behavior()) + return; + + /* All the remaining ones are affected */ + set_cpu_bug(c, X86_BUG_NULL_SEG); }
static void generic_identify(struct cpuinfo_x86 *c) @@ -1458,8 +1490,6 @@ static void generic_identify(struct cpui
get_model_name(c); /* Default name */
- detect_null_seg_behavior(c); - /* * ESPFIX is a strange bug. All real CPUs have it. Paravirt * systems that run Linux at CPL > 0 may or may not have the --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -75,6 +75,7 @@ extern int detect_extended_topology_earl extern int detect_extended_topology(struct cpuinfo_x86 *c); extern int detect_ht_early(struct cpuinfo_x86 *c); extern void detect_ht(struct cpuinfo_x86 *c); +extern void check_null_seg_clears_base(struct cpuinfo_x86 *c);
unsigned int aperfmperf_get_khz(int cpu);
--- a/arch/x86/kernel/cpu/hygon.c +++ b/arch/x86/kernel/cpu/hygon.c @@ -335,6 +335,8 @@ static void init_hygon(struct cpuinfo_x8 /* Hygon CPUs don't reset SS attributes on SYSRET, Xen does. */ if (!cpu_has(c, X86_FEATURE_XENPV)) set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); + + check_null_seg_clears_base(c); }
static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
From: Sean Christopherson seanjc@google.com
commit 6ff53f6a438f72998f56e82e76694a1df9d1ea2c upstream.
Add a synchronize_rcu() after clearing the posted interrupt wakeup handler to ensure all readers, i.e. in-flight IRQ handlers, see the new handler before returning to the caller. If the caller is an exiting module and is unregistering its handler, failure to wait could result in the IRQ handler jumping into an unloaded module.
The registration path doesn't require synchronization, as it's the caller's responsibility to not generate interrupts it cares about until after its handler is registered.
Fixes: f6b3c72c2366 ("x86/irq: Define a global vector for VT-d Posted-Interrupts") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211009001107.3936588-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/irq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -291,8 +291,10 @@ void kvm_set_posted_intr_wakeup_handler( { if (handler) kvm_posted_intr_wakeup_handler = handler; - else + else { kvm_posted_intr_wakeup_handler = dummy_handler; + synchronize_rcu(); + } } EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wakeup_handler);
From: Peter Zijlstra peterz@infradead.org
commit b968e84b509da593c50dc3db679e1d33de701f78 upstream.
Since commit c8137ace5638 ("x86/iopl: Restrict iopl() permission scope") it's possible to emulate iopl(3) using ioperm(), except for the CLI/STI usage.
Userspace CLI/STI usage is very dubious (read broken), since any exception taken during that window can lead to rescheduling anyway (or worse). The IOPL(2) manpage even states that usage of CLI/STI is highly discouraged and might even crash the system.
Of course, that won't stop people and HP has the dubious honour of being the first vendor to be found using this in their hp-health package.
In order to enable this 'software' to still 'work', have the #GP treat the CLI/STI instructions as NOPs when iopl(3). Warn the user that their program is doing dubious things.
Fixes: a24ca9976843 ("x86/iopl: Remove legacy IOPL option") Reported-by: Ondrej Zary linux@zary.sk Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Thomas Gleixner tglx@linutronix.de Cc: stable@kernel.org # v5.5+ Link: https://lkml.kernel.org/r/20210918090641.GD5106@worktop.programming.kicks-as... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/insn-eval.h | 1 + arch/x86/include/asm/processor.h | 1 + arch/x86/kernel/process.c | 1 + arch/x86/kernel/traps.c | 33 +++++++++++++++++++++++++++++++++ arch/x86/lib/insn-eval.c | 2 +- 5 files changed, 37 insertions(+), 1 deletion(-)
--- a/arch/x86/include/asm/insn-eval.h +++ b/arch/x86/include/asm/insn-eval.h @@ -21,6 +21,7 @@ int insn_get_modrm_rm_off(struct insn *i int insn_get_modrm_reg_off(struct insn *insn, struct pt_regs *regs); unsigned long insn_get_seg_base(struct pt_regs *regs, int seg_reg_idx); int insn_get_code_seg_params(struct pt_regs *regs); +int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip); int insn_fetch_from_user(struct pt_regs *regs, unsigned char buf[MAX_INSN_SIZE]); int insn_fetch_from_user_inatomic(struct pt_regs *regs, --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -518,6 +518,7 @@ struct thread_struct { */ unsigned long iopl_emul;
+ unsigned int iopl_warn:1; unsigned int sig_on_uaccess_err:1;
/* --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -132,6 +132,7 @@ int copy_thread(unsigned long clone_flag frame->ret_addr = (unsigned long) ret_from_fork; p->thread.sp = (unsigned long) fork_frame; p->thread.io_bitmap = NULL; + p->thread.iopl_warn = 0; memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
#ifdef CONFIG_X86_64 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -528,6 +528,36 @@ static enum kernel_gp_hint get_kernel_gp
#define GPFSTR "general protection fault"
+static bool fixup_iopl_exception(struct pt_regs *regs) +{ + struct thread_struct *t = ¤t->thread; + unsigned char byte; + unsigned long ip; + + if (!IS_ENABLED(CONFIG_X86_IOPL_IOPERM) || t->iopl_emul != 3) + return false; + + if (insn_get_effective_ip(regs, &ip)) + return false; + + if (get_user(byte, (const char __user *)ip)) + return false; + + if (byte != 0xfa && byte != 0xfb) + return false; + + if (!t->iopl_warn && printk_ratelimit()) { + pr_err("%s[%d] attempts to use CLI/STI, pretending it's a NOP, ip:%lx", + current->comm, task_pid_nr(current), ip); + print_vma_addr(KERN_CONT " in ", ip); + pr_cont("\n"); + t->iopl_warn = 1; + } + + regs->ip += 1; + return true; +} + DEFINE_IDTENTRY_ERRORCODE(exc_general_protection) { char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR; @@ -553,6 +583,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_pr tsk = current;
if (user_mode(regs)) { + if (fixup_iopl_exception(regs)) + goto exit; + tsk->thread.error_code = error_code; tsk->thread.trap_nr = X86_TRAP_GP;
--- a/arch/x86/lib/insn-eval.c +++ b/arch/x86/lib/insn-eval.c @@ -1417,7 +1417,7 @@ void __user *insn_get_addr_ref(struct in } }
-static int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) +int insn_get_effective_ip(struct pt_regs *regs, unsigned long *ip) { unsigned long seg_base = 0;
From: Li Zhang zhanglikernel@gmail.com
commit 5d03dbebba2594d2e6fbf3b5dd9060c5a835de3b upstream.
Reported bug: https://github.com/kdave/btrfs-progs/issues/389
There's a problem with scrub reporting aborted status but returning error code 0, on a filesystem with missing and readded device.
Roughly these steps:
- mkfs -d raid1 dev1 dev2 - fill with data - unmount - make dev1 disappear - mount -o degraded - copy more data - make dev1 appear again
Running scrub afterwards reports that the command was aborted, but the system log message says the exit code was 0.
It seems that the cause of the error is decrementing fs_devices->missing_devices but not clearing device->dev_state. Every time we umount filesystem, it would call close_ctree, And it would eventually involve btrfs_close_one_device to close the device, but it only decrements fs_devices->missing_devices but does not clear the device BTRFS_DEV_STATE_MISSING bit. Worse, this bug will cause Integer Overflow, because every time umount, fs_devices->missing_devices will decrease. If fs_devices->missing_devices value hit 0, it would overflow.
With added debugging:
loop1: detected capacity change from 0 to 20971520 BTRFS: device fsid 56ad51f1-5523-463b-8547-c19486c51ebb devid 1 transid 21 /dev/loop1 scanned by systemd-udevd (2311) loop2: detected capacity change from 0 to 20971520 BTRFS: device fsid 56ad51f1-5523-463b-8547-c19486c51ebb devid 2 transid 17 /dev/loop2 scanned by systemd-udevd (2313) BTRFS info (device loop1): flagging fs with big metadata feature BTRFS info (device loop1): allowing degraded mounts BTRFS info (device loop1): using free space tree BTRFS info (device loop1): has skinny extents BTRFS info (device loop1): before clear_missing.00000000f706684d /dev/loop1 0 BTRFS warning (device loop1): devid 2 uuid 6635ac31-56dd-4852-873b-c60f5e2d53d2 is missing BTRFS info (device loop1): before clear_missing.0000000000000000 /dev/loop2 1 BTRFS info (device loop1): flagging fs with big metadata feature BTRFS info (device loop1): allowing degraded mounts BTRFS info (device loop1): using free space tree BTRFS info (device loop1): has skinny extents BTRFS info (device loop1): before clear_missing.00000000f706684d /dev/loop1 0 BTRFS warning (device loop1): devid 2 uuid 6635ac31-56dd-4852-873b-c60f5e2d53d2 is missing BTRFS info (device loop1): before clear_missing.0000000000000000 /dev/loop2 0 BTRFS info (device loop1): flagging fs with big metadata feature BTRFS info (device loop1): allowing degraded mounts BTRFS info (device loop1): using free space tree BTRFS info (device loop1): has skinny extents BTRFS info (device loop1): before clear_missing.00000000f706684d /dev/loop1 18446744073709551615 BTRFS warning (device loop1): devid 2 uuid 6635ac31-56dd-4852-873b-c60f5e2d53d2 is missing BTRFS info (device loop1): before clear_missing.0000000000000000 /dev/loop2 18446744073709551615
If fs_devices->missing_devices is 0, next time it would be 18446744073709551615
After apply this patch, the fs_devices->missing_devices seems to be right:
$ truncate -s 10g test1 $ truncate -s 10g test2 $ losetup /dev/loop1 test1 $ losetup /dev/loop2 test2 $ mkfs.btrfs -draid1 -mraid1 /dev/loop1 /dev/loop2 -f $ losetup -d /dev/loop2 $ mount -o degraded /dev/loop1 /mnt/1 $ umount /mnt/1 $ mount -o degraded /dev/loop1 /mnt/1 $ umount /mnt/1 $ mount -o degraded /dev/loop1 /mnt/1 $ umount /mnt/1 $ dmesg
loop1: detected capacity change from 0 to 20971520 loop2: detected capacity change from 0 to 20971520 BTRFS: device fsid 15aa1203-98d3-4a66-bcae-ca82f629c2cd devid 1 transid 5 /dev/loop1 scanned by mkfs.btrfs (1863) BTRFS: device fsid 15aa1203-98d3-4a66-bcae-ca82f629c2cd devid 2 transid 5 /dev/loop2 scanned by mkfs.btrfs (1863) BTRFS info (device loop1): flagging fs with big metadata feature BTRFS info (device loop1): allowing degraded mounts BTRFS info (device loop1): disk space caching is enabled BTRFS info (device loop1): has skinny extents BTRFS info (device loop1): before clear_missing.00000000975bd577 /dev/loop1 0 BTRFS warning (device loop1): devid 2 uuid 8b333791-0b3f-4f57-b449-1c1ab6b51f38 is missing BTRFS info (device loop1): before clear_missing.0000000000000000 /dev/loop2 1 BTRFS info (device loop1): checking UUID tree BTRFS info (device loop1): flagging fs with big metadata feature BTRFS info (device loop1): allowing degraded mounts BTRFS info (device loop1): disk space caching is enabled BTRFS info (device loop1): has skinny extents BTRFS info (device loop1): before clear_missing.00000000975bd577 /dev/loop1 0 BTRFS warning (device loop1): devid 2 uuid 8b333791-0b3f-4f57-b449-1c1ab6b51f38 is missing BTRFS info (device loop1): before clear_missing.0000000000000000 /dev/loop2 1 BTRFS info (device loop1): flagging fs with big metadata feature BTRFS info (device loop1): allowing degraded mounts BTRFS info (device loop1): disk space caching is enabled BTRFS info (device loop1): has skinny extents BTRFS info (device loop1): before clear_missing.00000000975bd577 /dev/loop1 0 BTRFS warning (device loop1): devid 2 uuid 8b333791-0b3f-4f57-b449-1c1ab6b51f38 is missing BTRFS info (device loop1): before clear_missing.0000000000000000 /dev/loop2 1
CC: stable@vger.kernel.org # 4.19+ Signed-off-by: Li Zhang zhanglikernel@gmail.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/volumes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1122,8 +1122,10 @@ static void btrfs_close_one_device(struc if (device->devid == BTRFS_DEV_REPLACE_DEVID) clear_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state);
- if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)) + if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state)) { + clear_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state); fs_devices->missing_devices--; + }
btrfs_close_bdev(device); if (device->bdev) {
From: Filipe Manana fdmanana@suse.com
commit 10adb1152d957a4d570ad630f93a88bb961616c1 upstream.
At replay_dir_deletes(), if find_dir_range() returns an error we break out of the main while loop and then assign a value of 0 (success) to the 'ret' variable, resulting in completely ignoring that an error happened. Fix that by jumping to the 'out' label when find_dir_range() returns an error (negative value).
CC: stable@vger.kernel.org # 4.4+ Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/tree-log.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2500,7 +2500,9 @@ again: else { ret = find_dir_range(log, path, dirid, key_type, &range_start, &range_end); - if (ret != 0) + if (ret < 0) + goto out; + else if (ret > 0) break; }
From: Anand Jain anand.jain@oracle.com
commit 5c78a5e7aa835c4f08a7c90fe02d19f95a776f29 upstream.
In open_ctree() in btrfs_check_rw_degradable() [1], we check each block group individually if at least the minimum number of devices is available for that profile. If all the devices are available, then we don't have to check degradable.
[1] open_ctree() :: 3559 if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info, NULL)) {
Also before calling btrfs_check_rw_degradable() in open_ctee() at the line number shown below [2] we call btrfs_read_chunk_tree() and down to add_missing_dev() to record number of missing devices.
[2] open_ctree() :: 3454 ret = btrfs_read_chunk_tree(fs_info);
btrfs_read_chunk_tree() read_one_chunk() / read_one_dev() add_missing_dev()
So, check if there is any missing device before btrfs_check_rw_degradable() in open_ctree().
Also, with this the mount command could save ~16ms.[3] in the most common case, that is no device is missing.
[3] 1) * 16934.96 us | btrfs_check_rw_degradable [btrfs]();
CC: stable@vger.kernel.org # 4.19+ Reviewed-by: Josef Bacik josef@toxicpanda.com Signed-off-by: Anand Jain anand.jain@oracle.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/disk-io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3556,7 +3556,8 @@ int __cold open_ctree(struct super_block goto fail_sysfs; }
- if (!sb_rdonly(sb) && !btrfs_check_rw_degradable(fs_info, NULL)) { + if (!sb_rdonly(sb) && fs_info->fs_devices->missing_devices && + !btrfs_check_rw_degradable(fs_info, NULL)) { btrfs_warn(fs_info, "writable mount is not allowed due to too many missing devices"); goto fail_sysfs;
From: Sean Christopherson seanjc@google.com
commit bc3b3c1002ea684e618ff6d8c387b1b8b319f140 upstream.
A recent commit to fix the calls to kvm_flush_remote_tlbs_with_address() in kvm_zap_gfn_range() inadvertantly added yet another flush instead of fixing the existing flush. Drop the redundant flush, and fix the params for the existing flush.
Cc: stable@vger.kernel.org Fixes: 2822da446640 ("KVM: x86/mmu: fix parameters to kvm_flush_remote_tlbs_with_address") Cc: Maxim Levitsky mlevitsk@redhat.com Cc: Maciej S. Szmigiero maciej.szmigiero@oracle.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211022010005.1454978-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/mmu/mmu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5758,13 +5758,11 @@ void kvm_zap_gfn_range(struct kvm *kvm, for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) flush = kvm_tdp_mmu_zap_gfn_range(kvm, i, gfn_start, gfn_end, flush); - if (flush) - kvm_flush_remote_tlbs_with_address(kvm, gfn_start, - gfn_end - gfn_start); }
if (flush) - kvm_flush_remote_tlbs_with_address(kvm, gfn_start, gfn_end); + kvm_flush_remote_tlbs_with_address(kvm, gfn_start, + gfn_end - gfn_start);
kvm_dec_notifier_count(kvm, gfn_start, gfn_end);
From: Sean Christopherson seanjc@google.com
commit ec5a4919fa7b7d8c7a2af1c7e799b1fe4be84343 upstream.
Unregister KVM's posted interrupt wakeup handler during unsetup so that a spurious interrupt that arrives after kvm_intel.ko is unloaded doesn't call into freed memory.
Fixes: bf9f6ac8d749 ("KVM: Update Posted-Interrupts Descriptor when vCPU is blocked") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211009001107.3936588-3-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/vmx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7551,6 +7551,8 @@ static void vmx_migrate_timers(struct kv
static void hardware_unsetup(void) { + kvm_set_posted_intr_wakeup_handler(NULL); + if (nested) nested_vmx_hardware_unsetup();
@@ -7879,8 +7881,6 @@ static __init int hardware_setup(void) vmx_x86_ops.request_immediate_exit = __kvm_request_immediate_exit; }
- kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler); - kvm_mce_cap_supported |= MCG_LMCE_P;
if (pt_mode != PT_MODE_SYSTEM && pt_mode != PT_MODE_HOST_GUEST) @@ -7904,6 +7904,9 @@ static __init int hardware_setup(void) r = alloc_kvm_area(); if (r) nested_vmx_hardware_unsetup(); + + kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler); + return r; }
From: Andreas Gruenbacher agruenba@redhat.com
commit 0c8eb2884a42d992c7726539328b7d3568f22143 upstream.
When switching from __get_user to fault_in_pages_readable, commit 9f9eae5ce717 broke kvm_use_magic_page: like __get_user, fault_in_pages_readable returns 0 on success.
Fixes: 9f9eae5ce717 ("powerpc/kvm: Prefer fault_in_pages_readable function") Cc: stable@vger.kernel.org # v4.18+ Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/kvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -669,7 +669,7 @@ static void __init kvm_use_magic_page(vo on_each_cpu(kvm_map_magic_page, &features, 1);
/* Quick self-test to see if the mapping works */ - if (!fault_in_pages_readable((const char *)KVM_MAGIC_PAGE, sizeof(u32))) { + if (fault_in_pages_readable((const char *)KVM_MAGIC_PAGE, sizeof(u32))) { kvm_patching_worked = false; return; }
From: Laurent Vivier lvivier@redhat.com
commit 235cee162459d96153d63651ce7ff51752528c96 upstream.
Commit 112665286d08 ("KVM: PPC: Book3S HV: Context tracking exit guest context before enabling irqs") moved guest_exit() into the interrupt protected area to avoid wrong context warning (or worse). The problem is that tick-based time accounting has not yet been updated at this point (because it depends on the timer interrupt firing), so the guest time gets incorrectly accounted to system time.
To fix the problem, follow the x86 fix in commit 160457140187 ("Defer vtime accounting 'til after IRQ handling"), and allow host IRQs to run before accounting the guest exit time.
In the case vtime accounting is enabled, this is not required because TB is used directly for accounting.
Before this patch, with CONFIG_TICK_CPU_ACCOUNTING=y in the host and a guest running a kernel compile, the 'guest' fields of /proc/stat are stuck at zero. With the patch they can be observed increasing roughly as expected.
Fixes: e233d54d4d97 ("KVM: booke: use __kvm_guest_exit") Fixes: 112665286d08 ("KVM: PPC: Book3S HV: Context tracking exit guest context before enabling irqs") Cc: stable@vger.kernel.org # 5.12+ Signed-off-by: Laurent Vivier lvivier@redhat.com [np: only required for tick accounting, add Book3E fix, tweak changelog] Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211027142150.3711582-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kvm/book3s_hv.c | 30 ++++++++++++++++++++++++++++-- arch/powerpc/kvm/booke.c | 16 +++++++++++++++- 2 files changed, 43 insertions(+), 3 deletions(-)
--- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3726,7 +3726,20 @@ static noinline void kvmppc_run_core(str
kvmppc_set_host_core(pcpu);
- guest_exit_irqoff(); + context_tracking_guest_exit(); + if (!vtime_accounting_enabled_this_cpu()) { + local_irq_enable(); + /* + * Service IRQs here before vtime_account_guest_exit() so any + * ticks that occurred while running the guest are accounted to + * the guest. If vtime accounting is enabled, accounting uses + * TB rather than ticks, so it can be done without enabling + * interrupts here, which has the problem that it accounts + * interrupt processing overhead to the host. + */ + local_irq_disable(); + } + vtime_account_guest_exit();
local_irq_enable();
@@ -4510,7 +4523,20 @@ int kvmhv_run_single_vcpu(struct kvm_vcp
kvmppc_set_host_core(pcpu);
- guest_exit_irqoff(); + context_tracking_guest_exit(); + if (!vtime_accounting_enabled_this_cpu()) { + local_irq_enable(); + /* + * Service IRQs here before vtime_account_guest_exit() so any + * ticks that occurred while running the guest are accounted to + * the guest. If vtime accounting is enabled, accounting uses + * TB rather than ticks, so it can be done without enabling + * interrupts here, which has the problem that it accounts + * interrupt processing overhead to the host. + */ + local_irq_disable(); + } + vtime_account_guest_exit();
local_irq_enable();
--- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -1042,7 +1042,21 @@ int kvmppc_handle_exit(struct kvm_vcpu * }
trace_kvm_exit(exit_nr, vcpu); - guest_exit_irqoff(); + + context_tracking_guest_exit(); + if (!vtime_accounting_enabled_this_cpu()) { + local_irq_enable(); + /* + * Service IRQs here before vtime_account_guest_exit() so any + * ticks that occurred while running the guest are accounted to + * the guest. If vtime accounting is enabled, accounting uses + * TB rather than ticks, so it can be done without enabling + * interrupts here, which has the problem that it accounts + * interrupt processing overhead to the host. + */ + local_irq_disable(); + } + vtime_account_guest_exit();
local_irq_enable();
From: Masami Hiramatsu mhiramat@kernel.org
commit a7fe2378454cf46cd5e2776d05e72bbe8f0a468c upstream.
The following commit:
Commit e792ff804f49 ("ia64: kprobes: Use generic kretprobe trampoline handler")
Passed the wrong trampoline address to __kretprobe_trampoline_handler(): it passes the descriptor address instead of function entry address.
Pass the right parameter.
Also use correct symbol dereference function to get the function address from 'kretprobe_trampoline' - an IA64 special.
Link: https://lkml.kernel.org/r/163163042696.489837.12551102356265354730.stgit@dev...
Fixes: e792ff804f49 ("ia64: kprobes: Use generic kretprobe trampoline handler") Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Ingo Molnar mingo@kernel.org Cc: X86 ML x86@kernel.org Cc: Daniel Xu dxu@dxuuu.xyz Cc: Thomas Gleixner tglx@linutronix.de Cc: Borislav Petkov bp@alien8.de Cc: Peter Zijlstra peterz@infradead.org Cc: Abhishek Sagar sagar.abhishek@gmail.com Cc: Andrii Nakryiko andrii.nakryiko@gmail.com Cc: Paul McKenney paulmck@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/ia64/kernel/kprobes.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -398,7 +398,8 @@ static void kretprobe_trampoline(void)
int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - regs->cr_iip = __kretprobe_trampoline_handler(regs, kretprobe_trampoline, NULL); + regs->cr_iip = __kretprobe_trampoline_handler(regs, + dereference_function_descriptor(kretprobe_trampoline), NULL); /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler @@ -414,7 +415,7 @@ void __kprobes arch_prepare_kretprobe(st ri->fp = NULL;
/* Replace the return addr with trampoline addr */ - regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; + regs->b0 = (unsigned long)dereference_function_descriptor(kretprobe_trampoline); }
/* Check the instruction in the slot is break */ @@ -902,14 +903,14 @@ static struct kprobe trampoline_p = { int __init arch_init_kprobes(void) { trampoline_p.addr = - (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; + dereference_function_descriptor(kretprobe_trampoline); return register_kprobe(&trampoline_p); }
int __kprobes arch_trampoline_kprobe(struct kprobe *p) { if (p->addr == - (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip) + dereference_function_descriptor(kretprobe_trampoline)) return 1;
return 0;
From: Ondrej Mosnacek omosnace@redhat.com
commit cbfcd13be5cb2a07868afe67520ed181956579a7 upstream.
Current code contains a lot of racy patterns when converting an ocontext's context structure to an SID. This is being done in a "lazy" fashion, such that the SID is looked up in the SID table only when it's first needed and then cached in the "sid" field of the ocontext structure. However, this is done without any locking or memory barriers and is thus unsafe.
Between commits 24ed7fdae669 ("selinux: use separate table for initial SID lookup") and 66f8e2f03c02 ("selinux: sidtab reverse lookup hash table"), this race condition lead to an actual observable bug, because a pointer to the shared sid field was passed directly to sidtab_context_to_sid(), which was using this location to also store an intermediate value, which could have been read by other threads and interpreted as an SID. In practice this caused e.g. new mounts to get a wrong (seemingly random) filesystem context, leading to strange denials. This bug has been spotted in the wild at least twice, see [1] and [2].
Fix the race condition by making all the racy functions use a common helper that ensures the ocontext::sid accesses are made safely using the appropriate SMP constructs.
Note that security_netif_sid() was populating the sid field of both contexts stored in the ocontext, but only the first one was actually used. The SELinux wiki's documentation on the "netifcon" policy statement [3] suggests that using only the first context is intentional. I kept only the handling of the first context here, as there is really no point in doing the SID lookup for the unused one.
I wasn't able to reproduce the bug mentioned above on any kernel that includes commit 66f8e2f03c02, even though it has been reported that the issue occurs with that commit, too, just less frequently. Thus, I wasn't able to verify that this patch fixes the issue, but it makes sense to avoid the race condition regardless.
[1] https://github.com/containers/container-selinux/issues/89 [2] https://lists.fedoraproject.org/archives/list/selinux@lists.fedoraproject.or... [3] https://selinuxproject.org/page/NetworkStatements#netifcon
Cc: stable@vger.kernel.org Cc: Xinjie Zheng xinjie@google.com Reported-by: Sujithra Periasamy sujithra@google.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") 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/services.c | 162 +++++++++++++++++++---------------------- 1 file changed, 77 insertions(+), 85 deletions(-)
--- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2377,6 +2377,43 @@ err_policy: }
/** + * ocontext_to_sid - Helper to safely get sid for an ocontext + * @sidtab: SID table + * @c: ocontext structure + * @index: index of the context entry (0 or 1) + * @out_sid: pointer to the resulting SID value + * + * For all ocontexts except OCON_ISID the SID fields are populated + * on-demand when needed. Since updating the SID value is an SMP-sensitive + * operation, this helper must be used to do that safely. + * + * WARNING: This function may return -ESTALE, indicating that the caller + * must retry the operation after re-acquiring the policy pointer! + */ +static int ocontext_to_sid(struct sidtab *sidtab, struct ocontext *c, + size_t index, u32 *out_sid) +{ + int rc; + u32 sid; + + /* Ensure the associated sidtab entry is visible to this thread. */ + sid = smp_load_acquire(&c->sid[index]); + if (!sid) { + rc = sidtab_context_to_sid(sidtab, &c->context[index], &sid); + if (rc) + return rc; + + /* + * Ensure the new sidtab entry is visible to other threads + * when they see the SID. + */ + smp_store_release(&c->sid[index], sid); + } + *out_sid = sid; + return 0; +} + +/** * security_port_sid - Obtain the SID for a port. * @state: SELinux state * @protocol: protocol number @@ -2414,17 +2451,13 @@ retry: }
if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else { *out_sid = SECINITSID_PORT; } @@ -2473,18 +2506,13 @@ retry: }
if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, - &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else *out_sid = SECINITSID_UNLABELED;
@@ -2533,17 +2561,13 @@ retry: }
if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else *out_sid = SECINITSID_UNLABELED;
@@ -2587,25 +2611,13 @@ retry: }
if (c) { - if (!c->sid[0] || !c->sid[1]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; - rc = sidtab_context_to_sid(sidtab, &c->context[1], - &c->sid[1]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, if_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *if_sid = c->sid[0]; + if (rc) + goto out; } else *if_sid = SECINITSID_NETIF;
@@ -2697,18 +2709,13 @@ retry: }
if (c) { - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, - &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - *out_sid = c->sid[0]; + if (rc) + goto out; } else { *out_sid = SECINITSID_NODE; } @@ -2873,7 +2880,7 @@ static inline int __security_genfs_sid(s u16 sclass; struct genfs *genfs; struct ocontext *c; - int rc, cmp = 0; + int cmp = 0;
while (path[0] == '/' && path[1] == '/') path++; @@ -2887,9 +2894,8 @@ static inline int __security_genfs_sid(s break; }
- rc = -ENOENT; if (!genfs || cmp) - goto out; + return -ENOENT;
for (c = genfs->head; c; c = c->next) { len = strlen(c->u.name); @@ -2898,20 +2904,10 @@ static inline int __security_genfs_sid(s break; }
- rc = -ENOENT; if (!c) - goto out; + return -ENOENT;
- if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], &c->sid[0]); - if (rc) - goto out; - } - - *sid = c->sid[0]; - rc = 0; -out: - return rc; + return ocontext_to_sid(sidtab, c, 0, sid); }
/** @@ -2996,17 +2992,13 @@ retry:
if (c) { sbsec->behavior = c->v.behavior; - if (!c->sid[0]) { - rc = sidtab_context_to_sid(sidtab, &c->context[0], - &c->sid[0]); - if (rc == -ESTALE) { - rcu_read_unlock(); - goto retry; - } - if (rc) - goto out; + rc = ocontext_to_sid(sidtab, c, 0, &sbsec->sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + goto retry; } - sbsec->sid = c->sid[0]; + if (rc) + goto out; } else { rc = __security_genfs_sid(policy, fstype, "/", SECCLASS_DIR, &sbsec->sid);
From: Corey Minyard cminyard@mvista.com
commit db05ddf7f321634c5659a0cf7ea56594e22365f7 upstream.
You will get two decrements when the messages on a panic are sent, not one, since commit 2033f6858970 ("ipmi: Free receive messages when in an oops") was added, but the watchdog code had a bug where it didn't set the value properly.
Reported-by: Anton Lundin glance@acc.umu.se Cc: Stable@vger.kernel.org # v5.4+ Fixes: 2033f6858970 ("ipmi: Free receive messages when in an oops") Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/ipmi/ipmi_watchdog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -497,7 +497,7 @@ static void panic_halt_ipmi_heartbeat(vo msg.cmd = IPMI_WDOG_RESET_TIMER; msg.data = NULL; msg.data_len = 0; - atomic_inc(&panic_done_count); + atomic_add(2, &panic_done_count); rv = ipmi_request_supply_msgs(watchdog_user, (struct ipmi_addr *) &addr, 0, @@ -507,7 +507,7 @@ static void panic_halt_ipmi_heartbeat(vo &panic_halt_heartbeat_recv_msg, 1); if (rv) - atomic_dec(&panic_done_count); + atomic_sub(2, &panic_done_count); }
static struct ipmi_smi_msg panic_halt_smi_msg = { @@ -531,12 +531,12 @@ static void panic_halt_ipmi_set_timeout( /* Wait for the messages to be free. */ while (atomic_read(&panic_done_count) != 0) ipmi_poll_interface(watchdog_user); - atomic_inc(&panic_done_count); + atomic_add(2, &panic_done_count); rv = __ipmi_set_timeout(&panic_halt_smi_msg, &panic_halt_recv_msg, &send_heartbeat_now); if (rv) { - atomic_dec(&panic_done_count); + atomic_sub(2, &panic_done_count); pr_warn("Unable to extend the watchdog timeout\n"); } else { if (send_heartbeat_now)
From: Guoqing Jiang guoqing.jiang@linux.dev
commit fd3b6975e9c11c4fa00965f82a0bfbb3b7b44101 upstream.
Commit 6607cd319b6b91bff94e90f798a61c031650b514 ("raid1: ensure write behind bio has less than BIO_MAX_VECS sectors") tried to guarantee the size of behind bio is not bigger than BIO_MAX_VECS sectors.
Unfortunately the same calltrace still could happen since an array could enable write-behind without write mostly device.
To match the manpage of mdadm (which says "write-behind is only attempted on drives marked as write-mostly"), we need to check WriteMostly flag to avoid such unexpected behavior.
[1]. https://bugzilla.kernel.org/show_bug.cgi?id=213181#c25
Cc: stable@vger.kernel.org # v5.12+ Cc: Jens Stutte jens@chianterastutte.eu Reported-by: Jens Stutte jens@chianterastutte.eu Signed-off-by: Guoqing Jiang guoqing.jiang@linux.dev Signed-off-by: Song Liu songliubraving@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/raid1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1496,7 +1496,7 @@ static void raid1_write_request(struct m if (!r1_bio->bios[i]) continue;
- if (first_clone) { + if (first_clone && test_bit(WriteMostly, &rdev->flags)) { /* do behind I/O ? * Not if there are too many, or cannot * allocate memory, or a reader on WriteMostly
From: Zev Weiss zev@bewilderbeest.net
commit ae59dc455a78fb73034dd1fbb337d7e59c27cbd8 upstream.
With the exception of the lm5066i, all the devices handled by this driver had been missing their offset ('b') coefficients for direct format readings.
Cc: stable@vger.kernel.org Fixes: 58615a94f6a1 ("hwmon: (pmbus/lm25066) Add support for LM25056") Fixes: e53e6497fc9f ("hwmon: (pmbus/lm25066) Refactor device specific coefficients") Signed-off-by: Zev Weiss zev@bewilderbeest.net Link: https://lore.kernel.org/r/20210928092242.30036-2-zev@bewilderbeest.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwmon/pmbus/lm25066.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
--- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -55,22 +55,27 @@ static struct __coeff lm25066_coeff[6][P [lm25056] = { [PSC_VOLTAGE_IN] = { .m = 16296, + .b = 1343, .R = -2, }, [PSC_CURRENT_IN] = { .m = 13797, + .b = -1833, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 6726, + .b = -537, .R = -2, }, [PSC_POWER] = { .m = 5501, + .b = -2908, .R = -3, }, [PSC_POWER_L] = { .m = 26882, + .b = -5646, .R = -4, }, [PSC_TEMPERATURE] = { @@ -82,26 +87,32 @@ static struct __coeff lm25066_coeff[6][P [lm25066] = { [PSC_VOLTAGE_IN] = { .m = 22070, + .b = -1800, .R = -2, }, [PSC_VOLTAGE_OUT] = { .m = 22070, + .b = -1800, .R = -2, }, [PSC_CURRENT_IN] = { .m = 13661, + .b = -5200, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 6852, + .b = -3100, .R = -2, }, [PSC_POWER] = { .m = 736, + .b = -3300, .R = -2, }, [PSC_POWER_L] = { .m = 369, + .b = -1900, .R = -2, }, [PSC_TEMPERATURE] = { @@ -111,26 +122,32 @@ static struct __coeff lm25066_coeff[6][P [lm5064] = { [PSC_VOLTAGE_IN] = { .m = 4611, + .b = -642, .R = -2, }, [PSC_VOLTAGE_OUT] = { .m = 4621, + .b = 423, .R = -2, }, [PSC_CURRENT_IN] = { .m = 10742, + .b = 1552, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 5456, + .b = 2118, .R = -2, }, [PSC_POWER] = { .m = 1204, + .b = 8524, .R = -3, }, [PSC_POWER_L] = { .m = 612, + .b = 11202, .R = -3, }, [PSC_TEMPERATURE] = { @@ -140,26 +157,32 @@ static struct __coeff lm25066_coeff[6][P [lm5066] = { [PSC_VOLTAGE_IN] = { .m = 4587, + .b = -1200, .R = -2, }, [PSC_VOLTAGE_OUT] = { .m = 4587, + .b = -2400, .R = -2, }, [PSC_CURRENT_IN] = { .m = 10753, + .b = -1200, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 5405, + .b = -600, .R = -2, }, [PSC_POWER] = { .m = 1204, + .b = -6000, .R = -3, }, [PSC_POWER_L] = { .m = 605, + .b = -8000, .R = -3, }, [PSC_TEMPERATURE] = {
From: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com
commit b16bef60a9112b1e6daf3afd16484eb06e7ce792 upstream.
The driver and its bindings, before commit 04f9f068a619 ("regulator: s5m8767: Modify parsing method of the voltage table of buck2/3/4") were requiring to provide at least one safe/default voltage for DVS registers if DVS GPIO is not being enabled.
IOW, if s5m8767,pmic-buck2-uses-gpio-dvs is missing, the s5m8767,pmic-buck2-dvs-voltage should still be present and contain one voltage.
This requirement was coming from driver behavior matching this condition (none of DVS GPIO is enabled): it was always initializing the DVS selector pins to 0 and keeping the DVS enable setting at reset value (enabled). Therefore if none of DVS GPIO is enabled in devicetree, driver was configuring the first DVS voltage for buck[234].
Mentioned commit 04f9f068a619 ("regulator: s5m8767: Modify parsing method of the voltage table of buck2/3/4") broke it because DVS voltage won't be parsed from devicetree if DVS GPIO is not enabled. After the change, driver will configure bucks to use the register reset value as voltage which might have unpleasant effects.
Fix this by relaxing the bindings constrain: if DVS GPIO is not enabled in devicetree (therefore DVS voltage is also not parsed), explicitly disable it.
Cc: stable@vger.kernel.org Fixes: 04f9f068a619 ("regulator: s5m8767: Modify parsing method of the voltage table of buck2/3/4") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Acked-by: Rob Herring robh@kernel.org Message-Id: 20211008113723.134648-2-krzysztof.kozlowski@canonical.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt | 21 +++------- drivers/regulator/s5m8767.c | 21 ++++------ 2 files changed, 17 insertions(+), 25 deletions(-)
--- a/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt +++ b/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt @@ -13,6 +13,14 @@ common regulator binding documented in:
Required properties of the main device node (the parent!): + - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used + for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. + + [1] If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional + property is specified, then all the eight voltage values for the + 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. + +Optional properties of the main device node (the parent!): - s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV) units for buck2 when changing voltage using gpio dvs. Refer to [1] below for additional information. @@ -25,19 +33,6 @@ Required properties of the main device n units for buck4 when changing voltage using gpio dvs. Refer to [1] below for additional information.
- - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used - for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. - - [1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional - property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage' - property should specify atleast one voltage level (which would be a - safe operating voltage). - - If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional - property is specified, then all the eight voltage values for the - 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. - -Optional properties of the main device node (the parent!): - s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. - s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs. - s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs. --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -850,18 +850,15 @@ static int s5m8767_pmic_probe(struct pla /* DS4 GPIO */ gpio_direction_output(pdata->buck_ds[2], 0x0);
- if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || - pdata->buck4_gpiodvs) { - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK2CTRL, 1 << 1, - (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1)); - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK3CTRL, 1 << 1, - (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1)); - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK4CTRL, 1 << 1, - (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1)); - } + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK2CTRL, 1 << 1, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1)); + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK3CTRL, 1 << 1, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1)); + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK4CTRL, 1 << 1, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1));
/* Initialize GPIO DVS registers */ for (i = 0; i < 8; i++) {
From: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com
commit a7fda04bc9b6ad9da8e19c9e6e3b1dab773d068a upstream.
The driver was always parsing "s5m8767,pmic-buck-default-dvs-idx", not "s5m8767,pmic-buck234-default-dvs-idx".
Cc: stable@vger.kernel.org Fixes: 26aec009f6b6 ("regulator: add device tree support for s5m8767") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Acked-by: Rob Herring robh@kernel.org Message-Id: 20211008113723.134648-3-krzysztof.kozlowski@canonical.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt +++ b/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt @@ -39,7 +39,7 @@ Optional properties of the main device n
Additional properties required if either of the optional properties are used:
- - s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from + - s5m8767,pmic-buck-default-dvs-idx: Default voltage setting selected from the possible 8 options selectable by the dvs gpios. The value of this property should be between 0 and 7. If not specified or if out of range, the default value of this property is set to 0.
From: Eric Badger ebadger@purestorage.com
commit 537bddd069c743759addf422d0b8f028ff0f8dbc upstream.
The computation of TOHM is off by one bit. This missed bit results in too low a value for TOHM, which can cause errors in regular memory to incorrectly report:
EDAC MC0: 1 CE Error at MMIOH area, on addr 0x000000207fffa680 on any memory
Fixes: 50d1bb93672f ("sb_edac: add support for Haswell based systems") Cc: stable@vger.kernel.org Reported-by: Meeta Saggi msaggi@purestorage.com Signed-off-by: Eric Badger ebadger@purestorage.com Signed-off-by: Tony Luck tony.luck@intel.com Link: https://lore.kernel.org/r/20211010170127.848113-1-ebadger@purestorage.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/edac/sb_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -1052,7 +1052,7 @@ static u64 haswell_get_tohm(struct sbrid pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOHM_1, ®); rc = ((reg << 6) | rc) << 26;
- return rc | 0x1ffffff; + return rc | 0x3ffffff; }
static u64 knl_get_tolm(struct sbridge_pvt *pvt)
From: Johan Hovold johan@kernel.org
commit 89f8765a11d8df49296d92c404067f9b5c58ee26 upstream.
Add the missing endpoint sanity checks to probe() to avoid division by zero in mwifiex_write_data_sync() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing).
Only add checks for the firmware-download boot stage, which require both command endpoints, for now. The driver looks like it will handle a missing endpoint during normal operation without oopsing, albeit not very gracefully as it will try to submit URBs to the default pipe and fail.
Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")).
Fixes: 4daffe354366 ("mwifiex: add support for Marvell USB8797 chipset") Cc: stable@vger.kernel.org # 3.5 Cc: Amitkumar Karwar akarwar@marvell.com Signed-off-by: Johan Hovold johan@kernel.org Reviewed-by: Brian Norris briannorris@chromium.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211027080819.6675-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/marvell/mwifiex/usb.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
--- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -505,6 +505,22 @@ static int mwifiex_usb_probe(struct usb_ } }
+ switch (card->usb_boot_state) { + case USB8XXX_FW_DNLD: + /* Reject broken descriptors. */ + if (!card->rx_cmd_ep || !card->tx_cmd_ep) + return -ENODEV; + if (card->bulk_out_maxpktsize == 0) + return -ENODEV; + break; + case USB8XXX_FW_READY: + /* Assume the driver can handle missing endpoints for now. */ + break; + default: + WARN_ON(1); + return -ENODEV; + } + usb_set_intfdata(intf, card);
ret = mwifiex_add_card(card, &card->fw_done, &usb_ops,
From: Johan Hovold johan@kernel.org
commit c1b9ca365deae667192be9fe24db244919971234 upstream.
Add the missing endpoint max-packet sanity check to probe() to avoid division by zero in ath10k_usb_hif_tx_sg() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing).
Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")).
Fixes: 9cbee358687e ("ath6kl: add full USB support") Cc: stable@vger.kernel.org # 3.5 Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211027080819.6675-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/ath6kl/usb.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -340,6 +340,11 @@ static int ath6kl_usb_setup_pipe_resourc le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval); } + + /* Ignore broken descriptors. */ + if (usb_endpoint_maxp(endpoint) == 0) + continue; + urbcount = 0;
pipe_num =
From: Johan Hovold johan@kernel.org
commit a066d28a7e729f808a3e6eff22e70c003091544e upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: 241b128b6b69 ("ath6kl: add back beginnings of USB support") Cc: stable@vger.kernel.org # 3.4 Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211025120522.6045-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/ath6kl/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -912,7 +912,7 @@ static int ath6kl_usb_submit_ctrl_in(str req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); + size, 2000);
if (ret < 0) { ath6kl_warn("Failed to read usb control message: %d\n", ret);
From: Johan Hovold johan@kernel.org
commit 5286132324230168d3fab6ffc16bfd7de85bdfb4 upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: 4db66499df91 ("ath10k: add initial USB support") Cc: stable@vger.kernel.org # 4.14 Cc: Erik Stromdahl erik.stromdahl@gmail.com Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211025120522.6045-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/ath10k/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -525,7 +525,7 @@ static int ath10k_usb_submit_ctrl_in(str req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); + size, 2000);
if (ret < 0) { ath10k_warn(ar, "Failed to read usb control message: %d\n",
From: Johan Hovold johan@kernel.org
commit a006acb931317aad3a8dd41333ebb0453caf49b8 upstream.
Add the missing endpoint max-packet sanity check to probe() to avoid division by zero in ath10k_usb_hif_tx_sg() in case a malicious device has broken descriptors (or when doing descriptor fuzz testing).
Note that USB core will reject URBs submitted for endpoints with zero wMaxPacketSize but that drivers doing packet-size calculations still need to handle this (cf. commit 2548288b4fb0 ("USB: Fix: Don't skip endpoint descriptors with maxpacket=0")).
Fixes: 4db66499df91 ("ath10k: add initial USB support") Cc: stable@vger.kernel.org # 4.14 Cc: Erik Stromdahl erik.stromdahl@gmail.com Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211027080819.6675-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/ath10k/usb.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -853,6 +853,11 @@ static int ath10k_usb_setup_pipe_resourc le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval); } + + /* Ignore broken descriptors. */ + if (usb_endpoint_maxp(endpoint) == 0) + continue; + urbcount = 0;
pipe_num =
From: Ingmar Klein ingmar_klein@web.de
commit e3f4bd3462f6f796594ecc0dda7144ed2d1e5a26 upstream.
When passing the Atheros QCA6174 through to a virtual machine, the VM hangs at the point where the ath10k driver loads.
Add a quirk to avoid bus resets on this device, which avoids the hang.
[bhelgaas: commit log] Link: https://lore.kernel.org/r/08982e05-b6e8-5a8d-24ab-da1488ee50a8@web.de Signed-off-by: Ingmar Klein ingmar_klein@web.de Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Pali Rohár pali@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3612,6 +3612,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_A DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003e, quirk_no_bus_reset);
/* * Root port on some Cavium CN8xxx chips do not successfully complete a bus
From: Johan Hovold johan@kernel.org
commit 2e9be536a213e838daed6ba42024dd68954ac061 upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Fixes: 605bebe23bf6 ("[PATCH] Add rtl8187 wireless driver") Cc: stable@vger.kernel.org # 2.6.23 Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211025120522.6045-4-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c @@ -28,7 +28,7 @@ u8 rtl818x_ioread8_idx(struct rtl8187_pr usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits8, sizeof(val), 500);
val = priv->io_dmabuf->bits8; mutex_unlock(&priv->io_mutex); @@ -45,7 +45,7 @@ u16 rtl818x_ioread16_idx(struct rtl8187_ usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits16, sizeof(val), 500);
val = priv->io_dmabuf->bits16; mutex_unlock(&priv->io_mutex); @@ -62,7 +62,7 @@ u32 rtl818x_ioread32_idx(struct rtl8187_ usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits32, sizeof(val), 500);
val = priv->io_dmabuf->bits32; mutex_unlock(&priv->io_mutex); @@ -79,7 +79,7 @@ void rtl818x_iowrite8_idx(struct rtl8187 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits8, sizeof(val), 500);
mutex_unlock(&priv->io_mutex); } @@ -93,7 +93,7 @@ void rtl818x_iowrite16_idx(struct rtl818 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits16, sizeof(val), 500);
mutex_unlock(&priv->io_mutex); } @@ -107,7 +107,7 @@ void rtl818x_iowrite32_idx(struct rtl818 usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits32, sizeof(val), 500);
mutex_unlock(&priv->io_mutex); } @@ -183,7 +183,7 @@ static void rtl8225_write_8051(struct ie usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), - HZ / 2); + 500);
mutex_unlock(&priv->io_mutex);
From: Austin Kim austin.kim@lge.com
commit 32ba540f3c2a7ef61ed5a577ce25069a3d714fc9 upstream.
The evm_fixmode is only configurable by command-line option and it is never modified outside initcalls, so declaring it with __ro_after_init is better.
Signed-off-by: Austin Kim austin.kim@lge.com Cc: stable@vger.kernel.org Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/integrity/evm/evm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -78,7 +78,7 @@ static struct xattr_list evm_config_defa
LIST_HEAD(evm_config_xattrnames);
-static int evm_fixmode; +static int evm_fixmode __ro_after_init; static int __init evm_set_fixmode(char *str) { if (strncmp(str, "fix", 3) == 0)
From: Lukas Wunner lukas@wunner.de
commit 046178e726c2977d686ba5e07105d5a6685c830e upstream.
IFB originally depended on NET_CLS_ACT for traffic redirection. But since v4.5, that may be achieved with NFT_FWD_NETDEV as well.
Fixes: 39e6dea28adc ("netfilter: nf_tables: add forward expression to the netdev family") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.5+: bcfabee1afd9: netfilter: nft_fwd_netdev: allow to redirect to ifb via ingress Cc: stable@vger.kernel.org # v4.5+ Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -150,7 +150,7 @@ config NET_FC
config IFB tristate "Intermediate Functional Block support" - depends on NET_CLS_ACT + depends on NET_ACT_MIRRED || NFT_FWD_NETDEV select NET_REDIRECT help This is an intermediate driver that allows sharing of
From: Maximilian Luz luzmaximilian@gmail.com
commit 4f042e40199ce8bac6bc2b853e81744ee4ea759c upstream.
Add support for the Surface Laptop Studio.
In contrast to previous Surface Laptop models, this one has its HID devices attached to target ID 1 (instead of 2). It also has a couple more of them, including a new notifier for when the pen is stashed / taken out of its place, a "Sys Control" device, and two other unidentified HID devices with unknown usages.
Battery and performance profile interfaces remain the same.
Cc: stable@vger.kernel.org # 5.14+ Signed-off-by: Maximilian Luz luzmaximilian@gmail.com Link: https://lore.kernel.org/r/20211021130904.862610-2-luzmaximilian@gmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/platform/surface/surface_aggregator_registry.c | 54 +++++++++++++++++ 1 file changed, 54 insertions(+)
--- a/drivers/platform/surface/surface_aggregator_registry.c +++ b/drivers/platform/surface/surface_aggregator_registry.c @@ -77,6 +77,42 @@ static const struct software_node ssam_n .parent = &ssam_node_root, };
+/* HID keyboard (TID1). */ +static const struct software_node ssam_node_hid_tid1_keyboard = { + .name = "ssam:01:15:01:01:00", + .parent = &ssam_node_root, +}; + +/* HID pen stash (TID1; pen taken / stashed away evens). */ +static const struct software_node ssam_node_hid_tid1_penstash = { + .name = "ssam:01:15:01:02:00", + .parent = &ssam_node_root, +}; + +/* HID touchpad (TID1). */ +static const struct software_node ssam_node_hid_tid1_touchpad = { + .name = "ssam:01:15:01:03:00", + .parent = &ssam_node_root, +}; + +/* HID device instance 6 (TID1, unknown HID device). */ +static const struct software_node ssam_node_hid_tid1_iid6 = { + .name = "ssam:01:15:01:06:00", + .parent = &ssam_node_root, +}; + +/* HID device instance 7 (TID1, unknown HID device). */ +static const struct software_node ssam_node_hid_tid1_iid7 = { + .name = "ssam:01:15:01:07:00", + .parent = &ssam_node_root, +}; + +/* HID system controls (TID1). */ +static const struct software_node ssam_node_hid_tid1_sysctrl = { + .name = "ssam:01:15:01:08:00", + .parent = &ssam_node_root, +}; + /* HID keyboard. */ static const struct software_node ssam_node_hid_main_keyboard = { .name = "ssam:01:15:02:01:00", @@ -159,6 +195,21 @@ static const struct software_node *ssam_ NULL, };
+/* Devices for Surface Laptop Studio. */ +static const struct software_node *ssam_node_group_sls[] = { + &ssam_node_root, + &ssam_node_bat_ac, + &ssam_node_bat_main, + &ssam_node_tmp_pprof, + &ssam_node_hid_tid1_keyboard, + &ssam_node_hid_tid1_penstash, + &ssam_node_hid_tid1_touchpad, + &ssam_node_hid_tid1_iid6, + &ssam_node_hid_tid1_iid7, + &ssam_node_hid_tid1_sysctrl, + NULL, +}; + /* Devices for Surface Laptop Go. */ static const struct software_node *ssam_node_group_slg1[] = { &ssam_node_root, @@ -507,6 +558,9 @@ static const struct acpi_device_id ssam_ /* Surface Laptop Go 1 */ { "MSHW0118", (unsigned long)ssam_node_group_slg1 },
+ /* Surface Laptop Studio */ + { "MSHW0123", (unsigned long)ssam_node_group_sls }, + { }, }; MODULE_DEVICE_TABLE(acpi, ssam_platform_hub_match);
From: Felix Fietkau nbd@nbd.name
commit b5cd1fd6043bbb7c5810067b5f93f3016bfd8a6f upstream.
When clearing all existing pending tx slots, mt76_tx_complete_skb needs to be used to free the skbs, to ensure that they are cleared from the status list as well.
Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 45 ++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-)
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -1494,32 +1494,41 @@ out: }
static void -mt7615_mac_tx_free_token(struct mt7615_dev *dev, u16 token) +mt7615_txwi_free(struct mt7615_dev *dev, struct mt76_txwi_cache *txwi) { struct mt76_dev *mdev = &dev->mt76; - struct mt76_txwi_cache *txwi; __le32 *txwi_data; u32 val; u8 wcid;
- trace_mac_tx_free(dev, token); - txwi = mt76_token_put(mdev, token); - if (!txwi) - return; + mt7615_txp_skb_unmap(mdev, txwi); + if (!txwi->skb) + goto out;
txwi_data = (__le32 *)mt76_get_txwi_ptr(mdev, txwi); val = le32_to_cpu(txwi_data[1]); wcid = FIELD_GET(MT_TXD1_WLAN_IDX, val); + mt76_tx_complete_skb(mdev, wcid, txwi->skb);
- mt7615_txp_skb_unmap(mdev, txwi); - if (txwi->skb) { - mt76_tx_complete_skb(mdev, wcid, txwi->skb); - txwi->skb = NULL; - } - +out: + txwi->skb = NULL; mt76_put_txwi(mdev, txwi); }
+static void +mt7615_mac_tx_free_token(struct mt7615_dev *dev, u16 token) +{ + struct mt76_dev *mdev = &dev->mt76; + struct mt76_txwi_cache *txwi; + + trace_mac_tx_free(dev, token); + txwi = mt76_token_put(mdev, token); + if (!txwi) + return; + + mt7615_txwi_free(dev, txwi); +} + static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb) { struct mt7615_tx_free *free = (struct mt7615_tx_free *)skb->data; @@ -2026,16 +2035,8 @@ void mt7615_tx_token_put(struct mt7615_d int id;
spin_lock_bh(&dev->mt76.token_lock); - idr_for_each_entry(&dev->mt76.token, txwi, id) { - mt7615_txp_skb_unmap(&dev->mt76, txwi); - if (txwi->skb) { - struct ieee80211_hw *hw; - - hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb); - ieee80211_free_txskb(hw, txwi->skb); - } - mt76_put_txwi(&dev->mt76, txwi); - } + idr_for_each_entry(&dev->mt76.token, txwi, id) + mt7615_txwi_free(dev, txwi); spin_unlock_bh(&dev->mt76.token_lock); idr_destroy(&dev->mt76.token); }
From: Maximilian Luz luzmaximilian@gmail.com
commit dc0fd0acb6e0e8025a0a43ada54513b216254fac upstream.
Until now, we have only ever seen the REG-category registry being used on devices addressed with target ID 2. In fact, we have only ever seen Surface Aggregator Module (SAM) HID devices with target ID 2. For those devices, the registry also has to be addressed with target ID 2.
Some devices, like the new Surface Laptop Studio, however, address their HID devices on target ID 1. As a result of this, any target ID 2 commands time out. This includes event management commands addressed to the target ID 2 REG-category registry. For these devices, the registry has to be addressed via target ID 1 instead.
We therefore assume that the target ID of the registry to be used depends on the target ID of the respective device. Implement this accordingly.
Note that we currently allow the surface HID driver to only load against devices with target ID 2, so these timeouts are not happening (yet). This is just a preparation step before we allow the driver to load against all target IDs.
Cc: stable@vger.kernel.org # 5.14+ Signed-off-by: Maximilian Luz luzmaximilian@gmail.com Acked-by: Benjamin Tissoires benjamin.tissoires@redhat.com Link: https://lore.kernel.org/r/20211021130904.862610-3-luzmaximilian@gmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/surface-hid/surface_hid.c | 2 +- include/linux/surface_aggregator/controller.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/hid/surface-hid/surface_hid.c +++ b/drivers/hid/surface-hid/surface_hid.c @@ -209,7 +209,7 @@ static int surface_hid_probe(struct ssam
shid->notif.base.priority = 1; shid->notif.base.fn = ssam_hid_event_fn; - shid->notif.event.reg = SSAM_EVENT_REGISTRY_REG; + shid->notif.event.reg = SSAM_EVENT_REGISTRY_REG(sdev->uid.target); shid->notif.event.id.target_category = sdev->uid.category; shid->notif.event.id.instance = sdev->uid.instance; shid->notif.event.mask = SSAM_EVENT_MASK_STRICT; --- a/include/linux/surface_aggregator/controller.h +++ b/include/linux/surface_aggregator/controller.h @@ -792,8 +792,8 @@ enum ssam_event_mask { #define SSAM_EVENT_REGISTRY_KIP \ SSAM_EVENT_REGISTRY(SSAM_SSH_TC_KIP, 0x02, 0x27, 0x28)
-#define SSAM_EVENT_REGISTRY_REG \ - SSAM_EVENT_REGISTRY(SSAM_SSH_TC_REG, 0x02, 0x01, 0x02) +#define SSAM_EVENT_REGISTRY_REG(tid)\ + SSAM_EVENT_REGISTRY(SSAM_SSH_TC_REG, tid, 0x01, 0x02)
/** * enum ssam_event_notifier_flags - Flags for event notifiers.
From: Maximilian Luz luzmaximilian@gmail.com
commit ab5fe33925c6b03f646a1153771dab047548e4d8 upstream.
Until now we have only ever seen HID devices with target ID 2. The new Surface Laptop Studio however uses HID devices with target ID 1. Allow matching this driver to those as well.
Cc: stable@vger.kernel.org # 5.14+ Signed-off-by: Maximilian Luz luzmaximilian@gmail.com Acked-by: Benjamin Tissoires benjamin.tissoires@redhat.com Link: https://lore.kernel.org/r/20211021130904.862610-4-luzmaximilian@gmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/surface-hid/surface_hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hid/surface-hid/surface_hid.c +++ b/drivers/hid/surface-hid/surface_hid.c @@ -230,7 +230,7 @@ static void surface_hid_remove(struct ss }
static const struct ssam_device_id surface_hid_match[] = { - { SSAM_SDEV(HID, 0x02, SSAM_ANY_IID, 0x00) }, + { SSAM_SDEV(HID, SSAM_ANY_TID, SSAM_ANY_IID, 0x00) }, { }, }; MODULE_DEVICE_TABLE(ssam, surface_hid_match);
From: Loic Poulain loic.poulain@linaro.org
commit 960ae77f25631bbe4e3aafefe209b52e044baf31 upstream.
All wcn36xx controllers are supposed to support HT40 (and SGI40), This doubles the maximum bitrate/throughput with compatible APs.
Tested with wcn3620 & wcn3680B.
Cc: stable@vger.kernel.org Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware") Signed-off-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1634737133-22336-1-git-send-email-loic.poulain@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/wcn36xx/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -135,7 +135,9 @@ static struct ieee80211_supported_band w .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | - IEEE80211_HT_CAP_LSIG_TXOP_PROT, + IEEE80211_HT_CAP_LSIG_TXOP_PROT | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SUP_WIDTH_20_40, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
From: Loic Poulain loic.poulain@linaro.org
commit a9e79b116cc4d0057e912be8f40b2c2e5bdc7c43 upstream.
This change fix the TX ack mechanism in various ways:
- For NO_ACK tagged packets, we don't need to wait for TX_ACK indication and so are not subject to the single packet ack limitation. So we don't have to stop the tx queue, and can call the tx status callback as soon as DMA transfer has completed.
- Fix skb ownership/reference. Only start status indication timeout once the DMA transfer has been completed. This avoids the skb to be both referenced in the DMA tx ring and by the tx_ack_skb pointer, preventing any use-after-free or double-free.
- This adds a sanity (paranoia?) check on the skb tx ack pointer.
- Resume TX queue if TX status tagged packet TX fails.
Cc: stable@vger.kernel.org Fixes: fdf21cc37149 ("wcn36xx: Add TX ack support") Signed-off-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1634567281-28997-1-git-send-email-loic.poulain@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/wcn36xx/dxe.c | 37 ++++++++++++-------------------- drivers/net/wireless/ath/wcn36xx/txrx.c | 31 +++++--------------------- 2 files changed, 21 insertions(+), 47 deletions(-)
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -403,8 +403,21 @@ static void reap_tx_dxes(struct wcn36xx dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, ctl->skb->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(ctl->skb); - if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { - /* Keep frame until TX status comes */ + if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (info->flags & IEEE80211_TX_CTL_NO_ACK) { + info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + ieee80211_tx_status_irqsafe(wcn->hw, ctl->skb); + } else { + /* Wait for the TX ack indication or timeout... */ + spin_lock(&wcn->dxe_lock); + if (WARN_ON(wcn->tx_ack_skb)) + ieee80211_free_txskb(wcn->hw, wcn->tx_ack_skb); + wcn->tx_ack_skb = ctl->skb; /* Tracking ref */ + mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); + spin_unlock(&wcn->dxe_lock); + } + /* do not free, ownership transferred to mac80211 status cb */ + } else { ieee80211_free_txskb(wcn->hw, ctl->skb); }
@@ -426,7 +439,6 @@ static irqreturn_t wcn36xx_irq_tx_comple { struct wcn36xx *wcn = (struct wcn36xx *)dev; int int_src, int_reason; - bool transmitted = false;
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src);
@@ -466,7 +478,6 @@ static irqreturn_t wcn36xx_irq_tx_comple if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK | WCN36XX_CH_STAT_INT_ED_MASK)) { reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); - transmitted = true; } }
@@ -479,7 +490,6 @@ static irqreturn_t wcn36xx_irq_tx_comple WCN36XX_DXE_0_INT_CLR, WCN36XX_INT_MASK_CHAN_TX_L);
- if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) { wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ERR_CLR, @@ -507,25 +517,8 @@ static irqreturn_t wcn36xx_irq_tx_comple if (int_reason & (WCN36XX_CH_STAT_INT_DONE_MASK | WCN36XX_CH_STAT_INT_ED_MASK)) { reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); - transmitted = true; - } - } - - spin_lock(&wcn->dxe_lock); - if (wcn->tx_ack_skb && transmitted) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(wcn->tx_ack_skb); - - /* TX complete, no need to wait for 802.11 ack indication */ - if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS && - info->flags & IEEE80211_TX_CTL_NO_ACK) { - info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; - del_timer(&wcn->tx_ack_timer); - ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb); - wcn->tx_ack_skb = NULL; - ieee80211_wake_queues(wcn->hw); } } - spin_unlock(&wcn->dxe_lock);
return IRQ_HANDLED; } --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -502,10 +502,11 @@ int wcn36xx_start_tx(struct wcn36xx *wcn struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct wcn36xx_vif *vif_priv = NULL; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned long flags; bool is_low = ieee80211_is_data(hdr->frame_control); bool bcast = is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1); + bool ack_ind = (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) && + !(info->flags & IEEE80211_TX_CTL_NO_ACK); struct wcn36xx_tx_bd bd; int ret;
@@ -521,30 +522,16 @@ int wcn36xx_start_tx(struct wcn36xx *wcn
bd.dpu_rf = WCN36XX_BMU_WQ_TX;
- if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { + if (unlikely(ack_ind)) { wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n");
- spin_lock_irqsave(&wcn->dxe_lock, flags); - if (wcn->tx_ack_skb) { - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - wcn36xx_warn("tx_ack_skb already set\n"); - return -EINVAL; - } - - wcn->tx_ack_skb = skb; - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - /* Only one at a time is supported by fw. Stop the TX queues * until the ack status gets back. */ ieee80211_stop_queues(wcn->hw);
- /* TX watchdog if no TX irq or ack indication received */ - mod_timer(&wcn->tx_ack_timer, jiffies + HZ / 10); - /* Request ack indication from the firmware */ - if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) - bd.tx_comp = 1; + bd.tx_comp = 1; }
/* Data frames served first*/ @@ -558,14 +545,8 @@ int wcn36xx_start_tx(struct wcn36xx *wcn bd.tx_bd_sign = 0xbdbdbdbd;
ret = wcn36xx_dxe_tx_frame(wcn, vif_priv, &bd, skb, is_low); - if (ret && (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { - /* If the skb has not been transmitted, - * don't keep a reference to it. - */ - spin_lock_irqsave(&wcn->dxe_lock, flags); - wcn->tx_ack_skb = NULL; - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - + if (unlikely(ret && ack_ind)) { + /* If the skb has not been transmitted, resume TX queue */ ieee80211_wake_queues(wcn->hw); }
From: Loic Poulain loic.poulain@linaro.org
commit d3fd2c95c1c13ec217d43ebef3c61cfa00a6cd37 upstream.
We observe unexpected connection drops with some APs due to non-acked mac80211 generated null data frames (keep-alive). After debugging and capture, we noticed that null frames are submitted at standard data bitrate and that the given APs are in trouble with that.
After setting the null frame bitrate to control bitrate, all null frames are acked as expected and connection is maintained.
Not sure if it's a requirement of the specification, but it seems the right thing to do anyway, null frames are mostly used for control purpose (power-saving, keep-alive...), and submitting them with a slower/simpler bitrate/modulation is more robust.
Cc: stable@vger.kernel.org Fixes: 512b191d9652 ("wcn36xx: Fix TX data path") Signed-off-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1634560399-15290-1-git-send-email-loic.poulain@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -429,6 +429,7 @@ static void wcn36xx_set_tx_data(struct w if (ieee80211_is_any_nullfunc(hdr->frame_control)) { /* Don't use a regular queue for null packet (no ampdu) */ bd->queue_id = WCN36XX_TX_U_WQ_ID; + bd->bd_rate = WCN36XX_BD_RATE_CTRL; }
if (bcast) {
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
commit 928265e3601cde78c7e0a3e518a93b27defed3b1 upstream.
There is no reason to allow "syscore" devices to runtime-suspend during system-wide PM transitions, because they are subject to the same possible failure modes as any other devices in that respect.
Accordingly, change device_prepare() and device_complete() to call pm_runtime_get_noresume() and pm_runtime_put(), respectively, for "syscore" devices too.
Fixes: 057d51a1268f ("Merge branch 'pm-sleep'") Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Cc: 3.10+ stable@vger.kernel.org # 3.10+ Reviewed-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/power/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1051,7 +1051,7 @@ static void device_complete(struct devic const char *info = NULL;
if (dev->power.syscore) - return; + goto out;
device_lock(dev);
@@ -1081,6 +1081,7 @@ static void device_complete(struct devic
device_unlock(dev);
+out: pm_runtime_put(dev); }
@@ -1794,9 +1795,6 @@ static int device_prepare(struct device int (*callback)(struct device *) = NULL; int ret = 0;
- if (dev->power.syscore) - return 0; - /* * If a device's parent goes into runtime suspend at the wrong time, * it won't be possible to resume the device. To prevent this we @@ -1805,6 +1803,9 @@ static int device_prepare(struct device */ pm_runtime_get_noresume(dev);
+ if (dev->power.syscore) + return 0; + device_lock(dev);
dev->power.wakeup_path = false;
From: Jonas Dreßler verdre@v0yd.nl
commit e5f4eb8223aa740237cd463246a7debcddf4eda1 upstream.
On the 88W8897 PCIe+USB card the firmware randomly crashes after setting the TX ring write pointer. The issue is present in the latest firmware version 15.68.19.p21 of the PCIe+USB card.
Those firmware crashes can be worked around by reading any PCI register of the card after setting that register, so read the PCI_VENDOR_ID register here. The reason this works is probably because we keep the bus from entering an ASPM state for a bit longer, because that's what causes the cards firmware to crash.
This fixes a bug where during RX/TX traffic and with ASPM L1 substates enabled (the specific substates where the issue happens appear to be platform dependent), the firmware crashes and eventually a command timeout appears in the logs.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=109681 Cc: stable@vger.kernel.org Signed-off-by: Jonas Dreßler verdre@v0yd.nl Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211011133224.15561-2-verdre@v0yd.nl Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/marvell/mwifiex/pcie.c | 8 ++++++++ 1 file changed, 8 insertions(+)
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -1490,6 +1490,14 @@ mwifiex_pcie_send_data(struct mwifiex_ad ret = -1; goto done_unmap; } + + /* The firmware (latest version 15.68.19.p21) of the 88W8897 PCIe+USB card + * seems to crash randomly after setting the TX ring write pointer when + * ASPM powersaving is enabled. A workaround seems to be keeping the bus + * busy by reading a random register afterwards. + */ + mwifiex_read_reg(adapter, PCI_VENDOR_ID, &rx_val); + if ((mwifiex_pcie_txbd_not_full(card)) && tx_param->next_pkt_len) { /* have more packets and TxBD still can hold more */
From: Jonas Dreßler verdre@v0yd.nl
commit 8e3e59c31fea5de95ffc52c46f0c562c39f20c59 upstream.
It seems that the PCIe+USB firmware (latest version 15.68.19.p21) of the 88W8897 card sometimes ignores or misses when we try to wake it up by writing to the firmware status register. This leads to the firmware wakeup timeout expiring and the driver resetting the card because we assume the firmware has hung up or crashed.
Turns out that the firmware actually didn't hang up, but simply "missed" our wakeup request and didn't send us an interrupt with an AWAKE event.
Trying again to read the firmware status register after a short timeout usually makes the firmware wake up as expected, so add a small retry loop to mwifiex_pm_wakeup_card() that looks at the interrupt status to check whether the card woke up.
The number of tries and timeout lengths for this were determined experimentally: The firmware usually takes about 500 us to wake up after we attempt to read the status register. In some cases where the firmware is very busy (for example while doing a bluetooth scan) it might even miss our requests for multiple milliseconds, which is why after 15 tries the waiting time gets increased to 10 ms. The maximum number of tries it took to wake the firmware when testing this was around 20, so a maximum number of 50 tries should give us plenty of safety margin.
Here's a reproducer for those firmware wakeup failures I've found:
1) Make sure wifi powersaving is enabled (iw dev wlp1s0 set power_save on) 2) Connect to any wifi network (makes firmware go into wifi powersaving mode, not deep sleep) 3) Make sure bluetooth is turned off (to ensure the firmware actually enters powersave mode and doesn't keep the radio active doing bluetooth stuff) 4) To confirm that wifi powersaving is entered ping a device on the LAN, pings should be a few ms higher than without powersaving 5) Run "while true; do iwconfig; sleep 0.0001; done", this wakes and suspends the firmware extremely often 6) Wait until things explode, for me it consistently takes <5 minutes
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=109681 Cc: stable@vger.kernel.org Signed-off-by: Jonas Dreßler verdre@v0yd.nl Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211011133224.15561-3-verdre@v0yd.nl Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/marvell/mwifiex/pcie.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -17,6 +17,7 @@ * this warranty disclaimer. */
+#include <linux/iopoll.h> #include <linux/firmware.h>
#include "decl.h" @@ -647,11 +648,15 @@ static void mwifiex_delay_for_sleep_cook "max count reached while accessing sleep cookie\n"); }
+#define N_WAKEUP_TRIES_SHORT_INTERVAL 15 +#define N_WAKEUP_TRIES_LONG_INTERVAL 35 + /* This function wakes up the card by reading fw_status register. */ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + int retval;
mwifiex_dbg(adapter, EVENT, "event: Wakeup device...\n"); @@ -659,11 +664,24 @@ static int mwifiex_pm_wakeup_card(struct if (reg->sleep_cookie) mwifiex_pcie_dev_wakeup_delay(adapter);
- /* Accessing fw_status register will wakeup device */ - if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) { - mwifiex_dbg(adapter, ERROR, - "Writing fw_status register failed\n"); - return -1; + /* The 88W8897 PCIe+USB firmware (latest version 15.68.19.p21) sometimes + * appears to ignore or miss our wakeup request, so we continue trying + * until we receive an interrupt from the card. + */ + if (read_poll_timeout(mwifiex_write_reg, retval, + READ_ONCE(adapter->int_status) != 0, + 500, 500 * N_WAKEUP_TRIES_SHORT_INTERVAL, + false, + adapter, reg->fw_status, FIRMWARE_READY_PCIE)) { + if (read_poll_timeout(mwifiex_write_reg, retval, + READ_ONCE(adapter->int_status) != 0, + 10000, 10000 * N_WAKEUP_TRIES_LONG_INTERVAL, + false, + adapter, reg->fw_status, FIRMWARE_READY_PCIE)) { + mwifiex_dbg(adapter, ERROR, + "Firmware didn't wake up\n"); + return -EIO; + } }
if (reg->sleep_cookie) {
From: Reimar Döffinger Reimar.Doeffinger@gmx.de
commit f971a85439bd25dc7b4d597cf5e4e8dc7ffc884b upstream.
Checking if DMA is enabled should be done via the ata_dma_enabled helper function, since the init state 0xff indicates disabled. This meant that ATA_CMD_READ_LOG_DMA_EXT was used and probed for before DMA was enabled, which caused hangs for some combinations of controllers and devices. It might also have caused it to be incorrectly disabled as broken, but there have been no reports of that.
Cc: stable@vger.kernel.org BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=195895 Signed-off-by: Reimar Döffinger Reimar.Doeffinger@gmx.de Tested-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Damien Le Moal damien.lemoal@wdc.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2007,7 +2007,7 @@ unsigned int ata_read_log_page(struct at
retry: ata_tf_init(dev, &tf); - if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) && + if (ata_dma_enabled(dev) && ata_id_has_read_log_dma_ext(dev->id) && !(dev->horkage & ATA_HORKAGE_NO_DMA_LOG)) { tf.command = ATA_CMD_READ_LOG_DMA_EXT; tf.protocol = ATA_PROT_DMA;
From: Christian König christian.koenig@amd.com
commit 6b51b02a3a0ac49dfe302818d0746a799545e4e9 upstream.
Daniel pointed me towards this function and there are multiple obvious problems in the implementation.
First of all the retry loop is not working as intended. In general the retry makes only sense if you grab the reference first and then check the sequence values.
Then we should always also wait for the exclusive fence.
It's also good practice to keep the reference around when installing callbacks to fences you don't own.
And last the whole implementation was unnecessary complex and rather hard to understand which could lead to probably unexpected behavior of the IOCTL.
Fix all this by reworking the implementation from scratch. Dropping the whole RCU approach and taking the lock instead.
Only mildly tested and needs a thoughtful review of the code.
Pushing through drm-misc-next to avoid merge conflicts and give the code another round of testing.
v2: fix the reference counting as well v3: keep the excl fence handling as is for stable v4: back to testing all fences, drop RCU v5: handle in and out separately v6: add missing clear of events v7: change coding style as suggested by Michel, drop unused variables
Signed-off-by: Christian König christian.koenig@amd.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Tested-by: Michel Dänzer mdaenzer@redhat.com CC: stable@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20210720131110.88512-1-christi... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma-buf/dma-buf.c | 152 +++++++++++++++++++++------------------------- include/linux/dma-buf.h | 2 2 files changed, 71 insertions(+), 83 deletions(-)
--- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -74,7 +74,7 @@ static void dma_buf_release(struct dentr * If you hit this BUG() it means someone dropped their ref to the * dma-buf while still having pending operation to the buffer. */ - BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active); + BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);
dma_buf_stats_teardown(dmabuf); dmabuf->ops->release(dmabuf); @@ -205,16 +205,55 @@ static void dma_buf_poll_cb(struct dma_f wake_up_locked_poll(dcb->poll, dcb->active); dcb->active = 0; spin_unlock_irqrestore(&dcb->poll->lock, flags); + dma_fence_put(fence); +} + +static bool dma_buf_poll_shared(struct dma_resv *resv, + struct dma_buf_poll_cb_t *dcb) +{ + struct dma_resv_list *fobj = dma_resv_shared_list(resv); + struct dma_fence *fence; + int i, r; + + if (!fobj) + return false; + + for (i = 0; i < fobj->shared_count; ++i) { + fence = rcu_dereference_protected(fobj->shared[i], + dma_resv_held(resv)); + dma_fence_get(fence); + r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb); + if (!r) + return true; + dma_fence_put(fence); + } + + return false; +} + +static bool dma_buf_poll_excl(struct dma_resv *resv, + struct dma_buf_poll_cb_t *dcb) +{ + struct dma_fence *fence = dma_resv_excl_fence(resv); + int r; + + if (!fence) + return false; + + dma_fence_get(fence); + r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb); + if (!r) + return true; + dma_fence_put(fence); + + return false; }
static __poll_t dma_buf_poll(struct file *file, poll_table *poll) { struct dma_buf *dmabuf; struct dma_resv *resv; - struct dma_resv_list *fobj; - struct dma_fence *fence_excl; __poll_t events; - unsigned shared_count, seq;
dmabuf = file->private_data; if (!dmabuf || !dmabuf->resv) @@ -228,101 +267,50 @@ static __poll_t dma_buf_poll(struct file if (!events) return 0;
-retry: - seq = read_seqcount_begin(&resv->seq); - rcu_read_lock(); - - fobj = rcu_dereference(resv->fence); - if (fobj) - shared_count = fobj->shared_count; - else - shared_count = 0; - fence_excl = dma_resv_excl_fence(resv); - if (read_seqcount_retry(&resv->seq, seq)) { - rcu_read_unlock(); - goto retry; - } - - if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) { - struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl; - __poll_t pevents = EPOLLIN; + dma_resv_lock(resv, NULL);
- if (shared_count == 0) - pevents |= EPOLLOUT; + if (events & EPOLLOUT) { + struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_out;
+ /* Check that callback isn't busy */ spin_lock_irq(&dmabuf->poll.lock); - if (dcb->active) { - dcb->active |= pevents; - events &= ~pevents; - } else - dcb->active = pevents; + if (dcb->active) + events &= ~EPOLLOUT; + else + dcb->active = EPOLLOUT; spin_unlock_irq(&dmabuf->poll.lock);
- if (events & pevents) { - if (!dma_fence_get_rcu(fence_excl)) { - /* force a recheck */ - events &= ~pevents; + if (events & EPOLLOUT) { + if (!dma_buf_poll_shared(resv, dcb) && + !dma_buf_poll_excl(resv, dcb)) + /* No callback queued, wake up any other waiters */ dma_buf_poll_cb(NULL, &dcb->cb); - } else if (!dma_fence_add_callback(fence_excl, &dcb->cb, - dma_buf_poll_cb)) { - events &= ~pevents; - dma_fence_put(fence_excl); - } else { - /* - * No callback queued, wake up any additional - * waiters. - */ - dma_fence_put(fence_excl); - dma_buf_poll_cb(NULL, &dcb->cb); - } + else + events &= ~EPOLLOUT; } }
- if ((events & EPOLLOUT) && shared_count > 0) { - struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_shared; - int i; + if (events & EPOLLIN) { + struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_in;
- /* Only queue a new callback if no event has fired yet */ + /* Check that callback isn't busy */ spin_lock_irq(&dmabuf->poll.lock); if (dcb->active) - events &= ~EPOLLOUT; + events &= ~EPOLLIN; else - dcb->active = EPOLLOUT; + dcb->active = EPOLLIN; spin_unlock_irq(&dmabuf->poll.lock);
- if (!(events & EPOLLOUT)) - goto out; - - for (i = 0; i < shared_count; ++i) { - struct dma_fence *fence = rcu_dereference(fobj->shared[i]); - - if (!dma_fence_get_rcu(fence)) { - /* - * fence refcount dropped to zero, this means - * that fobj has been freed - * - * call dma_buf_poll_cb and force a recheck! - */ - events &= ~EPOLLOUT; + if (events & EPOLLIN) { + if (!dma_buf_poll_excl(resv, dcb)) + /* No callback queued, wake up any other waiters */ dma_buf_poll_cb(NULL, &dcb->cb); - break; - } - if (!dma_fence_add_callback(fence, &dcb->cb, - dma_buf_poll_cb)) { - dma_fence_put(fence); - events &= ~EPOLLOUT; - break; - } - dma_fence_put(fence); + else + events &= ~EPOLLIN; } - - /* No callback queued, wake up any additional waiters. */ - if (i == shared_count) - dma_buf_poll_cb(NULL, &dcb->cb); }
-out: - rcu_read_unlock(); + dma_resv_unlock(resv); return events; }
@@ -565,8 +553,8 @@ struct dma_buf *dma_buf_export(const str dmabuf->owner = exp_info->owner; spin_lock_init(&dmabuf->name_lock); init_waitqueue_head(&dmabuf->poll); - dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll; - dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0; + dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll; + dmabuf->cb_in.active = dmabuf->cb_out.active = 0;
if (!resv) { resv = (struct dma_resv *)&dmabuf[1]; --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -433,7 +433,7 @@ struct dma_buf { wait_queue_head_t *poll;
__poll_t active; - } cb_excl, cb_shared; + } cb_in, cb_out; #ifdef CONFIG_DMABUF_SYSFS_STATS /** * @sysfs_entry:
From: Benjamin Li benl@squareup.com
commit d6dbce453b19c64b96f3e927b10230f9a704b504 upstream.
Firmware sends delete_sta_context_ind when it detects the AP has gone away in STA mode. Right now the handler for that indication only handles AP mode; fix it to also handle STA mode.
Cc: stable@vger.kernel.org Signed-off-by: Benjamin Li benl@squareup.com Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Reviewed-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210901180606.11686-1-benl@squareup.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/ath/wcn36xx/smd.c | 44 ++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-)
--- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2623,30 +2623,52 @@ static int wcn36xx_smd_delete_sta_contex size_t len) { struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf; - struct wcn36xx_vif *tmp; + struct wcn36xx_vif *vif_priv; + struct ieee80211_vif *vif; + struct ieee80211_bss_conf *bss_conf; struct ieee80211_sta *sta; + bool found = false;
if (len != sizeof(*rsp)) { wcn36xx_warn("Corrupted delete sta indication\n"); return -EIO; }
- wcn36xx_dbg(WCN36XX_DBG_HAL, "delete station indication %pM index %d\n", - rsp->addr2, rsp->sta_id); + wcn36xx_dbg(WCN36XX_DBG_HAL, + "delete station indication %pM index %d reason %d\n", + rsp->addr2, rsp->sta_id, rsp->reason_code);
- list_for_each_entry(tmp, &wcn->vif_list, list) { + list_for_each_entry(vif_priv, &wcn->vif_list, list) { rcu_read_lock(); - sta = ieee80211_find_sta(wcn36xx_priv_to_vif(tmp), rsp->addr2); - if (sta) - ieee80211_report_low_ack(sta, 0); + vif = wcn36xx_priv_to_vif(vif_priv); + + if (vif->type == NL80211_IFTYPE_STATION) { + /* We could call ieee80211_find_sta too, but checking + * bss_conf is clearer. + */ + bss_conf = &vif->bss_conf; + if (vif_priv->sta_assoc && + !memcmp(bss_conf->bssid, rsp->addr2, ETH_ALEN)) { + found = true; + wcn36xx_dbg(WCN36XX_DBG_HAL, + "connection loss bss_index %d\n", + vif_priv->bss_index); + ieee80211_connection_loss(vif); + } + } else { + sta = ieee80211_find_sta(vif, rsp->addr2); + if (sta) { + found = true; + ieee80211_report_low_ack(sta, 0); + } + } + rcu_read_unlock(); - if (sta) + if (found) return 0; }
- wcn36xx_warn("STA with addr %pM and index %d not found\n", - rsp->addr2, - rsp->sta_id); + wcn36xx_warn("BSS or STA with addr %pM not found\n", rsp->addr2); return -ENOENT; }
From: Martin Fuzzey martin.fuzzey@flowbird.group
commit 9b14ed6e11b72dd4806535449ca6c6962cb2369d upstream.
When BT coexistence is enabled (eg oper mode 13, which is the default) the initialisation on startup sometimes silently fails.
In a normal initialisation we see usb 1-1.3: Product: Wireless USB Network Module usb 1-1.3: Manufacturer: Redpine Signals, Inc. usb 1-1.3: SerialNumber: 000000000001 rsi_91x: rsi_probe: Initialized os intf ops rsi_91x: rsi_load_9116_firmware: Loading chunk 0 rsi_91x: rsi_load_9116_firmware: Loading chunk 1 rsi_91x: rsi_load_9116_firmware: Loading chunk 2 rsi_91x: Max Stations Allowed = 1
But sometimes the last log is missing and the wlan net device is not created.
Running a userspace loop that resets the hardware via a GPIO shows the problem occurring ~5/100 resets.
The problem does not occur in oper mode 1 (wifi only).
Adding logs shows that the initialisation state machine requests a MAC reset via rsi_send_reset_mac() but the firmware does not reply, leading to the initialisation sequence being incomplete.
Fix this by delaying attaching the BT adapter until the wifi initialisation has completed.
With this applied I have done > 300 reset loops with no errors.
Fixes: 716b840c7641 ("rsi: handle BT traffic in driver") Signed-off-by: Martin Fuzzey martin.fuzzey@flowbird.group CC: stable@vger.kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1630337206-12410-2-git-send-email-martin.fuzzey@fl... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/rsi/rsi_91x_main.c | 16 +++++++++++++--- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 3 +++ drivers/net/wireless/rsi/rsi_main.h | 2 ++ 3 files changed, 18 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/rsi/rsi_91x_main.c +++ b/drivers/net/wireless/rsi/rsi_91x_main.c @@ -211,9 +211,10 @@ int rsi_read_pkt(struct rsi_common *comm bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST]; if (bt_pkt_type == BT_CARD_READY_IND) { rsi_dbg(INFO_ZONE, "BT Card ready recvd\n"); - if (rsi_bt_ops.attach(common, &g_proto_ops)) - rsi_dbg(ERR_ZONE, - "Failed to attach BT module\n"); + if (common->fsm_state == FSM_MAC_INIT_DONE) + rsi_attach_bt(common); + else + common->bt_defer_attach = true; } else { if (common->bt_adapter) rsi_bt_ops.recv_pkt(common->bt_adapter, @@ -278,6 +279,15 @@ void rsi_set_bt_context(void *priv, void } #endif
+void rsi_attach_bt(struct rsi_common *common) +{ +#ifdef CONFIG_RSI_COEX + if (rsi_bt_ops.attach(common, &g_proto_ops)) + rsi_dbg(ERR_ZONE, + "Failed to attach BT module\n"); +#endif +} + /** * rsi_91x_init() - This function initializes os interface operations. * @oper_mode: One of DEV_OPMODE_*. --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -2071,6 +2071,9 @@ static int rsi_handle_ta_confirm_type(st if (common->reinit_hw) { complete(&common->wlan_init_completion); } else { + if (common->bt_defer_attach) + rsi_attach_bt(common); + return rsi_mac80211_attach(common); } } --- a/drivers/net/wireless/rsi/rsi_main.h +++ b/drivers/net/wireless/rsi/rsi_main.h @@ -320,6 +320,7 @@ struct rsi_common { struct ieee80211_vif *roc_vif;
bool eapol4_confirm; + bool bt_defer_attach; void *bt_adapter;
struct cfg80211_scan_request *hwscan; @@ -401,5 +402,6 @@ struct rsi_host_intf_ops {
enum rsi_host_intf rsi_get_host_intf(void *priv); void rsi_set_bt_context(void *priv, void *bt_context); +void rsi_attach_bt(struct rsi_common *common);
#endif
From: Martin Fuzzey martin.fuzzey@flowbird.group
commit 99ac6018821253ec67f466086afb63fc18ea48e2 upstream.
My previous patch checked if encryption should be enabled by directly checking info->control.hw_key (like the downstream driver). However that missed that the control and driver_info members of struct ieee80211_tx_info are union fields.
Due to this when rsi_core_xmit() updates fields in "tx_params" (driver_info) it can overwrite the control.hw_key, causing the result of the later test to be incorrect.
With the current structure layout the first byte of control.hw_key is overlayed with the vap_id so, since we only test if control.hw_key is NULL / non NULL, a non zero vap_id will incorrectly enable encryption.
In basic STA and AP modes the vap_id is always zero so it works but in P2P client mode a second VIF is created causing vap_id to be non zero and hence encryption to be enabled before keys have been set.
Fix this by extracting the key presence flag to a new field in the driver private tx_params structure and populating it first.
Fixes: 314538041b56 ("rsi: fix AP mode with WPA failure due to encrypted EAPOL") Signed-off-by: Martin Fuzzey martin.fuzzey@flowbird.group CC: stable@vger.kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1630337206-12410-3-git-send-email-martin.fuzzey@fl... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/rsi/rsi_91x_core.c | 2 ++ drivers/net/wireless/rsi/rsi_91x_hal.c | 2 +- drivers/net/wireless/rsi/rsi_main.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/rsi/rsi_91x_core.c +++ b/drivers/net/wireless/rsi/rsi_91x_core.c @@ -399,6 +399,8 @@ void rsi_core_xmit(struct rsi_common *co
info = IEEE80211_SKB_CB(skb); tx_params = (struct skb_info *)info->driver_data; + /* info->driver_data and info->control part of union so make copy */ + tx_params->have_key = !!info->control.hw_key; wh = (struct ieee80211_hdr *)&skb->data[0]; tx_params->sta_id = 0;
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -203,7 +203,7 @@ int rsi_prepare_data_desc(struct rsi_com wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE);
if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) && - info->control.hw_key) { + tx_params->have_key) { if (rsi_is_cipher_wep(common)) ieee80211_size += 4; else --- a/drivers/net/wireless/rsi/rsi_main.h +++ b/drivers/net/wireless/rsi/rsi_main.h @@ -139,6 +139,7 @@ struct skb_info { u8 internal_hdr_size; struct ieee80211_vif *vif; u8 vap_id; + bool have_key; };
enum edca_queue {
From: Martin Fuzzey martin.fuzzey@flowbird.group
commit b515d097053a71d624e0c5840b42cd4caa653941 upstream.
P2P client mode was only working the first time. On subsequent connection attempts the group was successfully created but no data was sent (no transmitted data packets were seen with a sniffer).
The reason for this was that the hardware was being configured in fixed rate mode with rate RSI_RATE_1 (1Mbps) which is not valid in the 5GHz band.
In P2P mode wpa_supplicant uses NL80211_CMD_SET_TX_BITRATE_MASK to disallow the 11b rates in the 2.4GHz band which updated common->fixedrate_mask.
rsi_set_min_rate() then used the fixedrate_mask to calculate the minimum allowed rate, or 0xffff = auto if none was found. However that calculation did not account for the different rate sets allowed in the different bands leading to the error.
Fixing set_min_rate() would result in 6Mb/s being used all the time which is not what we want either.
The reason the problem did not occur on the first connection is that rsi_mac80211_set_rate_mask() only updated the fixedrate_mask for the *current* band. When it was called that was still 2.4GHz as the switch is done later. So the when set_min_rate() was subsequently called after the switch to 5GHz it still had a mask of zero, leading to defaulting to auto mode.
Fix this by differentiating the case of a single rate being requested, in which case the hardware will be used in fixed rate mode with just that rate, and multiple rates being requested, in which case we remain in auto mode but the firmware rate selection algorithm is configured with a restricted set of rates.
Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver") Signed-off-by: Martin Fuzzey martin.fuzzey@flowbird.group CC: stable@vger.kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1630337206-12410-4-git-send-email-martin.fuzzey@fl... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/rsi/rsi_91x_hal.c | 8 +-- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 74 ++++++++-------------------- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 21 +++++-- drivers/net/wireless/rsi/rsi_main.h | 12 +++- 4 files changed, 50 insertions(+), 65 deletions(-)
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -214,15 +214,17 @@ int rsi_prepare_data_desc(struct rsi_com RSI_WIFI_DATA_Q); data_desc->header_len = ieee80211_size;
- if (common->min_rate != RSI_RATE_AUTO) { + if (common->rate_config[common->band].fixed_enabled) { /* Send fixed rate */ + u16 fixed_rate = common->rate_config[common->band].fixed_hw_rate; + data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE); - data_desc->rate_info = cpu_to_le16(common->min_rate); + data_desc->rate_info = cpu_to_le16(fixed_rate);
if (conf_is_ht40(&common->priv->hw->conf)) data_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE);
- if ((common->vif_info[0].sgi) && (common->min_rate & 0x100)) { + if (common->vif_info[0].sgi && (fixed_rate & 0x100)) { /* Only MCS rates */ data_desc->rate_info |= cpu_to_le16(ENABLE_SHORTGI_RATE); --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -510,7 +510,6 @@ static int rsi_mac80211_add_interface(st if ((vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_P2P_GO)) { rsi_send_rx_filter_frame(common, DISALLOW_BEACONS); - common->min_rate = RSI_RATE_AUTO; for (i = 0; i < common->max_stations; i++) common->stations[i].sta = NULL; } @@ -1228,20 +1227,32 @@ static int rsi_mac80211_set_rate_mask(st struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) { + const unsigned int mcs_offset = ARRAY_SIZE(rsi_rates); struct rsi_hw *adapter = hw->priv; struct rsi_common *common = adapter->priv; - enum nl80211_band band = hw->conf.chandef.chan->band; + int i;
mutex_lock(&common->mutex); - common->fixedrate_mask[band] = 0;
- if (mask->control[band].legacy == 0xfff) { - common->fixedrate_mask[band] = - (mask->control[band].ht_mcs[0] << 12); - } else { - common->fixedrate_mask[band] = - mask->control[band].legacy; + for (i = 0; i < ARRAY_SIZE(common->rate_config); i++) { + struct rsi_rate_config *cfg = &common->rate_config[i]; + u32 bm; + + bm = mask->control[i].legacy | (mask->control[i].ht_mcs[0] << mcs_offset); + if (hweight32(bm) == 1) { /* single rate */ + int rate_index = ffs(bm) - 1; + + if (rate_index < mcs_offset) + cfg->fixed_hw_rate = rsi_rates[rate_index].hw_value; + else + cfg->fixed_hw_rate = rsi_mcsrates[rate_index - mcs_offset]; + cfg->fixed_enabled = true; + } else { + cfg->configured_mask = bm; + cfg->fixed_enabled = false; + } } + mutex_unlock(&common->mutex);
return 0; @@ -1378,46 +1389,6 @@ void rsi_indicate_pkt_to_os(struct rsi_c ieee80211_rx_irqsafe(hw, skb); }
-static void rsi_set_min_rate(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct rsi_common *common) -{ - u8 band = hw->conf.chandef.chan->band; - u8 ii; - u32 rate_bitmap; - bool matched = false; - - common->bitrate_mask[band] = sta->supp_rates[band]; - - rate_bitmap = (common->fixedrate_mask[band] & sta->supp_rates[band]); - - if (rate_bitmap & 0xfff) { - /* Find out the min rate */ - for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) { - if (rate_bitmap & BIT(ii)) { - common->min_rate = rsi_rates[ii].hw_value; - matched = true; - break; - } - } - } - - common->vif_info[0].is_ht = sta->ht_cap.ht_supported; - - if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) { - for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) { - if ((rate_bitmap >> 12) & BIT(ii)) { - common->min_rate = rsi_mcsrates[ii]; - matched = true; - break; - } - } - } - - if (!matched) - common->min_rate = 0xffff; -} - /** * rsi_mac80211_sta_add() - This function notifies driver about a peer getting * connected. @@ -1516,9 +1487,9 @@ static int rsi_mac80211_sta_add(struct i
if ((vif->type == NL80211_IFTYPE_STATION) || (vif->type == NL80211_IFTYPE_P2P_CLIENT)) { - rsi_set_min_rate(hw, sta, common); + common->bitrate_mask[common->band] = sta->supp_rates[common->band]; + common->vif_info[0].is_ht = sta->ht_cap.ht_supported; if (sta->ht_cap.ht_supported) { - common->vif_info[0].is_ht = true; common->bitrate_mask[NL80211_BAND_2GHZ] = sta->supp_rates[NL80211_BAND_2GHZ]; if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || @@ -1592,7 +1563,6 @@ static int rsi_mac80211_sta_remove(struc bss->qos = sta->wme; common->bitrate_mask[NL80211_BAND_2GHZ] = 0; common->bitrate_mask[NL80211_BAND_5GHZ] = 0; - common->min_rate = 0xffff; common->vif_info[0].is_ht = false; common->vif_info[0].sgi = false; common->vif_info[0].seq_start = 0; --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -276,7 +276,7 @@ static void rsi_set_default_parameters(s common->channel_width = BW_20MHZ; common->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; common->channel = 1; - common->min_rate = 0xffff; + memset(&common->rate_config, 0, sizeof(common->rate_config)); common->fsm_state = FSM_CARD_NOT_READY; common->iface_down = true; common->endpoint = EP_2GHZ_20MHZ; @@ -1314,7 +1314,7 @@ static int rsi_send_auto_rate_request(st u8 band = hw->conf.chandef.chan->band; u8 num_supported_rates = 0; u8 rate_table_offset, rate_offset = 0; - u32 rate_bitmap; + u32 rate_bitmap, configured_rates; u16 *selected_rates, min_rate; bool is_ht = false, is_sgi = false; u16 frame_len = sizeof(struct rsi_auto_rate); @@ -1364,6 +1364,10 @@ static int rsi_send_auto_rate_request(st is_sgi = true; }
+ /* Limit to any rates administratively configured by cfg80211 */ + configured_rates = common->rate_config[band].configured_mask ?: 0xffffffff; + rate_bitmap &= configured_rates; + if (band == NL80211_BAND_2GHZ) { if ((rate_bitmap == 0) && (is_ht)) min_rate = RSI_RATE_MCS0; @@ -1389,10 +1393,13 @@ static int rsi_send_auto_rate_request(st num_supported_rates = jj;
if (is_ht) { - for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) - selected_rates[jj++] = mcs[ii]; - num_supported_rates += ARRAY_SIZE(mcs); - rate_offset += ARRAY_SIZE(mcs); + for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) { + if (configured_rates & BIT(ii + ARRAY_SIZE(rsi_rates))) { + selected_rates[jj++] = mcs[ii]; + num_supported_rates++; + rate_offset++; + } + } }
sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL); @@ -1482,7 +1489,7 @@ void rsi_inform_bss_status(struct rsi_co qos_enable, aid, sta_id, vif); - if (common->min_rate == 0xffff) + if (!common->rate_config[common->band].fixed_enabled) rsi_send_auto_rate_request(common, sta, sta_id, vif); if (opmode == RSI_OPMODE_STA && !(assoc_cap & WLAN_CAPABILITY_PRIVACY) && --- a/drivers/net/wireless/rsi/rsi_main.h +++ b/drivers/net/wireless/rsi/rsi_main.h @@ -61,6 +61,7 @@ enum RSI_FSM_STATES { extern u32 rsi_zone_enabled; extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
+#define RSI_MAX_BANDS 2 #define RSI_MAX_VIFS 3 #define NUM_EDCA_QUEUES 4 #define IEEE80211_ADDR_LEN 6 @@ -230,6 +231,12 @@ struct rsi_9116_features { u32 ps_options; };
+struct rsi_rate_config { + u32 configured_mask; /* configured by mac80211 bits 0-11=legacy 12+ mcs */ + u16 fixed_hw_rate; + bool fixed_enabled; +}; + struct rsi_common { struct rsi_hw *priv; struct vif_priv vif_info[RSI_MAX_VIFS]; @@ -255,8 +262,8 @@ struct rsi_common { u8 channel_width;
u16 rts_threshold; - u16 bitrate_mask[2]; - u32 fixedrate_mask[2]; + u32 bitrate_mask[RSI_MAX_BANDS]; + struct rsi_rate_config rate_config[RSI_MAX_BANDS];
u8 rf_reset; struct transmit_q_stats tx_stats; @@ -277,7 +284,6 @@ struct rsi_common { u8 mac_id; u8 radio_id; u16 rate_pwr[20]; - u16 min_rate;
/* WMM algo related */ u8 selected_qnum;
From: Marek Vasut marex@denx.de
commit 31f97cf9f0c31143a2a6fcc89c4a1286ce20157e upstream.
The module parameters are missing dev_oper_mode 12, BT classic alone, add it. Moreover, the parameters encode newlines, which ends up being printed malformed e.g. by modinfo, so fix that too.
However, the module parameter string is duplicated in both USB and SDIO modules and the dev_oper_mode mode enumeration in those module parameters is a duplicate of macros used by the driver. Furthermore, the enumeration is confusing.
So, deduplicate the module parameter string and use __stringify() to encode the correct mode enumeration values into the module parameter string. Finally, replace 'Wi-Fi' with 'Wi-Fi alone' and 'BT' with 'BT classic alone' to clarify what those modes really mean.
Fixes: 898b255339310 ("rsi: add module parameter operating mode") Signed-off-by: Marek Vasut marex@denx.de Cc: Amitkumar Karwar amit.karwar@redpinesignals.com Cc: Angus Ainslie angus@akkea.ca Cc: David S. Miller davem@davemloft.net Cc: Jakub Kicinski kuba@kernel.org Cc: Kalle Valo kvalo@codeaurora.org Cc: Karun Eagalapati karun256@gmail.com Cc: Martin Fuzzey martin.fuzzey@flowbird.group Cc: Martin Kepplinger martink@posteo.de Cc: Prameela Rani Garnepudi prameela.j04cs@gmail.com Cc: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Cc: Siva Rebbagondla siva8118@gmail.com Cc: netdev@vger.kernel.org Cc: stable@vger.kernel.org # 4.17+ Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210916144245.10181-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/wireless/rsi/rsi_91x_sdio.c | 5 +---- drivers/net/wireless/rsi/rsi_91x_usb.c | 5 +---- drivers/net/wireless/rsi/rsi_hal.h | 11 +++++++++++ 3 files changed, 13 insertions(+), 8 deletions(-)
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -24,10 +24,7 @@ /* Default operating mode is wlan STA + BT */ static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; module_param(dev_oper_mode, ushort, 0444); -MODULE_PARM_DESC(dev_oper_mode, - "1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n" - "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n" - "6[AP + BT classic], 14[AP + BT classic + BT LE]"); +MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC);
/** * rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg. --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -25,10 +25,7 @@ /* Default operating mode is wlan STA + BT */ static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; module_param(dev_oper_mode, ushort, 0444); -MODULE_PARM_DESC(dev_oper_mode, - "1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n" - "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n" - "6[AP + BT classic], 14[AP + BT classic + BT LE]"); +MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC);
static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t flags);
--- a/drivers/net/wireless/rsi/rsi_hal.h +++ b/drivers/net/wireless/rsi/rsi_hal.h @@ -28,6 +28,17 @@ #define DEV_OPMODE_AP_BT 6 #define DEV_OPMODE_AP_BT_DUAL 14
+#define DEV_OPMODE_PARAM_DESC \ + __stringify(DEV_OPMODE_WIFI_ALONE) "[Wi-Fi alone], " \ + __stringify(DEV_OPMODE_BT_ALONE) "[BT classic alone], " \ + __stringify(DEV_OPMODE_BT_LE_ALONE) "[BT LE alone], " \ + __stringify(DEV_OPMODE_BT_DUAL) "[BT classic + BT LE alone], " \ + __stringify(DEV_OPMODE_STA_BT) "[Wi-Fi STA + BT classic], " \ + __stringify(DEV_OPMODE_STA_BT_LE) "[Wi-Fi STA + BT LE], " \ + __stringify(DEV_OPMODE_STA_BT_DUAL) "[Wi-Fi STA + BT classic + BT LE], " \ + __stringify(DEV_OPMODE_AP_BT) "[Wi-Fi AP + BT classic], " \ + __stringify(DEV_OPMODE_AP_BT_DUAL) "[Wi-Fi AP + BT classic + BT LE]" + #define FLASH_WRITE_CHUNK_SIZE (4 * 1024) #define FLASH_SECTOR_SIZE (4 * 1024)
From: Kan Liang kan.liang@linux.intel.com
commit 496a18f09374ad89b3ab4366019bc3975db90234 upstream.
There are three channels on a Ice Lake server, but only two channels will ever be active. Current perf only enables two channels.
Support the extra IMC channel, which may be activated on some Ice Lake machines. For a non-activated channel, the SW can still access it. The write will be ignored by the HW. 0 is always returned for the reading.
Fixes: 2b3b76b5ec67 ("perf/x86/intel/uncore: Add Ice Lake server uncore support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Andi Kleen ak@linux.intel.com Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/1629991963-102621-2-git-send-email-kan.liang@linux... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/events/intel/uncore_snbep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -452,7 +452,7 @@ #define ICX_M3UPI_PCI_PMON_BOX_CTL 0xa0
/* ICX IMC */ -#define ICX_NUMBER_IMC_CHN 2 +#define ICX_NUMBER_IMC_CHN 3 #define ICX_IMC_MEM_STRIDE 0x4
/* SPR */ @@ -5463,7 +5463,7 @@ static struct intel_uncore_ops icx_uncor static struct intel_uncore_type icx_uncore_imc = { .name = "imc", .num_counters = 4, - .num_boxes = 8, + .num_boxes = 12, .perf_ctr_bits = 48, .fixed_ctr_bits = 48, .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR,
From: Kan Liang kan.liang@linux.intel.com
commit e2bb9fab08cbcc7922050c7eb0bd650807abfa4e upstream.
The uncore unit with the type ID 0 and the unit ID 0 is missed.
The table3 of the uncore unit maybe 0. The uncore_discovery_invalid_unit() mistakenly treated it as an invalid value.
Remove the !unit.table3 check.
Fixes: edae1f06c2cd ("perf/x86/intel/uncore: Parse uncore discovery tables") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Andi Kleen ak@linux.intel.com Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/1629991963-102621-3-git-send-email-kan.liang@linux... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/events/intel/uncore_discovery.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/events/intel/uncore_discovery.h +++ b/arch/x86/events/intel/uncore_discovery.h @@ -30,7 +30,7 @@
#define uncore_discovery_invalid_unit(unit) \ - (!unit.table1 || !unit.ctl || !unit.table3 || \ + (!unit.table1 || !unit.ctl || \ unit.table1 == -1ULL || unit.ctl == -1ULL || \ unit.table3 == -1ULL)
From: Kan Liang kan.liang@linux.intel.com
commit f42e8a603c88f72bf047a710b9fc1d3579f31e71 upstream.
According to the latest uncore document, both NUM_OUTSTANDING_REQ_OF_CPU (0x88) event and COMP_BUF_OCCUPANCY(0xd5) event also have constraints. Add them into the event constraints table.
Fixes: 2b3b76b5ec67 ("perf/x86/intel/uncore: Add Ice Lake server uncore support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/1629991963-102621-4-git-send-email-kan.liang@linux... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/events/intel/uncore_snbep.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -5076,8 +5076,10 @@ static struct event_constraint icx_uncor UNCORE_EVENT_CONSTRAINT(0x02, 0x3), UNCORE_EVENT_CONSTRAINT(0x03, 0x3), UNCORE_EVENT_CONSTRAINT(0x83, 0x3), + UNCORE_EVENT_CONSTRAINT(0x88, 0xc), UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), + UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), EVENT_CONSTRAINT_END };
From: Alok Prasad palok@marvell.com
commit 4f960393a0ee9a39469ceb7c8077ae8db665cc12 upstream.
This patch fixes a crash caused by querying the QP via netlink, and corrects the state of GSI qp. GSI qp's have a NULL qed_qp.
The call trace is generated by: $ rdma res show
BUG: kernel NULL pointer dereference, address: 0000000000000034 Hardware name: Dell Inc. PowerEdge R720/0M1GCR, BIOS 1.2.6 05/10/2012 RIP: 0010:qed_rdma_query_qp+0x33/0x1a0 [qed] RSP: 0018:ffffba560a08f580 EFLAGS: 00010206 RAX: 0000000200000000 RBX: ffffba560a08f5b8 RCX: 0000000000000000 RDX: ffffba560a08f5b8 RSI: 0000000000000000 RDI: ffff9807ee458090 RBP: ffffba560a08f5a0 R08: 0000000000000000 R09: ffff9807890e7048 R10: ffffba560a08f658 R11: 0000000000000000 R12: 0000000000000000 R13: ffff9807ee458090 R14: ffff9807f0afb000 R15: ffffba560a08f7ec FS: 00007fbbf8bfe740(0000) GS:ffff980aafa00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000034 CR3: 00000001720ba001 CR4: 00000000000606f0 Call Trace: qedr_query_qp+0x82/0x360 [qedr] ib_query_qp+0x34/0x40 [ib_core] ? ib_query_qp+0x34/0x40 [ib_core] fill_res_qp_entry_query.isra.26+0x47/0x1d0 [ib_core] ? __nla_put+0x20/0x30 ? nla_put+0x33/0x40 fill_res_qp_entry+0xe3/0x120 [ib_core] res_get_common_dumpit+0x3f8/0x5d0 [ib_core] ? fill_res_cm_id_entry+0x1f0/0x1f0 [ib_core] nldev_res_get_qp_dumpit+0x1a/0x20 [ib_core] netlink_dump+0x156/0x2f0 __netlink_dump_start+0x1ab/0x260 rdma_nl_rcv+0x1de/0x330 [ib_core] ? nldev_res_get_cm_id_dumpit+0x20/0x20 [ib_core] netlink_unicast+0x1b8/0x270 netlink_sendmsg+0x33e/0x470 sock_sendmsg+0x63/0x70 __sys_sendto+0x13f/0x180 ? setup_sgl.isra.12+0x70/0xc0 __x64_sys_sendto+0x28/0x30 do_syscall_64+0x3a/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
Cc: stable@vger.kernel.org Fixes: cecbcddf6461 ("qedr: Add support for QP verbs") Link: https://lore.kernel.org/r/20211027184329.18454-1-palok@marvell.com Signed-off-by: Ariel Elior aelior@marvell.com Signed-off-by: Shai Malin smalin@marvell.com Signed-off-by: Prabhakar Kushwaha pkushwaha@marvell.com Signed-off-by: Alok Prasad palok@marvell.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/infiniband/hw/qedr/verbs.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
--- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -2744,15 +2744,18 @@ int qedr_query_qp(struct ib_qp *ibqp, int rc = 0;
memset(¶ms, 0, sizeof(params)); - - rc = dev->ops->rdma_query_qp(dev->rdma_ctx, qp->qed_qp, ¶ms); - if (rc) - goto err; - memset(qp_attr, 0, sizeof(*qp_attr)); memset(qp_init_attr, 0, sizeof(*qp_init_attr));
- qp_attr->qp_state = qedr_get_ibqp_state(params.state); + if (qp->qp_type != IB_QPT_GSI) { + rc = dev->ops->rdma_query_qp(dev->rdma_ctx, qp->qed_qp, ¶ms); + if (rc) + goto err; + qp_attr->qp_state = qedr_get_ibqp_state(params.state); + } else { + qp_attr->qp_state = qedr_get_ibqp_state(QED_ROCE_QP_STATE_RTS); + } + qp_attr->cur_qp_state = qedr_get_ibqp_state(params.state); qp_attr->path_mtu = ib_mtu_int_to_enum(params.mtu); qp_attr->path_mig_state = IB_MIG_MIGRATED;
From: Dmitry Osipenko digetx@gmail.com
commit 824edd866a13db7dbb0d8e26d2142f10271b6460 upstream.
The default card name for Trimslice device should be "tegra-trimslice". It got lost by accident during unification of machine sound drivers, fix it.
Cc: stable@vger.kernel.org Fixes: cc8f70f56039 ("ASoC: tegra: Unify ASoC machine drivers") Signed-off-by: Dmitry Osipenko digetx@gmail.com Link: https://lore.kernel.org/r/20211024192853.21957-2-digetx@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/tegra/tegra_asoc_machine.c | 1 + 1 file changed, 1 insertion(+)
--- a/sound/soc/tegra/tegra_asoc_machine.c +++ b/sound/soc/tegra/tegra_asoc_machine.c @@ -686,6 +686,7 @@ static struct snd_soc_dai_link tegra_tlv };
static struct snd_soc_card snd_soc_tegra_trimslice = { + .name = "tegra-trimslice", .components = "codec:tlv320aic23", .dai_link = &tegra_tlv320aic23_dai, .num_links = 1,
From: Dmitry Osipenko digetx@gmail.com
commit de8fc2b0a3f9930f3cbe801d40758bb1d80b0ad8 upstream.
The device-tree of AC97 codecs need to be parsed differently from I2S codecs, plus codec device may need to be created. This was missed by the patch that unified machine drivers into a single driver, fix it. It should restore audio on Toradex Colibri board.
Cc: stable@vger.kernel.org Fixes: cc8f70f56039 ("ASoC: tegra: Unify ASoC machine drivers") Signed-off-by: Dmitry Osipenko digetx@gmail.com Link: https://lore.kernel.org/r/20211024192853.21957-1-digetx@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/tegra/tegra_asoc_machine.c | 63 ++++++++++++++++++++++++++++------- sound/soc/tegra/tegra_asoc_machine.h | 1 2 files changed, 52 insertions(+), 12 deletions(-)
--- a/sound/soc/tegra/tegra_asoc_machine.c +++ b/sound/soc/tegra/tegra_asoc_machine.c @@ -341,9 +341,34 @@ tegra_machine_parse_phandle(struct devic return np; }
+static void tegra_machine_unregister_codec(void *pdev) +{ + platform_device_unregister(pdev); +} + +static int tegra_machine_register_codec(struct device *dev, const char *name) +{ + struct platform_device *pdev; + int err; + + if (!name) + return 0; + + pdev = platform_device_register_simple(name, -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + err = devm_add_action_or_reset(dev, tegra_machine_unregister_codec, + pdev); + if (err) + return err; + + return 0; +} + int tegra_asoc_machine_probe(struct platform_device *pdev) { - struct device_node *np_codec, *np_i2s; + struct device_node *np_codec, *np_i2s, *np_ac97; const struct tegra_asoc_data *asoc; struct device *dev = &pdev->dev; struct tegra_machine *machine; @@ -404,17 +429,30 @@ int tegra_asoc_machine_probe(struct plat return err; }
- np_codec = tegra_machine_parse_phandle(dev, "nvidia,audio-codec"); - if (IS_ERR(np_codec)) - return PTR_ERR(np_codec); - - np_i2s = tegra_machine_parse_phandle(dev, "nvidia,i2s-controller"); - if (IS_ERR(np_i2s)) - return PTR_ERR(np_i2s); - - card->dai_link->cpus->of_node = np_i2s; - card->dai_link->codecs->of_node = np_codec; - card->dai_link->platforms->of_node = np_i2s; + if (asoc->set_ac97) { + err = tegra_machine_register_codec(dev, asoc->codec_dev_name); + if (err) + return err; + + np_ac97 = tegra_machine_parse_phandle(dev, "nvidia,ac97-controller"); + if (IS_ERR(np_ac97)) + return PTR_ERR(np_ac97); + + card->dai_link->cpus->of_node = np_ac97; + card->dai_link->platforms->of_node = np_ac97; + } else { + np_codec = tegra_machine_parse_phandle(dev, "nvidia,audio-codec"); + if (IS_ERR(np_codec)) + return PTR_ERR(np_codec); + + np_i2s = tegra_machine_parse_phandle(dev, "nvidia,i2s-controller"); + if (IS_ERR(np_i2s)) + return PTR_ERR(np_i2s); + + card->dai_link->cpus->of_node = np_i2s; + card->dai_link->codecs->of_node = np_codec; + card->dai_link->platforms->of_node = np_i2s; + }
if (asoc->add_common_controls) { card->controls = tegra_machine_controls; @@ -589,6 +627,7 @@ static struct snd_soc_card snd_soc_tegra static const struct tegra_asoc_data tegra_wm9712_data = { .card = &snd_soc_tegra_wm9712, .add_common_dapm_widgets = true, + .codec_dev_name = "wm9712-codec", .set_ac97 = true, };
--- a/sound/soc/tegra/tegra_asoc_machine.h +++ b/sound/soc/tegra/tegra_asoc_machine.h @@ -13,6 +13,7 @@ struct snd_soc_pcm_runtime;
struct tegra_asoc_data { unsigned int (*mclk_rate)(unsigned int srate); + const char *codec_dev_name; struct snd_soc_card *card; unsigned int mclk_id; bool hp_jack_gpio_active_low;
From: Eric W. Biederman ebiederm@xmission.com
commit 7d613f9f72ec8f90ddefcae038fdae5adb8404b3 upstream.
The existence of sigkill_pending is a little silly as it is functionally a duplicate of fatal_signal_pending that is used in exactly one place.
Checking for pending fatal signals and returning early in ptrace_stop is actively harmful. It casues the ptrace_stop called by ptrace_signal to return early before setting current->exit_code. Later when ptrace_signal reads the signal number from current->exit_code is undefined, making it unpredictable what will happen.
Instead rely on the fact that schedule will not sleep if there is a pending signal that can awaken a task.
Removing the explict sigkill_pending test fixes fixes ptrace_signal when ptrace_stop does not stop because current->exit_code is always set to to signr.
Cc: stable@vger.kernel.org Fixes: 3d749b9e676b ("ptrace: simplify ptrace_stop()->sigkill_pending() path") Fixes: 1a669c2f16d4 ("Add arch_ptrace_stop") Link: https://lkml.kernel.org/r/87pmsyx29t.fsf@disp2133 Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/signal.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-)
--- a/kernel/signal.c +++ b/kernel/signal.c @@ -2169,15 +2169,6 @@ static inline bool may_ptrace_stop(void) return true; }
-/* - * Return non-zero if there is a SIGKILL that should be waking us up. - * Called with the siglock held. - */ -static bool sigkill_pending(struct task_struct *tsk) -{ - return sigismember(&tsk->pending.signal, SIGKILL) || - sigismember(&tsk->signal->shared_pending.signal, SIGKILL); -}
/* * This must be called with current->sighand->siglock held. @@ -2204,17 +2195,16 @@ static void ptrace_stop(int exit_code, i * calling arch_ptrace_stop, so we must release it now. * To preserve proper semantics, we must do this before * any signal bookkeeping like checking group_stop_count. - * Meanwhile, a SIGKILL could come in before we retake the - * siglock. That must prevent us from sleeping in TASK_TRACED. - * So after regaining the lock, we must check for SIGKILL. */ spin_unlock_irq(¤t->sighand->siglock); arch_ptrace_stop(exit_code, info); spin_lock_irq(¤t->sighand->siglock); - if (sigkill_pending(current)) - return; }
+ /* + * schedule() will not sleep if there is a pending signal that + * can awaken the task. + */ set_special_state(TASK_TRACED);
/*
From: Wolfram Sang wsa+renesas@sang-engineering.com
commit fff53a551db50f5edecaa0b29a64056ab8d2bbca upstream.
This patch fixes 2 problems: [1] The output warning logs and data loss when performing mount/umount then remount the device with jffs2 format. [2] The access width of SMWDR[0:1]/SMRDR[0:1] register is wrong.
This is the sample warning logs when performing mount/umount then remount the device with jffs2 format: jffs2: jffs2_scan_inode_node(): CRC failed on node at 0x031c51d4: Read 0x00034e00, calculated 0xadb272a7
The reason for issue [1] is that the writing data seems to get messed up. Data is only completed when the number of bytes is divisible by 4. If you only have 3 bytes of data left to write, 1 garbage byte is inserted after the end of the write stream. If you only have 2 bytes of data left to write, 2 bytes of '00' are added into the write stream. If you only have 1 byte of data left to write, 2 bytes of '00' are added into the write stream. 1 garbage byte is inserted after the end of the write stream.
To solve problem [1], data must be written continuously in serial and the write stream ends when data is out.
Following HW manual 62.2.15, access to SMWDR0 register should be in the same size as the transfer size specified in the SPIDE[3:0] bits in the manual mode enable setting register (SMENR). Be sure to access from address 0.
So, in 16-bit transfer (SPIDE[3:0]=b'1100), SMWDR0 should be accessed by 16-bit width. Similar to SMWDR1, SMDDR0/1 registers. In current code, SMWDR0 register is accessed by regmap_write() that only set up to do 32-bit width.
To solve problem [2], data must be written 16-bit or 8-bit when transferring 1-byte or 2-byte.
Fixes: ca7d8b980b67 ("memory: add Renesas RPC-IF driver") Cc: stable@vger.kernel.org Signed-off-by: Duc Nguyen duc.nguyen.ub@renesas.com [wsa: refactored to use regmap only via reg_read/reg_write] Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Tested-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Link: https://lore.kernel.org/r/20210922091007.5516-1-wsa+renesas@sang-engineering... Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/memory/renesas-rpc-if.c | 113 +++++++++++++++++++++++++++------------- include/memory/renesas-rpc-if.h | 1 2 files changed, 79 insertions(+), 35 deletions(-)
--- a/drivers/memory/renesas-rpc-if.c +++ b/drivers/memory/renesas-rpc-if.c @@ -160,10 +160,62 @@ static const struct regmap_access_table .n_yes_ranges = ARRAY_SIZE(rpcif_volatile_ranges), };
+ +/* + * Custom accessor functions to ensure SMRDR0 and SMWDR0 are always accessed + * with proper width. Requires SMENR_SPIDE to be correctly set before! + */ +static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct rpcif *rpc = context; + + if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) { + u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF); + + if (spide == 0x8) { + *val = readb(rpc->base + reg); + return 0; + } else if (spide == 0xC) { + *val = readw(rpc->base + reg); + return 0; + } else if (spide != 0xF) { + return -EILSEQ; + } + } + + *val = readl(rpc->base + reg); + return 0; + +} + +static int rpcif_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct rpcif *rpc = context; + + if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) { + u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF); + + if (spide == 0x8) { + writeb(val, rpc->base + reg); + return 0; + } else if (spide == 0xC) { + writew(val, rpc->base + reg); + return 0; + } else if (spide != 0xF) { + return -EILSEQ; + } + } + + writel(val, rpc->base + reg); + return 0; +} + static const struct regmap_config rpcif_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, + .reg_read = rpcif_reg_read, + .reg_write = rpcif_reg_write, .fast_io = true, .max_register = RPCIF_PHYINT, .volatile_table = &rpcif_volatile_table, @@ -173,17 +225,15 @@ int rpcif_sw_init(struct rpcif *rpc, str { struct platform_device *pdev = to_platform_device(dev); struct resource *res; - void __iomem *base;
rpc->dev = dev;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); - base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) - return PTR_ERR(base); + rpc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rpc->base)) + return PTR_ERR(rpc->base);
- rpc->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &rpcif_regmap_config); + rpc->regmap = devm_regmap_init(&pdev->dev, NULL, rpc, &rpcif_regmap_config); if (IS_ERR(rpc->regmap)) { dev_err(&pdev->dev, "failed to init regmap for rpcif, error %ld\n", @@ -354,20 +404,16 @@ void rpcif_prepare(struct rpcif *rpc, co nbytes = op->data.nbytes; rpc->xferlen = nbytes;
- rpc->enable |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)) | - RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth)); + rpc->enable |= RPCIF_SMENR_SPIDB(rpcif_bit_size(op->data.buswidth)); } } EXPORT_SYMBOL(rpcif_prepare);
int rpcif_manual_xfer(struct rpcif *rpc) { - u32 smenr, smcr, pos = 0, max = 4; + u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4; int ret = 0;
- if (rpc->bus_size == 2) - max = 8; - pm_runtime_get_sync(rpc->dev);
regmap_update_bits(rpc->regmap, RPCIF_PHYCNT, @@ -378,37 +424,36 @@ int rpcif_manual_xfer(struct rpcif *rpc) regmap_write(rpc->regmap, RPCIF_SMOPR, rpc->option); regmap_write(rpc->regmap, RPCIF_SMDMCR, rpc->dummy); regmap_write(rpc->regmap, RPCIF_SMDRENR, rpc->ddr); + regmap_write(rpc->regmap, RPCIF_SMADR, rpc->smadr); smenr = rpc->enable;
switch (rpc->dir) { case RPCIF_DATA_OUT: while (pos < rpc->xferlen) { - u32 nbytes = rpc->xferlen - pos; - u32 data[2]; + u32 bytes_left = rpc->xferlen - pos; + u32 nbytes, data[2];
smcr = rpc->smcr | RPCIF_SMCR_SPIE; - if (nbytes > max) { - nbytes = max; + + /* nbytes may only be 1, 2, 4, or 8 */ + nbytes = bytes_left >= max ? max : (1 << ilog2(bytes_left)); + if (bytes_left > nbytes) smcr |= RPCIF_SMCR_SSLKP; - } + + smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); + regmap_write(rpc->regmap, RPCIF_SMENR, smenr);
memcpy(data, rpc->buffer + pos, nbytes); - if (nbytes > 4) { + if (nbytes == 8) { regmap_write(rpc->regmap, RPCIF_SMWDR1, data[0]); regmap_write(rpc->regmap, RPCIF_SMWDR0, data[1]); - } else if (nbytes > 2) { + } else { regmap_write(rpc->regmap, RPCIF_SMWDR0, data[0]); - } else { - regmap_write(rpc->regmap, RPCIF_SMWDR0, - data[0] << 16); }
- regmap_write(rpc->regmap, RPCIF_SMADR, - rpc->smadr + pos); - regmap_write(rpc->regmap, RPCIF_SMENR, smenr); regmap_write(rpc->regmap, RPCIF_SMCR, smcr); ret = wait_msg_xfer_end(rpc); if (ret) @@ -448,14 +493,16 @@ int rpcif_manual_xfer(struct rpcif *rpc) break; } while (pos < rpc->xferlen) { - u32 nbytes = rpc->xferlen - pos; - u32 data[2]; + u32 bytes_left = rpc->xferlen - pos; + u32 nbytes, data[2];
- if (nbytes > max) - nbytes = max; + /* nbytes may only be 1, 2, 4, or 8 */ + nbytes = bytes_left >= max ? max : (1 << ilog2(bytes_left));
regmap_write(rpc->regmap, RPCIF_SMADR, rpc->smadr + pos); + smenr &= ~RPCIF_SMENR_SPIDE(0xF); + smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); regmap_write(rpc->regmap, RPCIF_SMENR, smenr); regmap_write(rpc->regmap, RPCIF_SMCR, rpc->smcr | RPCIF_SMCR_SPIE); @@ -463,18 +510,14 @@ int rpcif_manual_xfer(struct rpcif *rpc) if (ret) goto err_out;
- if (nbytes > 4) { + if (nbytes == 8) { regmap_read(rpc->regmap, RPCIF_SMRDR1, &data[0]); regmap_read(rpc->regmap, RPCIF_SMRDR0, &data[1]); - } else if (nbytes > 2) { - regmap_read(rpc->regmap, RPCIF_SMRDR0, - &data[0]); - } else { + } else { regmap_read(rpc->regmap, RPCIF_SMRDR0, &data[0]); - data[0] >>= 16; } memcpy(rpc->buffer + pos, data, nbytes);
--- a/include/memory/renesas-rpc-if.h +++ b/include/memory/renesas-rpc-if.h @@ -59,6 +59,7 @@ struct rpcif_op {
struct rpcif { struct device *dev; + void __iomem *base; void __iomem *dirmap; struct regmap *regmap; struct reset_control *rstc;
From: Eric W. Biederman ebiederm@xmission.com
commit 95bf9d646c3c3f95cb0be7e703b371db8da5be68 upstream.
When an instruction to save or restore a register from the stack fails in _save_fp_context or _restore_fp_context return with -EFAULT. This change was made to r2300_fpu.S[1] but it looks like it got lost with the introduction of EX2[2]. This is also what the other implementation of _save_fp_context and _restore_fp_context in r4k_fpu.S does, and what is needed for the callers to be able to handle the error.
Furthermore calling do_exit(SIGSEGV) from bad_stack is wrong because it does not terminate the entire process it just terminates a single thread.
As the changed code was the only caller of arch/mips/kernel/syscall.c:bad_stack remove the problematic and now unused helper function.
Cc: Thomas Bogendoerfer tsbogend@alpha.franken.de Cc: Maciej Rozycki macro@orcam.me.uk Cc: linux-mips@vger.kernel.org [1] 35938a00ba86 ("MIPS: Fix ISA I FP sigcontext access violation handling") [2] f92722dc4545 ("MIPS: Correct MIPS I FP sigcontext layout") Cc: stable@vger.kernel.org Fixes: f92722dc4545 ("MIPS: Correct MIPS I FP sigcontext layout") Acked-by: Maciej W. Rozycki macro@orcam.me.uk Acked-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Link: https://lkml.kernel.org/r/20211020174406.17889-5-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/kernel/r2300_fpu.S | 4 ++-- arch/mips/kernel/syscall.c | 9 --------- 2 files changed, 2 insertions(+), 11 deletions(-)
--- a/arch/mips/kernel/r2300_fpu.S +++ b/arch/mips/kernel/r2300_fpu.S @@ -29,8 +29,8 @@ #define EX2(a,b) \ 9: a,##b; \ .section __ex_table,"a"; \ - PTR 9b,bad_stack; \ - PTR 9b+4,bad_stack; \ + PTR 9b,fault; \ + PTR 9b+4,fault; \ .previous
.set mips1 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -240,12 +240,3 @@ SYSCALL_DEFINE3(cachectl, char *, addr, { return -ENOSYS; } - -/* - * If we ever come here the user sp is bad. Zap the process right away. - * Due to the bad stack signaling wouldn't work. - */ -asmlinkage void bad_stack(void) -{ - do_exit(SIGSEGV); -}
From: Eric W. Biederman ebiederm@xmission.com
commit 00b06da29cf9dc633cdba87acd3f57f4df3fd5c7 upstream.
As Andy pointed out that there are races between force_sig_info_to_task and sigaction[1] when force_sig_info_task. As Kees discovered[2] ptrace is also able to change these signals.
In the case of seeccomp killing a process with a signal it is a security violation to allow the signal to be caught or manipulated.
Solve this problem by introducing a new flag SA_IMMUTABLE that prevents sigaction and ptrace from modifying these forced signals. This flag is carefully made kernel internal so that no new ABI is introduced.
Longer term I think this can be solved by guaranteeing short circuit delivery of signals in this case. Unfortunately reliable and guaranteed short circuit delivery of these signals is still a ways off from being implemented, tested, and merged. So I have implemented a much simpler alternative for now.
[1] https://lkml.kernel.org/r/b5d52d25-7bde-4030-a7b1-7c6f8ab90660@www.fastmail.... [2] https://lkml.kernel.org/r/202110281136.5CE65399A7@keescook Cc: stable@vger.kernel.org Fixes: 307d522f5eb8 ("signal/seccomp: Refactor seccomp signal and coredump generation") Tested-by: Andrea Righi andrea.righi@canonical.com Tested-by: Kees Cook keescook@chromium.org Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/signal_types.h | 3 +++ include/uapi/asm-generic/signal-defs.h | 1 + kernel/signal.c | 8 +++++++- 3 files changed, 11 insertions(+), 1 deletion(-)
--- a/include/linux/signal_types.h +++ b/include/linux/signal_types.h @@ -70,6 +70,9 @@ struct ksignal { int sig; };
+/* Used to kill the race between sigaction and forced signals */ +#define SA_IMMUTABLE 0x00800000 + #ifndef __ARCH_UAPI_SA_FLAGS #ifdef SA_RESTORER #define __ARCH_UAPI_SA_FLAGS SA_RESTORER --- a/include/uapi/asm-generic/signal-defs.h +++ b/include/uapi/asm-generic/signal-defs.h @@ -45,6 +45,7 @@ #define SA_UNSUPPORTED 0x00000400 #define SA_EXPOSE_TAGBITS 0x00000800 /* 0x00010000 used on mips */ +/* 0x00800000 used for internal SA_IMMUTABLE */ /* 0x01000000 used on x86 */ /* 0x02000000 used on x86 */ /* --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1323,6 +1323,7 @@ force_sig_info_to_task(struct kernel_sig blocked = sigismember(&t->blocked, sig); if (blocked || ignored || sigdfl) { action->sa.sa_handler = SIG_DFL; + action->sa.sa_flags |= SA_IMMUTABLE; if (blocked) { sigdelset(&t->blocked, sig); recalc_sigpending_and_wake(t); @@ -2729,7 +2730,8 @@ relock: if (!signr) break; /* will return 0 */
- if (unlikely(current->ptrace) && signr != SIGKILL) { + if (unlikely(current->ptrace) && (signr != SIGKILL) && + !(sighand->action[signr -1].sa.sa_flags & SA_IMMUTABLE)) { signr = ptrace_signal(signr, &ksig->info); if (!signr) continue; @@ -4079,6 +4081,10 @@ int do_sigaction(int sig, struct k_sigac k = &p->sighand->action[sig-1];
spin_lock_irq(&p->sighand->siglock); + if (k->sa.sa_flags & SA_IMMUTABLE) { + spin_unlock_irq(&p->sighand->siglock); + return -EINVAL; + } if (oact) *oact = *k;
From: David Virag virag.david003@gmail.com
commit e37ef6dcdb1f4738b01cec7fb7be46af07816af9 upstream.
Commit 93618e344a5e ("soc: samsung: exynos-pmu: instantiate clkout driver as MFD") adds a "devm_mfd_add_devices" call in the exynos-pmu driver which depends on CONFIG_MFD_CORE. If no driver selects that config, the build will fail if CONFIG_EXYNOS_PMU is enabled with the following error:
drivers/soc/samsung/exynos-pmu.c:137: undefined reference to `devm_mfd_add_devices'
Fix this by making CONFIG_EXYNOS_PMU select CONFIG_MFD_CORE.
Fixes: 93618e344a5e ("soc: samsung: exynos-pmu: instantiate clkout driver as MFD") Cc: stable@vger.kernel.org Signed-off-by: David Virag virag.david003@gmail.com Link: https://lore.kernel.org/r/20210909222812.108614-1-virag.david003@gmail.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/samsung/Kconfig | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/soc/samsung/Kconfig +++ b/drivers/soc/samsung/Kconfig @@ -25,6 +25,7 @@ config EXYNOS_PMU bool "Exynos PMU controller driver" if COMPILE_TEST depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST) select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS + select MFD_CORE
# There is no need to enable these drivers for ARMv8 config EXYNOS_PMU_ARM_DRIVERS
From: Meng Li Meng.Li@windriver.com
commit e775eb9fc2a4107f03222fa48bc95c2c82427e64 upstream.
When enable debug kernel configs,there will be calltrace as below:
BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1 caller is debug_smp_processor_id+0x20/0x30 CPU: 6 PID: 1 Comm: swapper/0 Not tainted 5.10.63-yocto-standard #1 Hardware name: NXP Layerscape LX2160ARDB (DT) Call trace: dump_backtrace+0x0/0x1a0 show_stack+0x24/0x30 dump_stack+0xf0/0x13c check_preemption_disabled+0x100/0x110 debug_smp_processor_id+0x20/0x30 dpaa2_io_query_fq_count+0xdc/0x154 dpaa2_eth_stop+0x144/0x314 __dev_close_many+0xdc/0x160 __dev_change_flags+0xe8/0x220 dev_change_flags+0x30/0x70 ic_close_devs+0x50/0x78 ip_auto_config+0xed0/0xf10 do_one_initcall+0xac/0x460 kernel_init_freeable+0x30c/0x378 kernel_init+0x20/0x128 ret_from_fork+0x10/0x38
Based on comment in the context, it doesn't matter whether preemption is disable or not. So, replace smp_processor_id() with raw_smp_processor_id() to avoid above call trace.
Fixes: c89105c9b390 ("staging: fsl-mc: Move DPIO from staging to drivers/soc/fsl") Cc: stable@vger.kernel.org Signed-off-by: Meng Li Meng.Li@windriver.com Signed-off-by: Li Yang leoyang.li@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/fsl/dpio/dpio-service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/soc/fsl/dpio/dpio-service.c +++ b/drivers/soc/fsl/dpio/dpio-service.c @@ -59,7 +59,7 @@ static inline struct dpaa2_io *service_s * potentially being migrated away. */ if (cpu < 0) - cpu = smp_processor_id(); + cpu = raw_smp_processor_id();
/* If a specific cpu was requested, pick it up immediately */ return dpio_by_cpu[cpu];
From: Meng Li Meng.Li@windriver.com
commit dc7e5940aad6641bd5ab33ea8b21c4b3904d989f upstream.
In orininal code, use 2 function spin_lock() and local_irq_save() to protect the critical zone. But when enable the kernel debug config, there are below inconsistent lock state detected. ================================ WARNING: inconsistent lock state 5.10.63-yocto-standard #1 Not tainted -------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. lock_torture_wr/226 [HC0[0]:SC1[5]:HE1:SE0] takes: ffff002005b2dd80 (&p->access_spinlock){+.?.}-{3:3}, at: qbman_swp_enqueue_multiple_mem_back+0x44/0x270 {SOFTIRQ-ON-W} state was registered at: lock_acquire.part.0+0xf8/0x250 lock_acquire+0x68/0x84 _raw_spin_lock+0x68/0x90 qbman_swp_enqueue_multiple_mem_back+0x44/0x270 ...... cryptomgr_test+0x38/0x60 kthread+0x158/0x164 ret_from_fork+0x10/0x38 irq event stamp: 4498 hardirqs last enabled at (4498): [<ffff800010fcf980>] _raw_spin_unlock_irqrestore+0x90/0xb0 hardirqs last disabled at (4497): [<ffff800010fcffc4>] _raw_spin_lock_irqsave+0xd4/0xe0 softirqs last enabled at (4458): [<ffff8000100108c4>] __do_softirq+0x674/0x724 softirqs last disabled at (4465): [<ffff80001005b2a4>] __irq_exit_rcu+0x190/0x19c
other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&p->access_spinlock); <Interrupt> lock(&p->access_spinlock); *** DEADLOCK ***
So, in order to avoid deadlock, use the combined functions spin_lock_irqsave/spin_unlock_irqrestore() to protect critical zone.
Fixes: 3b2abda7d28c ("soc: fsl: dpio: Replace QMAN array mode with ring mode enqueue") Cc: stable@vger.kernel.org Signed-off-by: Meng Li Meng.Li@windriver.com Signed-off-by: Li Yang leoyang.li@nxp.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/soc/fsl/dpio/qbman-portal.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
--- a/drivers/soc/fsl/dpio/qbman-portal.c +++ b/drivers/soc/fsl/dpio/qbman-portal.c @@ -732,8 +732,7 @@ int qbman_swp_enqueue_multiple_mem_back( int i, num_enqueued = 0; unsigned long irq_flags;
- spin_lock(&s->access_spinlock); - local_irq_save(irq_flags); + spin_lock_irqsave(&s->access_spinlock, irq_flags);
half_mask = (s->eqcr.pi_ci_mask>>1); full_mask = s->eqcr.pi_ci_mask; @@ -744,8 +743,7 @@ int qbman_swp_enqueue_multiple_mem_back( s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, eqcr_ci, s->eqcr.ci); if (!s->eqcr.available) { - local_irq_restore(irq_flags); - spin_unlock(&s->access_spinlock); + spin_unlock_irqrestore(&s->access_spinlock, irq_flags); return 0; } } @@ -784,8 +782,7 @@ int qbman_swp_enqueue_multiple_mem_back( dma_wmb(); qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI, (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); - local_irq_restore(irq_flags); - spin_unlock(&s->access_spinlock); + spin_unlock_irqrestore(&s->access_spinlock, irq_flags);
return num_enqueued; }
From: Miquel Raynal miquel.raynal@bootlin.com
commit b4ebddd6540d78a7f977b3fea0261bd575c6ffe2 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: b36bf0a0fe5d ("mtd: rawnand: socrates: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-9-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/socrates_nand.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/socrates_nand.c +++ b/drivers/mtd/nand/raw/socrates_nand.c @@ -119,9 +119,8 @@ static int socrates_nand_device_ready(st
static int socrates_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -175,6 +174,13 @@ static int socrates_nand_probe(struct pl /* TODO: I have no idea what real delay is. */ nand_chip->legacy.chip_delay = 20; /* 20us command delay time */
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + dev_set_drvdata(&ofdev->dev, host);
res = nand_scan(nand_chip, 1);
From: Eugene Syromiatnikov esyr@redhat.com
commit 1e4b50f06d970d8da3474d2a0354450416710bda upstream.
In order to have the padding fields actually usable in the future, there have to be checks that user space doesn't supply non-zero garbage there. It is also worth setting these padding fields to zero, unless it is known that they have been already zeroed.
Cc: stable@vger.kernel.org # v5.15 Fixes: 5a20dd46b8b84593 ("mctp: Be explicit about struct sockaddr_mctp padding") Signed-off-by: Eugene Syromiatnikov esyr@redhat.com Acked-by: Jeremy Kerr jk@codeconstruct.com.au Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mctp/af_mctp.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/net/mctp/af_mctp.c +++ b/net/mctp/af_mctp.c @@ -30,6 +30,12 @@ static int mctp_release(struct socket *s return 0; }
+/* Generic sockaddr checks, padding checks only so far */ +static bool mctp_sockaddr_is_ok(const struct sockaddr_mctp *addr) +{ + return !addr->__smctp_pad0 && !addr->__smctp_pad1; +} + static int mctp_bind(struct socket *sock, struct sockaddr *addr, int addrlen) { struct sock *sk = sock->sk; @@ -49,6 +55,9 @@ static int mctp_bind(struct socket *sock /* it's a valid sockaddr for MCTP, cast and do protocol checks */ smctp = (struct sockaddr_mctp *)addr;
+ if (!mctp_sockaddr_is_ok(smctp)) + return -EINVAL; + lock_sock(sk);
/* TODO: allow rebind */ @@ -83,6 +92,8 @@ static int mctp_sendmsg(struct socket *s return -EINVAL; if (addr->smctp_family != AF_MCTP) return -EINVAL; + if (!mctp_sockaddr_is_ok(addr)) + return -EINVAL; if (addr->smctp_tag & ~(MCTP_TAG_MASK | MCTP_TAG_OWNER)) return -EINVAL;
@@ -172,11 +183,13 @@ static int mctp_recvmsg(struct socket *s
addr = msg->msg_name; addr->smctp_family = AF_MCTP; + addr->__smctp_pad0 = 0; addr->smctp_network = cb->net; addr->smctp_addr.s_addr = hdr->src; addr->smctp_type = type; addr->smctp_tag = hdr->flags_seq_tag & (MCTP_HDR_TAG_MASK | MCTP_HDR_FLAG_TO); + addr->__smctp_pad1 = 0; msg->msg_namelen = sizeof(*addr); }
From: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm
commit e660dbb68c6b3f7b9eb8b9775846a44f9798b719 upstream.
max17042_set_soc_threshold gets called with offset set to 1, which means that minimum threshold value would underflow once SOC got down to 0, causing invalid alerts from the gauge.
Fixes: e5f3872d2044 ("max17042: Add support for signalling change in SOC") Cc: stable@vger.kernel.org Signed-off-by: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/power/supply/max17042_battery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -857,7 +857,8 @@ static void max17042_set_soc_threshold(s regmap_read(map, MAX17042_RepSOC, &soc); soc >>= 8; soc_tr = (soc + off) << 8; - soc_tr |= (soc - off); + if (off < soc) + soc_tr |= soc - off; regmap_write(map, MAX17042_SALRT_Th, soc_tr); }
From: Henrik Grimler henrik@grimler.se
commit 223a3b82834f036a62aa831f67cbf1f1d644c6e2 upstream.
On Galaxy S3 (i9300/i9305), which has the max17047 fuel gauge and no current sense resistor (rsns), the RepSOC register does not provide an accurate state of charge value. The reported value is wrong, and does not change over time. VFSOC however, which uses the voltage fuel gauge to determine the state of charge, always shows an accurate value.
For devices without current sense, VFSOC is already used for the soc-alert (0x0003 is written to MiscCFG register), so with this change the source of the alert and the PROP_CAPACITY value match.
Fixes: 359ab9f5b154 ("power_supply: Add MAX17042 Fuel Gauge Driver") Cc: stable@vger.kernel.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Suggested-by: Wolfgang Wiedmeyer wolfgit@wiedmeyer.de Signed-off-by: Henrik Grimler henrik@grimler.se Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/power/supply/max17042_battery.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -313,7 +313,10 @@ static int max17042_get_property(struct val->intval = data * 625 / 8; break; case POWER_SUPPLY_PROP_CAPACITY: - ret = regmap_read(map, MAX17042_RepSOC, &data); + if (chip->pdata->enable_current_sense) + ret = regmap_read(map, MAX17042_RepSOC, &data); + else + ret = regmap_read(map, MAX17042_VFSOC, &data); if (ret < 0) return ret;
From: Yang Yingliang yangyingliang@huawei.com
commit 19833c40d0415d6fe4340b5b9c46239abbf718f6 upstream.
I got the double free report:
BUG: KASAN: double-free or invalid-free in kfree+0xce/0x390 iio_device_unregister_sysfs+0x108/0x13b [industrialio] iio_dev_release+0x9e/0x10e [industrialio] device_release+0xa5/0x240
If __iio_device_register() fails, iio_dev_opaque->groups will be freed in error path in iio_device_unregister_sysfs(), then iio_dev_release() will call iio_device_unregister_sysfs() again, it causes double free. Set iio_dev_opaque->groups to NULL when it's freed to fix this double free.
Not this is a local work around for a more general mess around life time management that will get cleaned up and should make this handling unnecesarry.
Fixes: 32f171724e5c ("iio: core: rework iio device group creation") Reported-by: Hulk Robot hulkci@huawei.com Reviewed-by: Alexandru Ardelean ardeleanalex@gmail.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211013030532.956133-1-yangyingliang@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-core.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1600,6 +1600,7 @@ static void iio_device_unregister_sysfs( kfree(iio_dev_opaque->chan_attr_group.attrs); iio_dev_opaque->chan_attr_group.attrs = NULL; kfree(iio_dev_opaque->groups); + iio_dev_opaque->groups = NULL; }
static void iio_dev_release(struct device *device)
From: Yang Yingliang yangyingliang@huawei.com
commit fe6f45f6ba22d625a8500cbad0237c60dd3117ee upstream.
I got a null-ptr-deref report when doing fault injection test:
BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:strlen+0x0/0x20 Call Trace: start_creating+0x199/0x2f0 debugfs_create_dir+0x25/0x430 __iio_device_register+0x4da/0x1b40 [industrialio] __devm_iio_device_register+0x22/0x80 [industrialio] max1027_probe+0x639/0x860 [max1027] spi_probe+0x183/0x210 really_probe+0x285/0xc30
If dev_set_name() fails, the dev_name() is null, check the return value of dev_set_name() to avoid the null-ptr-deref.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: e553f182d55b ("staging: iio: core: Introduce debugfs support...") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Cc: Stable@vger.kernel.org Link: https://lore.kernel.org/r/20211012063624.3167460-1-yangyingliang@huawei.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1665,7 +1665,13 @@ struct iio_dev *iio_device_alloc(struct kfree(iio_dev_opaque); return NULL; } - dev_set_name(&indio_dev->dev, "iio:device%d", iio_dev_opaque->id); + + if (dev_set_name(&indio_dev->dev, "iio:device%d", iio_dev_opaque->id)) { + ida_simple_remove(&iio_ida, iio_dev_opaque->id); + kfree(iio_dev_opaque); + return NULL; + } + INIT_LIST_HEAD(&iio_dev_opaque->buffer_list); INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers);
From: Mark Rutland mark.rutland@arm.com
commit 8bb084119f1acc2ec55ea085a97231e3ddb30782 upstream.
Since ARMv8.0 the upper 32 bits of ESR_ELx have been RES0, and recently some of the upper bits gained a meaning and can be non-zero. For example, when FEAT_LS64 is implemented, ESR_ELx[36:32] contain ISS2, which for an ST64BV or ST64BV0 can be non-zero. This can be seen in ARM DDI 0487G.b, page D13-3145, section D13.2.37.
Generally, we must not rely on RES0 bit remaining zero in future, and when extracting ESR_ELx.EC we must mask out all other bits.
All C code uses the ESR_ELx_EC() macro, which masks out the irrelevant bits, and therefore no alterations are required to C code to avoid consuming irrelevant bits.
In a couple of places the KVM assembly extracts ESR_ELx.EC using LSR on an X register, and so could in theory consume previously RES0 bits. In both cases this is for comparison with EC values ESR_ELx_EC_HVC32 and ESR_ELx_EC_HVC64, for which the upper bits of ESR_ELx must currently be zero, but this could change in future.
This patch adjusts the KVM vectors to use UBFX rather than LSR to extract ESR_ELx.EC, ensuring these are robust to future additions to ESR_ELx.
Cc: stable@vger.kernel.org Signed-off-by: Mark Rutland mark.rutland@arm.com Cc: Alexandru Elisei alexandru.elisei@arm.com Cc: Catalin Marinas catalin.marinas@arm.com Cc: James Morse james.morse@arm.com Cc: Marc Zyngier maz@kernel.org Cc: Suzuki K Poulose suzuki.poulose@arm.com Cc: Will Deacon will@kernel.org Acked-by: Will Deacon will@kernel.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211103110545.4613-1-mark.rutland@arm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm64/include/asm/esr.h | 1 + arch/arm64/kvm/hyp/hyp-entry.S | 2 +- arch/arm64/kvm/hyp/nvhe/host.S | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-)
--- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -68,6 +68,7 @@ #define ESR_ELx_EC_MAX (0x3F)
#define ESR_ELx_EC_SHIFT (26) +#define ESR_ELx_EC_WIDTH (6) #define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) #define ESR_ELx_EC(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT)
--- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -44,7 +44,7 @@ el1_sync: // Guest trapped into EL2
mrs x0, esr_el2 - lsr x0, x0, #ESR_ELx_EC_SHIFT + ubfx x0, x0, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH cmp x0, #ESR_ELx_EC_HVC64 ccmp x0, #ESR_ELx_EC_HVC32, #4, ne b.ne el1_trap --- a/arch/arm64/kvm/hyp/nvhe/host.S +++ b/arch/arm64/kvm/hyp/nvhe/host.S @@ -115,7 +115,7 @@ SYM_FUNC_END(__hyp_do_panic) .L__vect_start@: stp x0, x1, [sp, #-16]! mrs x0, esr_el2 - lsr x0, x0, #ESR_ELx_EC_SHIFT + ubfx x0, x0, #ESR_ELx_EC_SHIFT, #ESR_ELx_EC_WIDTH cmp x0, #ESR_ELx_EC_HVC64 b.ne __host_exit
From: David Woodhouse dwmw2@infradead.org
commit 7e2175ebd695f17860c5bd4ad7616cce12ed4591 upstream.
In commit b043138246a4 ("x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed") we switched to using a gfn_to_pfn_cache for accessing the guest steal time structure in order to allow for an atomic xchg of the preempted field. This has a couple of problems.
Firstly, kvm_map_gfn() doesn't work at all for IOMEM pages when the atomic flag is set, which it is in kvm_steal_time_set_preempted(). So a guest vCPU using an IOMEM page for its steal time would never have its preempted field set.
Secondly, the gfn_to_pfn_cache is not invalidated in all cases where it should have been. There are two stages to the GFN->PFN conversion; first the GFN is converted to a userspace HVA, and then that HVA is looked up in the process page tables to find the underlying host PFN. Correct invalidation of the latter would require being hooked up to the MMU notifiers, but that doesn't happen---so it just keeps mapping and unmapping the *wrong* PFN after the userspace page tables change.
In the !IOMEM case at least the stale page *is* pinned all the time it's cached, so it won't be freed and reused by anyone else while still receiving the steal time updates. The map/unmap dance only takes care of the KVM administrivia such as marking the page dirty.
Until the gfn_to_pfn cache handles the remapping automatically by integrating with the MMU notifiers, we might as well not get a kernel mapping of it, and use the perfectly serviceable userspace HVA that we already have. We just need to implement the atomic xchg on the userspace address with appropriate exception handling, which is fairly trivial.
Cc: stable@vger.kernel.org Fixes: b043138246a4 ("x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed") Signed-off-by: David Woodhouse dwmw@amazon.co.uk Message-Id: 3645b9b889dac6438394194bb5586a46b68d581f.camel@infradead.org [I didn't entirely agree with David's assessment of the usefulness of the gfn_to_pfn cache, and integrated the outcome of the discussion in the above commit message. - Paolo] Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/kvm_host.h | 2 arch/x86/kvm/x86.c | 105 ++++++++++++++++++++++++++++------------ 2 files changed, 76 insertions(+), 31 deletions(-)
--- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -751,7 +751,7 @@ struct kvm_vcpu_arch { u8 preempted; u64 msr_val; u64 last_steal; - struct gfn_to_pfn_cache cache; + struct gfn_to_hva_cache cache; } st;
u64 l1_tsc_offset; --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3195,8 +3195,11 @@ static void kvm_vcpu_flush_tlb_guest(str
static void record_steal_time(struct kvm_vcpu *vcpu) { - struct kvm_host_map map; - struct kvm_steal_time *st; + struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; + struct kvm_steal_time __user *st; + struct kvm_memslots *slots; + u64 steal; + u32 version;
if (kvm_xen_msr_enabled(vcpu->kvm)) { kvm_xen_runstate_set_running(vcpu); @@ -3206,47 +3209,83 @@ static void record_steal_time(struct kvm if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return;
- /* -EAGAIN is returned in atomic context so we can just return. */ - if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, - &map, &vcpu->arch.st.cache, false)) + if (WARN_ON_ONCE(current->mm != vcpu->kvm->mm)) return;
- st = map.hva + - offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); + slots = kvm_memslots(vcpu->kvm); + + if (unlikely(slots->generation != ghc->generation || + kvm_is_error_hva(ghc->hva) || !ghc->memslot)) { + gfn_t gfn = vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS; + + /* We rely on the fact that it fits in a single page. */ + BUILD_BUG_ON((sizeof(*st) - 1) & KVM_STEAL_VALID_BITS); + + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gfn, sizeof(*st)) || + kvm_is_error_hva(ghc->hva) || !ghc->memslot) + return; + } + + st = (struct kvm_steal_time __user *)ghc->hva; + if (!user_access_begin(st, sizeof(*st))) + return;
/* * Doing a TLB flush here, on the guest's behalf, can avoid * expensive IPIs. */ if (guest_pv_has(vcpu, KVM_FEATURE_PV_TLB_FLUSH)) { - u8 st_preempted = xchg(&st->preempted, 0); + u8 st_preempted = 0; + int err = -EFAULT; + + asm volatile("1: xchgb %0, %2\n" + "xor %1, %1\n" + "2:\n" + _ASM_EXTABLE_UA(1b, 2b) + : "+r" (st_preempted), + "+&r" (err) + : "m" (st->preempted)); + if (err) + goto out; + + user_access_end(); + + vcpu->arch.st.preempted = 0;
trace_kvm_pv_tlb_flush(vcpu->vcpu_id, st_preempted & KVM_VCPU_FLUSH_TLB); if (st_preempted & KVM_VCPU_FLUSH_TLB) kvm_vcpu_flush_tlb_guest(vcpu); + + if (!user_access_begin(st, sizeof(*st))) + goto dirty; } else { - st->preempted = 0; + unsafe_put_user(0, &st->preempted, out); + vcpu->arch.st.preempted = 0; }
- vcpu->arch.st.preempted = 0; - - if (st->version & 1) - st->version += 1; /* first time write, random junk */ + unsafe_get_user(version, &st->version, out); + if (version & 1) + version += 1; /* first time write, random junk */
- st->version += 1; + version += 1; + unsafe_put_user(version, &st->version, out);
smp_wmb();
- st->steal += current->sched_info.run_delay - + unsafe_get_user(steal, &st->steal, out); + steal += current->sched_info.run_delay - vcpu->arch.st.last_steal; vcpu->arch.st.last_steal = current->sched_info.run_delay; + unsafe_put_user(steal, &st->steal, out);
- smp_wmb(); - - st->version += 1; + version += 1; + unsafe_put_user(version, &st->version, out);
- kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, false); + out: + user_access_end(); + dirty: + mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa)); }
int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) @@ -4285,8 +4324,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) { - struct kvm_host_map map; - struct kvm_steal_time *st; + struct gfn_to_hva_cache *ghc = &vcpu->arch.st.cache; + struct kvm_steal_time __user *st; + struct kvm_memslots *slots; + static const u8 preempted = KVM_VCPU_PREEMPTED;
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) return; @@ -4294,16 +4335,23 @@ static void kvm_steal_time_set_preempted if (vcpu->arch.st.preempted) return;
- if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, &map, - &vcpu->arch.st.cache, true)) + /* This happens on process exit */ + if (unlikely(current->mm != vcpu->kvm->mm)) return;
- st = map.hva + - offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS); + slots = kvm_memslots(vcpu->kvm); + + if (unlikely(slots->generation != ghc->generation || + kvm_is_error_hva(ghc->hva) || !ghc->memslot)) + return;
- st->preempted = vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; + st = (struct kvm_steal_time __user *)ghc->hva; + BUILD_BUG_ON(sizeof(st->preempted) != sizeof(preempted));
- kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, true); + if (!copy_to_user_nofault(&st->preempted, &preempted, sizeof(preempted))) + vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED; + + mark_page_dirty_in_slot(vcpu->kvm, ghc->memslot, gpa_to_gfn(ghc->gpa)); }
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) @@ -10817,11 +10865,8 @@ void kvm_arch_vcpu_postcreate(struct kvm
void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) { - struct gfn_to_pfn_cache *cache = &vcpu->arch.st.cache; int idx;
- kvm_release_pfn(cache->pfn, cache->dirty, cache); - kvmclock_reset(vcpu);
static_call(kvm_x86_vcpu_free)(vcpu);
From: Sean Christopherson seanjc@google.com
commit 8b44b174f6aca815fc84c2038e4523ef8e32fabb upstream.
Move the core logic of SET_CPUID and SET_CPUID2 to a common helper, the only difference between the two ioctls() is the format of the userspace struct. A future fix will add yet more code to the core logic.
No functional change intended.
Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211105095101.5384-2-pdurrant@amazon.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/cpuid.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-)
--- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -232,6 +232,25 @@ u64 kvm_vcpu_reserved_gpa_bits_raw(struc return rsvd_bits(cpuid_maxphyaddr(vcpu), 63); }
+static int kvm_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid_entry2 *e2, + int nent) +{ + int r; + + r = kvm_check_cpuid(e2, nent); + if (r) + return r; + + kvfree(vcpu->arch.cpuid_entries); + vcpu->arch.cpuid_entries = e2; + vcpu->arch.cpuid_nent = nent; + + kvm_update_cpuid_runtime(vcpu); + kvm_vcpu_after_set_cpuid(vcpu); + + return 0; +} + /* when an old userspace process fills a new kernel module */ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid *cpuid, @@ -268,18 +287,9 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_ e2[i].padding[2] = 0; }
- r = kvm_check_cpuid(e2, cpuid->nent); - if (r) { + r = kvm_set_cpuid(vcpu, e2, cpuid->nent); + if (r) kvfree(e2); - goto out_free_cpuid; - } - - kvfree(vcpu->arch.cpuid_entries); - vcpu->arch.cpuid_entries = e2; - vcpu->arch.cpuid_nent = cpuid->nent; - - kvm_update_cpuid_runtime(vcpu); - kvm_vcpu_after_set_cpuid(vcpu);
out_free_cpuid: kvfree(e); @@ -303,20 +313,11 @@ int kvm_vcpu_ioctl_set_cpuid2(struct kvm return PTR_ERR(e2); }
- r = kvm_check_cpuid(e2, cpuid->nent); - if (r) { + r = kvm_set_cpuid(vcpu, e2, cpuid->nent); + if (r) kvfree(e2); - return r; - }
- kvfree(vcpu->arch.cpuid_entries); - vcpu->arch.cpuid_entries = e2; - vcpu->arch.cpuid_nent = cpuid->nent; - - kvm_update_cpuid_runtime(vcpu); - kvm_vcpu_after_set_cpuid(vcpu); - - return 0; + return r; }
int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
From: Sean Christopherson seanjc@google.com
commit 7dfbc624eb5726367900c8d86deff50836240361 upstream.
Check the current VMCS controls to determine if an MSR write will be intercepted due to MSR bitmaps being disabled. In the nested VMX case, KVM will disable MSR bitmaps in vmcs02 if they're disabled in vmcs12 or if KVM can't map L1's bitmaps for whatever reason.
Note, the bad behavior is relatively benign in the current code base as KVM sets all bits in vmcs02's MSR bitmap by default, clears bits if and only if L0 KVM also disables interception of an MSR, and only uses the buggy helper for MSR_IA32_SPEC_CTRL. Because KVM explicitly tests WRMSR before disabling interception of MSR_IA32_SPEC_CTRL, the flawed check will only result in KVM reading MSR_IA32_SPEC_CTRL from hardware when it isn't strictly necessary.
Tag the fix for stable in case a future fix wants to use msr_write_intercepted(), in which case a buggy implementation in older kernels could prove subtly problematic.
Fixes: d28b387fb74d ("KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211109013047.2041518-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/vmx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -769,15 +769,15 @@ void vmx_update_exception_bitmap(struct /* * Check if MSR is intercepted for currently loaded MSR bitmap. */ -static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr) +static bool msr_write_intercepted(struct vcpu_vmx *vmx, u32 msr) { unsigned long *msr_bitmap; int f = sizeof(unsigned long);
- if (!cpu_has_vmx_msr_bitmap()) + if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS)) return true;
- msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap; + msr_bitmap = vmx->loaded_vmcs->msr_bitmap;
if (msr <= 0x1fff) { return !!test_bit(msr, msr_bitmap + 0x800 / f); @@ -6720,7 +6720,7 @@ static fastpath_t vmx_vcpu_run(struct kv * If the L02 MSR bitmap does not intercept the MSR, then we need to * save it. */ - if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) + if (unlikely(!msr_write_intercepted(vmx, MSR_IA32_SPEC_CTRL))) vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0);
From: Sean Christopherson seanjc@google.com
commit 67f4b9969c305be515e47f809ecacfd86bd20a9c upstream.
Always check vmcs01's MSR bitmap when merging L0 and L1 bitmaps for L2, and always update the relevant bits in vmcs02. This fixes two distinct, but intertwined bugs related to dynamic MSR bitmap modifications.
The first issue is that KVM fails to enable MSR interception in vmcs02 for the FS/GS base MSRs if L1 first runs L2 with interception disabled, and later enables interception.
The second issue is that KVM fails to honor userspace MSR filtering when preparing vmcs02.
Fix both issues simultaneous as fixing only one of the issues (doesn't matter which) would create a mess that no one should have to bisect. Fixing only the first bug would exacerbate the MSR filtering issue as userspace would see inconsistent behavior depending on the whims of L1. Fixing only the second bug (MSR filtering) effectively requires fixing the first, as the nVMX code only knows how to transition vmcs02's bitmap from 1->0.
Move the various accessor/mutators that are currently buried in vmx.c into vmx.h so that they can be shared by the nested code.
Fixes: 1a155254ff93 ("KVM: x86: Introduce MSR filtering") Fixes: d69129b4e46a ("KVM: nVMX: Disable intercept for FS/GS base MSRs in vmcs02 when possible") Cc: stable@vger.kernel.org Cc: Alexander Graf graf@amazon.com Signed-off-by: Sean Christopherson seanjc@google.com Message-Id: 20211109013047.2041518-3-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/vmx/nested.c | 103 ++++++++++++++++++++-------------------------- arch/x86/kvm/vmx/vmx.c | 55 ------------------------ arch/x86/kvm/vmx/vmx.h | 63 ++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 110 deletions(-)
--- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -524,29 +524,6 @@ static int nested_vmx_check_tpr_shadow_c }
/* - * Check if MSR is intercepted for L01 MSR bitmap. - */ -static bool msr_write_intercepted_l01(struct kvm_vcpu *vcpu, u32 msr) -{ - unsigned long *msr_bitmap; - int f = sizeof(unsigned long); - - if (!cpu_has_vmx_msr_bitmap()) - return true; - - msr_bitmap = to_vmx(vcpu)->vmcs01.msr_bitmap; - - if (msr <= 0x1fff) { - return !!test_bit(msr, msr_bitmap + 0x800 / f); - } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { - msr &= 0x1fff; - return !!test_bit(msr, msr_bitmap + 0xc00 / f); - } - - return true; -} - -/* * If a msr is allowed by L0, we should check whether it is allowed by L1. * The corresponding bit will be cleared unless both of L0 and L1 allow it. */ @@ -599,6 +576,34 @@ static inline void enable_x2apic_msr_int } }
+#define BUILD_NVMX_MSR_INTERCEPT_HELPER(rw) \ +static inline \ +void nested_vmx_set_msr_##rw##_intercept(struct vcpu_vmx *vmx, \ + unsigned long *msr_bitmap_l1, \ + unsigned long *msr_bitmap_l0, u32 msr) \ +{ \ + if (vmx_test_msr_bitmap_##rw(vmx->vmcs01.msr_bitmap, msr) || \ + vmx_test_msr_bitmap_##rw(msr_bitmap_l1, msr)) \ + vmx_set_msr_bitmap_##rw(msr_bitmap_l0, msr); \ + else \ + vmx_clear_msr_bitmap_##rw(msr_bitmap_l0, msr); \ +} +BUILD_NVMX_MSR_INTERCEPT_HELPER(read) +BUILD_NVMX_MSR_INTERCEPT_HELPER(write) + +static inline void nested_vmx_set_intercept_for_msr(struct vcpu_vmx *vmx, + unsigned long *msr_bitmap_l1, + unsigned long *msr_bitmap_l0, + u32 msr, int types) +{ + if (types & MSR_TYPE_R) + nested_vmx_set_msr_read_intercept(vmx, msr_bitmap_l1, + msr_bitmap_l0, msr); + if (types & MSR_TYPE_W) + nested_vmx_set_msr_write_intercept(vmx, msr_bitmap_l1, + msr_bitmap_l0, msr); +} + /* * Merge L0's and L1's MSR bitmap, return false to indicate that * we do not use the hardware. @@ -606,10 +611,11 @@ static inline void enable_x2apic_msr_int static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) { + struct vcpu_vmx *vmx = to_vmx(vcpu); int msr; unsigned long *msr_bitmap_l1; - unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap; - struct kvm_host_map *map = &to_vmx(vcpu)->nested.msr_bitmap_map; + unsigned long *msr_bitmap_l0 = vmx->nested.vmcs02.msr_bitmap; + struct kvm_host_map *map = &vmx->nested.msr_bitmap_map;
/* Nothing to do if the MSR bitmap is not in use. */ if (!cpu_has_vmx_msr_bitmap() || @@ -660,44 +666,27 @@ static inline bool nested_vmx_prepare_ms } }
- /* KVM unconditionally exposes the FS/GS base MSRs to L1. */ + /* + * Always check vmcs01's bitmap to honor userspace MSR filters and any + * other runtime changes to vmcs01's bitmap, e.g. dynamic pass-through. + */ #ifdef CONFIG_X86_64 - nested_vmx_disable_intercept_for_msr(msr_bitmap_l1, msr_bitmap_l0, - MSR_FS_BASE, MSR_TYPE_RW); + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_FS_BASE, MSR_TYPE_RW);
- nested_vmx_disable_intercept_for_msr(msr_bitmap_l1, msr_bitmap_l0, - MSR_GS_BASE, MSR_TYPE_RW); + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_GS_BASE, MSR_TYPE_RW);
- nested_vmx_disable_intercept_for_msr(msr_bitmap_l1, msr_bitmap_l0, - MSR_KERNEL_GS_BASE, MSR_TYPE_RW); + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_KERNEL_GS_BASE, MSR_TYPE_RW); #endif + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_SPEC_CTRL, MSR_TYPE_RW);
- /* - * Checking the L0->L1 bitmap is trying to verify two things: - * - * 1. L0 gave a permission to L1 to actually passthrough the MSR. This - * ensures that we do not accidentally generate an L02 MSR bitmap - * from the L12 MSR bitmap that is too permissive. - * 2. That L1 or L2s have actually used the MSR. This avoids - * unnecessarily merging of the bitmap if the MSR is unused. This - * works properly because we only update the L01 MSR bitmap lazily. - * So even if L0 should pass L1 these MSRs, the L01 bitmap is only - * updated to reflect this when L1 (or its L2s) actually write to - * the MSR. - */ - if (!msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL)) - nested_vmx_disable_intercept_for_msr( - msr_bitmap_l1, msr_bitmap_l0, - MSR_IA32_SPEC_CTRL, - MSR_TYPE_R | MSR_TYPE_W); - - if (!msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD)) - nested_vmx_disable_intercept_for_msr( - msr_bitmap_l1, msr_bitmap_l0, - MSR_IA32_PRED_CMD, - MSR_TYPE_W); + nested_vmx_set_intercept_for_msr(vmx, msr_bitmap_l1, msr_bitmap_l0, + MSR_IA32_PRED_CMD, MSR_TYPE_W);
- kvm_vcpu_unmap(vcpu, &to_vmx(vcpu)->nested.msr_bitmap_map, false); + kvm_vcpu_unmap(vcpu, &vmx->nested.msr_bitmap_map, false);
return true; } --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -771,22 +771,11 @@ void vmx_update_exception_bitmap(struct */ static bool msr_write_intercepted(struct vcpu_vmx *vmx, u32 msr) { - unsigned long *msr_bitmap; - int f = sizeof(unsigned long); - if (!(exec_controls_get(vmx) & CPU_BASED_USE_MSR_BITMAPS)) return true;
- msr_bitmap = vmx->loaded_vmcs->msr_bitmap; - - if (msr <= 0x1fff) { - return !!test_bit(msr, msr_bitmap + 0x800 / f); - } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { - msr &= 0x1fff; - return !!test_bit(msr, msr_bitmap + 0xc00 / f); - } - - return true; + return vmx_test_msr_bitmap_write(vmx->loaded_vmcs->msr_bitmap, + MSR_IA32_SPEC_CTRL); }
static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx, @@ -3695,46 +3684,6 @@ void free_vpid(int vpid) spin_unlock(&vmx_vpid_lock); }
-static void vmx_clear_msr_bitmap_read(ulong *msr_bitmap, u32 msr) -{ - int f = sizeof(unsigned long); - - if (msr <= 0x1fff) - __clear_bit(msr, msr_bitmap + 0x000 / f); - else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) - __clear_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); -} - -static void vmx_clear_msr_bitmap_write(ulong *msr_bitmap, u32 msr) -{ - int f = sizeof(unsigned long); - - if (msr <= 0x1fff) - __clear_bit(msr, msr_bitmap + 0x800 / f); - else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) - __clear_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); -} - -static void vmx_set_msr_bitmap_read(ulong *msr_bitmap, u32 msr) -{ - int f = sizeof(unsigned long); - - if (msr <= 0x1fff) - __set_bit(msr, msr_bitmap + 0x000 / f); - else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) - __set_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); -} - -static void vmx_set_msr_bitmap_write(ulong *msr_bitmap, u32 msr) -{ - int f = sizeof(unsigned long); - - if (msr <= 0x1fff) - __set_bit(msr, msr_bitmap + 0x800 / f); - else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) - __set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); -} - void vmx_disable_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr, int type) { struct vcpu_vmx *vmx = to_vmx(vcpu); --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -400,6 +400,69 @@ static inline void vmx_set_intercept_for
void vmx_update_cpu_dirty_logging(struct kvm_vcpu *vcpu);
+static inline bool vmx_test_msr_bitmap_read(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + return test_bit(msr, msr_bitmap + 0x000 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + return test_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); + return true; +} + +static inline bool vmx_test_msr_bitmap_write(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + return test_bit(msr, msr_bitmap + 0x800 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + return test_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); + return true; +} + +static inline void vmx_clear_msr_bitmap_read(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __clear_bit(msr, msr_bitmap + 0x000 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __clear_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); +} + +static inline void vmx_clear_msr_bitmap_write(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __clear_bit(msr, msr_bitmap + 0x800 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __clear_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); +} + +static inline void vmx_set_msr_bitmap_read(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __set_bit(msr, msr_bitmap + 0x000 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __set_bit(msr & 0x1fff, msr_bitmap + 0x400 / f); +} + +static inline void vmx_set_msr_bitmap_write(ulong *msr_bitmap, u32 msr) +{ + int f = sizeof(unsigned long); + + if (msr <= 0x1fff) + __set_bit(msr, msr_bitmap + 0x800 / f); + else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) + __set_bit(msr & 0x1fff, msr_bitmap + 0xc00 / f); +} + + static inline u8 vmx_get_rvi(void) { return vmcs_read16(GUEST_INTR_STATUS) & 0xff;
From: Stephane Grosjean s.grosjean@peak-system.com
commit 3f1c7aa28498e52a5e6aa2f1b89bf35c63352cfd upstream.
Since for the PCAN-USB, the management of the transition to the ERROR_WARNING or ERROR_PASSIVE state is done according to the error counters, these must be requested unconditionally.
Link: https://lore.kernel.org/all/20211021081505.18223-2-s.grosjean@peak-system.co... Fixes: c11dcee75830 ("can: peak_usb: pcan_usb_decode_error(): upgrade handling of bus state changes") Cc: stable@vger.kernel.org Signed-off-by: Stephane Grosjean s.grosjean@peak-system.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/usb/peak_usb/pcan_usb.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -841,14 +841,14 @@ static int pcan_usb_start(struct peak_us pdev->bec.rxerr = 0; pdev->bec.txerr = 0;
- /* be notified on error counter changes (if requested by user) */ - if (dev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) { - err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK); - if (err) - netdev_warn(dev->netdev, - "Asking for BERR reporting error %u\n", - err); - } + /* always ask the device for BERR reporting, to be able to switch from + * WARNING to PASSIVE state + */ + err = pcan_usb_set_err_frame(dev, PCAN_USB_BERR_MASK); + if (err) + netdev_warn(dev->netdev, + "Asking for BERR reporting error %u\n", + err);
/* if revision greater than 3, can put silent mode on/off */ if (dev->device_rev > 3) { @@ -986,7 +986,6 @@ const struct peak_usb_adapter pcan_usb = .device_id = PCAN_USB_PRODUCT_ID, .ctrl_count = 1, .ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY | - CAN_CTRLMODE_BERR_REPORTING | CAN_CTRLMODE_CC_LEN8_DLC, .clock = { .freq = PCAN_USB_CRYSTAL_HZ / 2,
From: Marc Kleine-Budde mkl@pengutronix.de
commit 691204bd66b34ba982e19988e6eba9f6321dfe6c upstream.
The function can_rx_offload_threaded_irq_finish() is needed to trigger the NAPI thread to deliver read CAN frames to the networking stack.
This patch adds the missing call to can_rx_offload_threaded_irq_finish() in case of a bus off, before leaving the interrupt handler to avoid packet starvation.
Link: https://lore.kernel.org/all/20211106201526.44292-1-mkl@pengutronix.de Fixes: 30bfec4fec59 ("can: rx-offload: can_rx_offload_threaded_irq_finish(): add new function to be called from threaded interrupt") Cc: stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -2290,8 +2290,10 @@ static irqreturn_t mcp251xfd_irq(int irq * check will fail, too. So leave IRQ handler * directly. */ - if (priv->can.state == CAN_STATE_BUS_OFF) + if (priv->can.state == CAN_STATE_BUS_OFF) { + can_rx_offload_threaded_irq_finish(&priv->offload); return IRQ_HANDLED; + } }
handled = IRQ_HANDLED;
From: Zhang Changzhong zhangchangzhong@huawei.com
commit c0f49d98006f2db3333b917caac65bce2af9865c upstream.
This patch prevents BAM transport from being closed by receiving abort message, as specified in SAE-J1939-82 2015 (A.3.3 Row 4).
Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") Link: https://lore.kernel.org/all/1635431907-15617-2-git-send-email-zhangchangzhon... Cc: stable@vger.kernel.org Signed-off-by: Zhang Changzhong zhangchangzhong@huawei.com Acked-by: Oleksij Rempel o.rempel@pengutronix.de Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/can/j1939/transport.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -2085,6 +2085,12 @@ static void j1939_tp_cmd_recv(struct j19 break;
case J1939_ETP_CMD_ABORT: /* && J1939_TP_CMD_ABORT */ + if (j1939_cb_is_broadcast(skcb)) { + netdev_err_once(priv->ndev, "%s: abort to broadcast (%02x), ignoring!\n", + __func__, skcb->addr.sa); + return; + } + if (j1939_tp_im_transmitter(skcb)) j1939_xtp_rx_abort(priv, skb, true);
From: Zhang Changzhong zhangchangzhong@huawei.com
commit a79305e156db3d24fcd8eb649cdb3c3b2350e5c2 upstream.
According to SAE-J1939-82 2015 (A.3.6 Row 2), a receiver should never send TP.CM_CTS to the global address, so we can add a check in j1939_can_recv() to drop messages with invalid source address.
Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") Link: https://lore.kernel.org/all/1635431907-15617-3-git-send-email-zhangchangzhon... Cc: stable@vger.kernel.org Signed-off-by: Zhang Changzhong zhangchangzhong@huawei.com Acked-by: Oleksij Rempel o.rempel@pengutronix.de Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/can/j1939/main.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/net/can/j1939/main.c +++ b/net/can/j1939/main.c @@ -75,6 +75,13 @@ static void j1939_can_recv(struct sk_buf skcb->addr.pgn = (cf->can_id >> 8) & J1939_PGN_MAX; /* set default message type */ skcb->addr.type = J1939_TP; + + if (!j1939_address_is_valid(skcb->addr.sa)) { + netdev_err_once(priv->ndev, "%s: sa is broadcast address, ignoring!\n", + __func__); + goto done; + } + if (j1939_pgn_is_pdu1(skcb->addr.pgn)) { /* Type 1: with destination address */ skcb->addr.da = skcb->addr.pgn;
From: Zhang Changzhong zhangchangzhong@huawei.com
commit 164051a6ab5445bd97f719f50b16db8b32174269 upstream.
The TP.CM_BAM message must be sent to the global address [1], so add a check to drop TP.CM_BAM sent to a non-global address.
Without this patch, the receiver will treat the following packets as normal RTS/CTS transport: 18EC0102#20090002FF002301 18EB0102#0100000000000000 18EB0102#020000FFFFFFFFFF
[1] SAE-J1939-82 2015 A.3.3 Row 1.
Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") Link: https://lore.kernel.org/all/1635431907-15617-4-git-send-email-zhangchangzhon... Cc: stable@vger.kernel.org Signed-off-by: Zhang Changzhong zhangchangzhong@huawei.com Acked-by: Oleksij Rempel o.rempel@pengutronix.de Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/can/j1939/transport.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -2023,6 +2023,11 @@ static void j1939_tp_cmd_recv(struct j19 extd = J1939_ETP; fallthrough; case J1939_TP_CMD_BAM: + if (cmd == J1939_TP_CMD_BAM && !j1939_cb_is_broadcast(skcb)) { + netdev_err_once(priv->ndev, "%s: BAM to unicast (%02x), ignoring!\n", + __func__, skcb->addr.sa); + return; + } fallthrough; case J1939_TP_CMD_RTS: if (skcb->addr.type != extd)
From: Oleksij Rempel o.rempel@pengutronix.de
commit 69b31fd7a61784692db6433c05d46915b1b1a680 upstream.
Sync if statement with the actual warning.
Fixes: 9504db5765e8 ("iio: adc: tsc2046: fix a warning message in tsc2046_adc_update_scan_mode()") Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de Link: https://lore.kernel.org/r/20211007093007.1466-2-o.rempel@pengutronix.de Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/adc/ti-tsc2046.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/adc/ti-tsc2046.c +++ b/drivers/iio/adc/ti-tsc2046.c @@ -398,7 +398,7 @@ static int tsc2046_adc_update_scan_mode( priv->xfer.len = size; priv->time_per_scan_us = size * 8 * priv->time_per_bit_ns / NSEC_PER_USEC;
- if (priv->scan_interval_us > priv->time_per_scan_us) + if (priv->scan_interval_us < priv->time_per_scan_us) dev_warn(&priv->spi->dev, "The scan interval (%d) is less then calculated scan time (%d)\n", priv->scan_interval_us, priv->time_per_scan_us);
From: Xiaoming Ni nixiaoming@huawei.com
commit 3c2172c1c47b4079c29f0e6637d764a99355ebcd upstream.
When the field described in mpc85xx_smp_guts_ids[] is not configured in dtb, the mpc85xx_setup_pmc() does not assign a value to the "guts" variable. As a result, the oops is triggered when mpc85xx_freeze_time_base() is executed.
Fixes: 56f1ba280719 ("powerpc/mpc85xx: refactor the PM operations") Cc: stable@vger.kernel.org # v4.6+ Signed-off-by: Xiaoming Ni nixiaoming@huawei.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210929033646.39630-2-nixiaoming@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c @@ -94,9 +94,8 @@ int __init mpc85xx_setup_pmc(void) pr_err("Could not map guts node address\n"); return -ENOMEM; } + qoriq_pm_ops = &mpc85xx_pm_ops; }
- qoriq_pm_ops = &mpc85xx_pm_ops; - return 0; }
From: Pavel Begunkov asml.silence@gmail.com
commit bad119b9a00019054f0c9e2045f312ed63ace4f4 upstream.
When we pass in zero as an io-wq worker number limit it shouldn't actually change the limits but return the old value, follow that behaviour with deferred limits setup as well.
Cc: stable@kernel.org # 5.15 Reported-by: Beld Zhang beldzhang@gmail.com Fixes: e139a1ec92f8d ("io_uring: apply max_workers limit to all future users") Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/1b222a92f7a78a24b042763805e891a4cdd4b544.163638403... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io_uring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -10684,7 +10684,9 @@ static int io_register_iowq_max_workers(
BUILD_BUG_ON(sizeof(new_count) != sizeof(ctx->iowq_limits));
- memcpy(ctx->iowq_limits, new_count, sizeof(new_count)); + for (i = 0; i < ARRAY_SIZE(new_count); i++) + if (new_count[i]) + ctx->iowq_limits[i] = new_count[i]; ctx->iowq_limits_set = true;
ret = -EINVAL;
From: Steven Rostedt (VMware) rostedt@goodmis.org
commit 51d157946666382e779f94c39891e8e9a020da78 upstream.
The resetting of the entire ring buffer use to simply go through and reset each individual CPU buffer that had its own protection and synchronization. But this was very slow, due to performing a synchronization for each CPU. The code was reshuffled to do one disabling of all CPU buffers, followed by a single RCU synchronization, and then the resetting of each of the CPU buffers. But unfortunately, the mutex that prevented multiple occurrences of resetting the buffer was not moved to the upper function, and there is nothing to protect from it.
Take the ring buffer mutex around the global reset.
Cc: stable@vger.kernel.org Fixes: b23d7a5f4a07a ("ring-buffer: speed up buffer resets by avoiding synchronize_rcu for each CPU") Reported-by: "Tzvetomir Stoyanov (VMware)" tz.stoyanov@gmail.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/trace/ring_buffer.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -5233,6 +5233,9 @@ void ring_buffer_reset(struct trace_buff struct ring_buffer_per_cpu *cpu_buffer; int cpu;
+ /* prevent another thread from changing buffer sizes */ + mutex_lock(&buffer->mutex); + for_each_buffer_cpu(buffer, cpu) { cpu_buffer = buffer->buffers[cpu];
@@ -5251,6 +5254,8 @@ void ring_buffer_reset(struct trace_buff atomic_dec(&cpu_buffer->record_disabled); atomic_dec(&cpu_buffer->resize_disabled); } + + mutex_unlock(&buffer->mutex); } EXPORT_SYMBOL_GPL(ring_buffer_reset);
From: Pali Rohár pali@kernel.org
commit 027b57170bf8bb6999a28e4a5f3d78bf1db0f90c upstream.
Since commit edc6afc54968 ("tty: switch to ktermios and new framework") termios speed is no longer stored only in c_cflag member but also in new additional c_ispeed and c_ospeed members. If BOTHER flag is set in c_cflag then termios speed is stored only in these new members.
Therefore to correctly restore termios speed it is required to store also ispeed and ospeed members, not only cflag member.
In case only cflag member with BOTHER flag is restored then functions tty_termios_baud_rate() and tty_termios_input_baud_rate() returns baudrate stored in c_ospeed / c_ispeed member, which is zero as it was not restored too. If reported baudrate is invalid (e.g. zero) then serial core functions report fallback baudrate value 9600. So it means that in this case original baudrate is lost and kernel changes it to value 9600.
Simple reproducer of this issue is to boot kernel with following command line argument: "console=ttyXXX,86400" (where ttyXXX is the device name). For speed 86400 there is no Bnnn constant and therefore kernel has to represent this speed via BOTHER c_cflag. Which means that speed is stored only in c_ospeed and c_ispeed members, not in c_cflag anymore.
If bootloader correctly configures serial device to speed 86400 then kernel prints boot log to early console at speed speed 86400 without any issue. But after kernel starts initializing real console device ttyXXX then speed is changed to fallback value 9600 because information about speed was lost.
This patch fixes above issue by storing and restoring also ispeed and ospeed members, which are required for BOTHER flag.
Fixes: edc6afc54968 ("[PATCH] tty: switch to ktermios and new framework") Cc: stable@vger.kernel.org Signed-off-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/20211002130900.9518-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/serial_core.c | 16 ++++++++++++++-- include/linux/console.h | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-)
--- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -222,7 +222,11 @@ static int uart_port_startup(struct tty_ if (retval == 0) { if (uart_console(uport) && uport->cons->cflag) { tty->termios.c_cflag = uport->cons->cflag; + tty->termios.c_ispeed = uport->cons->ispeed; + tty->termios.c_ospeed = uport->cons->ospeed; uport->cons->cflag = 0; + uport->cons->ispeed = 0; + uport->cons->ospeed = 0; } /* * Initialise the hardware port settings. @@ -290,8 +294,11 @@ static void uart_shutdown(struct tty_str /* * Turn off DTR and RTS early. */ - if (uport && uart_console(uport) && tty) + if (uport && uart_console(uport) && tty) { uport->cons->cflag = tty->termios.c_cflag; + uport->cons->ispeed = tty->termios.c_ispeed; + uport->cons->ospeed = tty->termios.c_ospeed; + }
if (!tty || C_HUPCL(tty)) uart_port_dtr_rts(uport, 0); @@ -2094,8 +2101,11 @@ uart_set_options(struct uart_port *port, * Allow the setting of the UART parameters with a NULL console * too: */ - if (co) + if (co) { co->cflag = termios.c_cflag; + co->ispeed = termios.c_ispeed; + co->ospeed = termios.c_ospeed; + }
return 0; } @@ -2229,6 +2239,8 @@ int uart_resume_port(struct uart_driver */ memset(&termios, 0, sizeof(struct ktermios)); termios.c_cflag = uport->cons->cflag; + termios.c_ispeed = uport->cons->ispeed; + termios.c_ospeed = uport->cons->ospeed;
/* * If that's unset, use the tty termios setting. --- a/include/linux/console.h +++ b/include/linux/console.h @@ -149,6 +149,8 @@ struct console { short flags; short index; int cflag; + uint ispeed; + uint ospeed; void *data; struct console *next; };
From: Arnd Bergmann arnd@arndb.de
commit 7444d706be31753f65052c7f6325fc8470cc1789 upstream.
The driver no longer depends on this option, but it fails to build if it's disabled because the skb->tc_skip_classify is hidden behind an #ifdef:
drivers/net/ifb.c:81:8: error: no member named 'tc_skip_classify' in 'struct sk_buff' skb->tc_skip_classify = 1;
Use the same #ifdef around the assignment.
Fixes: 046178e726c2 ("ifb: Depend on netfilter alternatively to tc") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ifb.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -76,7 +76,9 @@ static void ifb_ri_tasklet(struct taskle
while ((skb = __skb_dequeue(&txp->tq)) != NULL) { skb->redirected = 0; +#ifdef CONFIG_NET_CLS_ACT skb->tc_skip_classify = 1; +#endif
u64_stats_update_begin(&txp->tsync); txp->tx_packets++;
From: Juergen Gross jgross@suse.com
commit 40fdea0284bb20814399da0484a658a96c735d90 upstream.
When running as PVH or HVM guest with actual memory < max memory the hypervisor is using "populate on demand" in order to allow the guest to balloon down from its maximum memory size. For this to work correctly the guest must not touch more memory pages than its target memory size as otherwise the PoD cache will be exhausted and the guest is crashed as a result of that.
In extreme cases ballooning down might not be finished today before the init process is started, which can consume lots of memory.
In order to avoid random boot crashes in such cases, add a late init call to wait for ballooning down having finished for PVH/HVM guests.
Warn on console if initial ballooning fails, panic() after stalling for more than 3 minutes per default. Add a module parameter for changing this timeout.
[boris: replaced pr_info() with pr_notice()]
Cc: stable@vger.kernel.org Reported-by: Marek Marczykowski-Górecki marmarek@invisiblethingslab.com Signed-off-by: Juergen Gross jgross@suse.com Link: https://lore.kernel.org/r/20211102091944.17487-1-jgross@suse.com Reviewed-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/admin-guide/kernel-parameters.txt | 7 + drivers/xen/balloon.c | 86 +++++++++++++++++------- 2 files changed, 70 insertions(+), 23 deletions(-)
--- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6349,6 +6349,13 @@ improve timer resolution at the expense of processing more timer interrupts.
+ xen.balloon_boot_timeout= [XEN] + The time (in seconds) to wait before giving up to boot + in case initial ballooning fails to free enough memory. + Applies only when running as HVM or PVH guest and + started with less memory configured than allowed at + max. Default is 180. + xen.event_eoi_delay= [XEN] How long to delay EOI handling in case of event storms (jiffies). Default is 10. --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -58,6 +58,7 @@ #include <linux/percpu-defs.h> #include <linux/slab.h> #include <linux/sysctl.h> +#include <linux/moduleparam.h>
#include <asm/page.h> #include <asm/tlb.h> @@ -73,6 +74,12 @@ #include <xen/page.h> #include <xen/mem-reservation.h>
+#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "xen." + +static uint __read_mostly balloon_boot_timeout = 180; +module_param(balloon_boot_timeout, uint, 0444); + static int xen_hotplug_unpopulated;
#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG @@ -125,12 +132,12 @@ static struct ctl_table xen_root[] = { * BP_ECANCELED: error, balloon operation canceled. */
-enum bp_state { +static enum bp_state { BP_DONE, BP_WAIT, BP_EAGAIN, BP_ECANCELED -}; +} balloon_state = BP_DONE;
/* Main waiting point for xen-balloon thread. */ static DECLARE_WAIT_QUEUE_HEAD(balloon_thread_wq); @@ -199,18 +206,15 @@ static struct page *balloon_next_page(st return list_entry(next, struct page, lru); }
-static enum bp_state update_schedule(enum bp_state state) +static void update_schedule(void) { - if (state == BP_WAIT) - return BP_WAIT; - - if (state == BP_ECANCELED) - return BP_ECANCELED; + if (balloon_state == BP_WAIT || balloon_state == BP_ECANCELED) + return;
- if (state == BP_DONE) { + if (balloon_state == BP_DONE) { balloon_stats.schedule_delay = 1; balloon_stats.retry_count = 1; - return BP_DONE; + return; }
++balloon_stats.retry_count; @@ -219,7 +223,8 @@ static enum bp_state update_schedule(enu balloon_stats.retry_count > balloon_stats.max_retry_count) { balloon_stats.schedule_delay = 1; balloon_stats.retry_count = 1; - return BP_ECANCELED; + balloon_state = BP_ECANCELED; + return; }
balloon_stats.schedule_delay <<= 1; @@ -227,7 +232,7 @@ static enum bp_state update_schedule(enu if (balloon_stats.schedule_delay > balloon_stats.max_schedule_delay) balloon_stats.schedule_delay = balloon_stats.max_schedule_delay;
- return BP_EAGAIN; + balloon_state = BP_EAGAIN; }
#ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG @@ -494,9 +499,9 @@ static enum bp_state decrease_reservatio * Stop waiting if either state is BP_DONE and ballooning action is * needed, or if the credit has changed while state is not BP_DONE. */ -static bool balloon_thread_cond(enum bp_state state, long credit) +static bool balloon_thread_cond(long credit) { - if (state == BP_DONE) + if (balloon_state == BP_DONE) credit = 0;
return current_credit() != credit || kthread_should_stop(); @@ -510,13 +515,12 @@ static bool balloon_thread_cond(enum bp_ */ static int balloon_thread(void *unused) { - enum bp_state state = BP_DONE; long credit; unsigned long timeout;
set_freezable(); for (;;) { - switch (state) { + switch (balloon_state) { case BP_DONE: case BP_ECANCELED: timeout = 3600 * HZ; @@ -532,7 +536,7 @@ static int balloon_thread(void *unused) credit = current_credit();
wait_event_freezable_timeout(balloon_thread_wq, - balloon_thread_cond(state, credit), timeout); + balloon_thread_cond(credit), timeout);
if (kthread_should_stop()) return 0; @@ -543,22 +547,23 @@ static int balloon_thread(void *unused)
if (credit > 0) { if (balloon_is_inflated()) - state = increase_reservation(credit); + balloon_state = increase_reservation(credit); else - state = reserve_additional_memory(); + balloon_state = reserve_additional_memory(); }
if (credit < 0) { long n_pages;
n_pages = min(-credit, si_mem_available()); - state = decrease_reservation(n_pages, GFP_BALLOON); - if (state == BP_DONE && n_pages != -credit && + balloon_state = decrease_reservation(n_pages, + GFP_BALLOON); + if (balloon_state == BP_DONE && n_pages != -credit && n_pages < totalreserve_pages) - state = BP_EAGAIN; + balloon_state = BP_EAGAIN; }
- state = update_schedule(state); + update_schedule();
mutex_unlock(&balloon_mutex);
@@ -765,3 +770,38 @@ static int __init balloon_init(void) return 0; } subsys_initcall(balloon_init); + +static int __init balloon_wait_finish(void) +{ + long credit, last_credit = 0; + unsigned long last_changed = 0; + + if (!xen_domain()) + return -ENODEV; + + /* PV guests don't need to wait. */ + if (xen_pv_domain() || !current_credit()) + return 0; + + pr_notice("Waiting for initial ballooning down having finished.\n"); + + while ((credit = current_credit()) < 0) { + if (credit != last_credit) { + last_changed = jiffies; + last_credit = credit; + } + if (balloon_state == BP_ECANCELED) { + pr_warn_once("Initial ballooning failed, %ld pages need to be freed.\n", + -credit); + if (jiffies - last_changed >= HZ * balloon_boot_timeout) + panic("Initial ballooning failed!\n"); + } + + schedule_timeout_interruptible(HZ / 10); + } + + pr_notice("Initial ballooning down finished.\n"); + + return 0; +} +late_initcall_sync(balloon_wait_finish);
From: yangerkun yangerkun@huawei.com
commit 9a254403760041528bc8f69fe2f5e1ef86950991 upstream.
Example for triggering use after free in a overlay on ext4 setup:
aio_read ovl_read_iter vfs_iter_read ext4_file_read_iter ext4_dio_read_iter iomap_dio_rw -> -EIOCBQUEUED /* * Here IO is completed in a separate thread, * ovl_aio_cleanup_handler() frees aio_req which has iocb embedded */ file_accessed(iocb->ki_filp); /**BOOM**/
Fix by introducing a refcount in ovl_aio_req similarly to aio_kiocb. This guarantees that iocb is only freed after vfs_read/write_iter() returns on underlying fs.
Fixes: 2406a307ac7d ("ovl: implement async IO routines") Signed-off-by: yangerkun yangerkun@huawei.com Link: https://lore.kernel.org/r/20210930032228.3199690-3-yangerkun@huawei.com/ Cc: stable@vger.kernel.org # v5.6 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/file.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
--- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -17,6 +17,7 @@
struct ovl_aio_req { struct kiocb iocb; + refcount_t ref; struct kiocb *orig_iocb; struct fd fd; }; @@ -252,6 +253,14 @@ static rwf_t ovl_iocb_to_rwf(int ifl) return flags; }
+static inline void ovl_aio_put(struct ovl_aio_req *aio_req) +{ + if (refcount_dec_and_test(&aio_req->ref)) { + fdput(aio_req->fd); + kmem_cache_free(ovl_aio_request_cachep, aio_req); + } +} + static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req) { struct kiocb *iocb = &aio_req->iocb; @@ -268,8 +277,7 @@ static void ovl_aio_cleanup_handler(stru }
orig_iocb->ki_pos = iocb->ki_pos; - fdput(aio_req->fd); - kmem_cache_free(ovl_aio_request_cachep, aio_req); + ovl_aio_put(aio_req); }
static void ovl_aio_rw_complete(struct kiocb *iocb, long res, long res2) @@ -319,7 +327,9 @@ static ssize_t ovl_read_iter(struct kioc aio_req->orig_iocb = iocb; kiocb_clone(&aio_req->iocb, iocb, real.file); aio_req->iocb.ki_complete = ovl_aio_rw_complete; + refcount_set(&aio_req->ref, 2); ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter); + ovl_aio_put(aio_req); if (ret != -EIOCBQUEUED) ovl_aio_cleanup_handler(aio_req); } @@ -390,7 +400,9 @@ static ssize_t ovl_write_iter(struct kio kiocb_clone(&aio_req->iocb, iocb, real.file); aio_req->iocb.ki_flags = ifl; aio_req->iocb.ki_complete = ovl_aio_rw_complete; + refcount_set(&aio_req->ref, 2); ret = vfs_iocb_iter_write(real.file, &aio_req->iocb, iter); + ovl_aio_put(aio_req); if (ret != -EIOCBQUEUED) ovl_aio_cleanup_handler(aio_req); }
From: Miklos Szeredi mszeredi@redhat.com
commit 5b0a414d06c3ed2097e32ef7944a4abb644b89bd upstream.
This regression can be reproduced with ntfs-3g and overlayfs:
mkdir lower upper work overlay dd if=/dev/zero of=ntfs.raw bs=1M count=2 mkntfs -F ntfs.raw mount ntfs.raw lower touch lower/file.txt mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work - overlay mv overlay/file.txt overlay/file2.txt
mv fails and (misleadingly) prints
mv: cannot move 'overlay/file.txt' to a subdirectory of itself, 'overlay/file2.txt'
The reason is that ovl_copy_fileattr() is triggered due to S_NOATIME being set on all inodes (by fuse) regardless of fileattr.
ovl_copy_fileattr() tries to retrieve file attributes from lower file, but that fails because filesystem does not support this ioctl (this should fail with ENOTTY, but ntfs-3g return EINVAL instead). This failure is propagated to origial operation (in this case rename) that triggered the copy-up.
The fix is to ignore ENOTTY and EINVAL errors from fileattr_get() in copy up. This also requires turning the internal ENOIOCTLCMD into ENOTTY.
As a further measure to prevent unnecessary failures, only try the fileattr_get/set on upper if there are any flags to copy up.
Side note: a number of filesystems set S_NOATIME (and sometimes other inode flags) irrespective of fileattr flags. This causes unnecessary calls during copy up, which might lead to a performance issue, especially if latency is high. To fix this, the kernel would need to differentiate between the two cases. E.g. introduce SB_NOATIME_UPDATE, a per-sb variant of S_NOATIME. SB_NOATIME doesn't work, because that's interpreted as "filesystem doesn't store an atime attribute"
Reported-and-tested-by: Kevin Locke kevin@kevinlocke.name Fixes: 72db82115d2b ("ovl: copy up sync/noatime fileattr flags") Cc: stable@vger.kernel.org # v5.15 Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/overlayfs/copy_up.c | 23 ++++++++++++++++++----- fs/overlayfs/inode.c | 5 ++++- 2 files changed, 22 insertions(+), 6 deletions(-)
--- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -140,12 +140,14 @@ static int ovl_copy_fileattr(struct inod int err;
err = ovl_real_fileattr_get(old, &oldfa); - if (err) - return err; - - err = ovl_real_fileattr_get(new, &newfa); - if (err) + if (err) { + /* Ntfs-3g returns -EINVAL for "no fileattr support" */ + if (err == -ENOTTY || err == -EINVAL) + return 0; + pr_warn("failed to retrieve lower fileattr (%pd2, err=%i)\n", + old, err); return err; + }
/* * We cannot set immutable and append-only flags on upper inode, @@ -159,6 +161,17 @@ static int ovl_copy_fileattr(struct inod return err; }
+ /* Don't bother copying flags if none are set */ + if (!(oldfa.flags & OVL_COPY_FS_FLAGS_MASK)) + return 0; + + err = ovl_real_fileattr_get(new, &newfa); + if (err) { + pr_warn("failed to retrieve upper fileattr (%pd2, err=%i)\n", + new, err); + return err; + } + BUILD_BUG_ON(OVL_COPY_FS_FLAGS_MASK & ~FS_COMMON_FL); newfa.flags &= ~OVL_COPY_FS_FLAGS_MASK; newfa.flags |= (oldfa.flags & OVL_COPY_FS_FLAGS_MASK); --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -610,7 +610,10 @@ int ovl_real_fileattr_get(struct path *r if (err) return err;
- return vfs_fileattr_get(realpath->dentry, fa); + err = vfs_fileattr_get(realpath->dentry, fa); + if (err == -ENOIOCTLCMD) + err = -ENOTTY; + return err; }
int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa)
From: Marek Behún kabel@kernel.org
commit 7a41ae80bdcb17e14dd7d83239b8a0cf368f18be upstream.
The pci_bridge_emul_conf_write() function correctly clears W1C bits in cfgspace cache, but it does not inform the underlying implementation about the clear request: the .write_op() method is given the value with these bits cleared.
This is wrong if the .write_op() needs to know which bits were requested to be cleared.
Fix the value to be passed into the .write_op() method to have requested W1C bits set, so that it can clear them.
Both pci-bridge-emul users (mvebu and aardvark) are compatible with this change.
Link: https://lore.kernel.org/r/20211028185659.20329-2-kabel@kernel.org Fixes: 23a5fba4d941 ("PCI: Introduce PCI bridge emulated config space common logic") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Cc: Russell King rmk+kernel@armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/pci-bridge-emul.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
--- a/drivers/pci/pci-bridge-emul.c +++ b/drivers/pci/pci-bridge-emul.c @@ -431,8 +431,21 @@ int pci_bridge_emul_conf_write(struct pc /* Clear the W1C bits */ new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
+ /* Save the new value with the cleared W1C bits into the cfgspace */ cfgspace[reg / 4] = cpu_to_le32(new);
+ /* + * Clear the W1C bits not specified by the write mask, so that the + * write_op() does not clear them. + */ + new &= ~(behavior[reg / 4].w1c & ~mask); + + /* + * Set the W1C bits specified by the write mask, so that write_op() + * knows about that they are to be cleared. + */ + new |= (value << shift) & (behavior[reg / 4].w1c & mask); + if (write_op) write_op(bridge, reg, old, new, mask);
From: Li Chen lchen@ambarella.com
commit 27cd7e3c9bb1ae13bc16f08138edd6e4df3cd211 upstream.
When cdns_plat_pcie_probe() succeeds, return success instead of falling into the error handling code.
Fixes: bd22885aa188 ("PCI: cadence: Refactor driver to use as a core library") Link: https://lore.kernel.org/r/DM6PR19MB40271B93057D949310F0B0EDA0BF9@DM6PR19MB40... Signed-off-by: Xuliang Zhang xlzhanga@ambarella.com Signed-off-by: Li Chen lchen@ambarella.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/cadence/pcie-cadence-plat.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c +++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c @@ -127,6 +127,8 @@ static int cdns_plat_pcie_probe(struct p goto err_init; }
+ return 0; + err_init: err_get_sync: pm_runtime_put_sync(dev);
From: Dan Williams dan.j.williams@intel.com
commit ca76a3a8052b71c0334d5c094859cfa340c290a8 upstream.
cxl_pci_map_regblock() may return an ERR_PTR(), but cxl_pci_setup_regs() is only prepared for NULL as the error case. Pick the minimal fix for -stable backport purposes and just have cxl_pci_map_regblock() return NULL for errors.
Fixes: f8a7e8c29be8 ("cxl/pci: Reserve all device regions at once") Cc: stable@vger.kernel.org Reviewed-by: Ira Weiny ira.weiny@intel.com Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Link: https://lore.kernel.org/r/163433325724.834522.17809774578178224149.stgit@dwi... Signed-off-by: Dan Williams dan.j.williams@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/cxl/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/cxl/pci.c +++ b/drivers/cxl/pci.c @@ -972,7 +972,7 @@ static void __iomem *cxl_mem_map_regbloc if (pci_resource_len(pdev, bar) < offset) { dev_err(dev, "BAR%d: %pr: too small (offset: %#llx)\n", bar, &pdev->resource[bar], (unsigned long long)offset); - return IOMEM_ERR_PTR(-ENXIO); + return NULL; }
addr = pci_iomap(pdev, bar, 0);
From: Pali Rohár pali@kernel.org
commit a7ca6d7fa3c02c032db5440ff392d96c04684c21 upstream.
The PCIE_ISR1_REG says which interrupts are currently set / active, including those which are masked.
The driver currently reads this register and looks if some unmasked interrupts are active, and if not, it clears status bits of _all_ interrupts, including the masked ones.
This is incorrect, since, for example, some drivers may poll these bits.
Remove this clearing, and also remove this early return statement completely, since it does not change functionality in any way.
Link: https://lore.kernel.org/r/20211005180952.6812-7-kabel@kernel.org Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -1286,12 +1286,6 @@ static void advk_pcie_handle_int(struct isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
- if (!isr0_status && !isr1_status) { - advk_writel(pcie, isr0_val, PCIE_ISR0_REG); - advk_writel(pcie, isr1_val, PCIE_ISR1_REG); - return; - } - /* Process MSI interrupts */ if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) advk_pcie_handle_msi(pcie);
From: Pali Rohár pali@kernel.org
commit 661c399a651c11aaf83c45cbfe0b4a1fb7bc3179 upstream.
Current implementation of advk_pcie_link_up() is wrong as it marks also link disabled or hot reset states as link up.
Fix it by marking link up only to those states which are defined in PCIe Base specification 3.0, Table 4-14: Link Status Mapped to the LTSSM.
To simplify implementation, Define macros for every LTSSM state which aardvark hardware can return in CFG_REG register.
Fix also checking for link training according to the same Table 4-14. Define a new function advk_pcie_link_training() for this purpose.
Link: https://lore.kernel.org/r/20211005180952.6812-13-kabel@kernel.org Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org Cc: Remi Pommarel repk@triplefau.lt Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 76 +++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 6 deletions(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -164,8 +164,50 @@ #define CFG_REG (LMI_BASE_ADDR + 0x0) #define LTSSM_SHIFT 24 #define LTSSM_MASK 0x3f -#define LTSSM_L0 0x10 #define RC_BAR_CONFIG 0x300 + +/* LTSSM values in CFG_REG */ +enum { + LTSSM_DETECT_QUIET = 0x0, + LTSSM_DETECT_ACTIVE = 0x1, + LTSSM_POLLING_ACTIVE = 0x2, + LTSSM_POLLING_COMPLIANCE = 0x3, + LTSSM_POLLING_CONFIGURATION = 0x4, + LTSSM_CONFIG_LINKWIDTH_START = 0x5, + LTSSM_CONFIG_LINKWIDTH_ACCEPT = 0x6, + LTSSM_CONFIG_LANENUM_ACCEPT = 0x7, + LTSSM_CONFIG_LANENUM_WAIT = 0x8, + LTSSM_CONFIG_COMPLETE = 0x9, + LTSSM_CONFIG_IDLE = 0xa, + LTSSM_RECOVERY_RCVR_LOCK = 0xb, + LTSSM_RECOVERY_SPEED = 0xc, + LTSSM_RECOVERY_RCVR_CFG = 0xd, + LTSSM_RECOVERY_IDLE = 0xe, + LTSSM_L0 = 0x10, + LTSSM_RX_L0S_ENTRY = 0x11, + LTSSM_RX_L0S_IDLE = 0x12, + LTSSM_RX_L0S_FTS = 0x13, + LTSSM_TX_L0S_ENTRY = 0x14, + LTSSM_TX_L0S_IDLE = 0x15, + LTSSM_TX_L0S_FTS = 0x16, + LTSSM_L1_ENTRY = 0x17, + LTSSM_L1_IDLE = 0x18, + LTSSM_L2_IDLE = 0x19, + LTSSM_L2_TRANSMIT_WAKE = 0x1a, + LTSSM_DISABLED = 0x20, + LTSSM_LOOPBACK_ENTRY_MASTER = 0x21, + LTSSM_LOOPBACK_ACTIVE_MASTER = 0x22, + LTSSM_LOOPBACK_EXIT_MASTER = 0x23, + LTSSM_LOOPBACK_ENTRY_SLAVE = 0x24, + LTSSM_LOOPBACK_ACTIVE_SLAVE = 0x25, + LTSSM_LOOPBACK_EXIT_SLAVE = 0x26, + LTSSM_HOT_RESET = 0x27, + LTSSM_RECOVERY_EQUALIZATION_PHASE0 = 0x28, + LTSSM_RECOVERY_EQUALIZATION_PHASE1 = 0x29, + LTSSM_RECOVERY_EQUALIZATION_PHASE2 = 0x2a, + LTSSM_RECOVERY_EQUALIZATION_PHASE3 = 0x2b, +}; + #define VENDOR_ID_REG (LMI_BASE_ADDR + 0x44)
/* PCIe core controller registers */ @@ -262,13 +304,35 @@ static inline u16 advk_read16(struct adv return advk_readl(pcie, (reg & ~0x3)) >> ((reg & 0x3) * 8); }
-static int advk_pcie_link_up(struct advk_pcie *pcie) +static u8 advk_pcie_ltssm_state(struct advk_pcie *pcie) { - u32 val, ltssm_state; + u32 val; + u8 ltssm_state;
val = advk_readl(pcie, CFG_REG); ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK; - return ltssm_state >= LTSSM_L0; + return ltssm_state; +} + +static inline bool advk_pcie_link_up(struct advk_pcie *pcie) +{ + /* check if LTSSM is in normal operation - some L* state */ + u8 ltssm_state = advk_pcie_ltssm_state(pcie); + return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED; +} + +static inline bool advk_pcie_link_training(struct advk_pcie *pcie) +{ + /* + * According to PCIe Base specification 3.0, Table 4-14: Link + * Status Mapped to the LTSSM is Link Training mapped to LTSSM + * Configuration and Recovery states. + */ + u8 ltssm_state = advk_pcie_ltssm_state(pcie); + return ((ltssm_state >= LTSSM_CONFIG_LINKWIDTH_START && + ltssm_state < LTSSM_L0) || + (ltssm_state >= LTSSM_RECOVERY_EQUALIZATION_PHASE0 && + ltssm_state <= LTSSM_RECOVERY_EQUALIZATION_PHASE3)); }
static int advk_pcie_wait_for_link(struct advk_pcie *pcie) @@ -291,7 +355,7 @@ static void advk_pcie_wait_for_retrain(s size_t retries;
for (retries = 0; retries < RETRAIN_WAIT_MAX_RETRIES; ++retries) { - if (!advk_pcie_link_up(pcie)) + if (advk_pcie_link_training(pcie)) break; udelay(RETRAIN_WAIT_USLEEP_US); } @@ -738,7 +802,7 @@ advk_pci_bridge_emul_pcie_conf_read(stru /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */ u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) & ~(PCI_EXP_LNKSTA_LT << 16); - if (!advk_pcie_link_up(pcie)) + if (advk_pcie_link_training(pcie)) val |= (PCI_EXP_LNKSTA_LT << 16); *value = val; return PCI_BRIDGE_EMUL_HANDLED;
From: Pali Rohár pali@kernel.org
commit 1fb95d7d3c7a926b002fe8a6bd27a1cb428b46dc upstream.
There are lot of undocumented interrupt bits. To prevent unwanted spurious interrupts, fix all *_ALL_MASK macros to define all interrupt bits, so that driver can properly mask all interrupts, including those which are undocumented.
Link: https://lore.kernel.org/r/20211005180952.6812-8-kabel@kernel.org Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -106,13 +106,13 @@ #define PCIE_ISR0_MSI_INT_PENDING BIT(24) #define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val)) #define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val)) -#define PCIE_ISR0_ALL_MASK GENMASK(26, 0) +#define PCIE_ISR0_ALL_MASK GENMASK(31, 0) #define PCIE_ISR1_REG (CONTROL_BASE_ADDR + 0x48) #define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C) #define PCIE_ISR1_POWER_STATE_CHANGE BIT(4) #define PCIE_ISR1_FLUSH BIT(5) #define PCIE_ISR1_INTX_ASSERT(val) BIT(8 + (val)) -#define PCIE_ISR1_ALL_MASK GENMASK(11, 4) +#define PCIE_ISR1_ALL_MASK GENMASK(31, 0) #define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50) #define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54) #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) @@ -240,7 +240,7 @@ enum { #define PCIE_IRQ_MSI_INT2_DET BIT(21) #define PCIE_IRQ_RC_DBELL_DET BIT(22) #define PCIE_IRQ_EP_STATUS BIT(23) -#define PCIE_IRQ_ALL_MASK 0xfff0fb +#define PCIE_IRQ_ALL_MASK GENMASK(31, 0) #define PCIE_IRQ_ENABLE_INTS_MASK PCIE_IRQ_CORE_INT
/* Transaction types */
From: Pali Rohár pali@kernel.org
commit 2b650b7ff20eb7ea8ef9031d20fb657286ab90cc upstream.
Add support for reporting PCI_EXP_LNKSTA_DLLLA bit in Link Control register on emulated bridge via current LTSSM state. Also correctly indicate DLLLA capability via PCI_EXP_LNKCAP_DLLLARC bit in Link Control Capability register.
Link: https://lore.kernel.org/r/20211005180952.6812-14-kabel@kernel.org Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -321,6 +321,20 @@ static inline bool advk_pcie_link_up(str return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED; }
+static inline bool advk_pcie_link_active(struct advk_pcie *pcie) +{ + /* + * According to PCIe Base specification 3.0, Table 4-14: Link + * Status Mapped to the LTSSM, and 4.2.6.3.6 Configuration.Idle + * is Link Up mapped to LTSSM Configuration.Idle, Recovery, L0, + * L0s, L1 and L2 states. And according to 3.2.1. Data Link + * Control and Management State Machine Rules is DL Up status + * reported in DL Active state. + */ + u8 ltssm_state = advk_pcie_ltssm_state(pcie); + return ltssm_state >= LTSSM_CONFIG_IDLE && ltssm_state < LTSSM_DISABLED; +} + static inline bool advk_pcie_link_training(struct advk_pcie *pcie) { /* @@ -798,12 +812,26 @@ advk_pci_bridge_emul_pcie_conf_read(stru return PCI_BRIDGE_EMUL_HANDLED; }
+ case PCI_EXP_LNKCAP: { + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); + /* + * PCI_EXP_LNKCAP_DLLLARC bit is hardwired in aardvark HW to 0. + * But support for PCI_EXP_LNKSTA_DLLLA is emulated via ltssm + * state so explicitly enable PCI_EXP_LNKCAP_DLLLARC flag. + */ + val |= PCI_EXP_LNKCAP_DLLLARC; + *value = val; + return PCI_BRIDGE_EMUL_HANDLED; + } + case PCI_EXP_LNKCTL: { /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */ u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) & ~(PCI_EXP_LNKSTA_LT << 16); if (advk_pcie_link_training(pcie)) val |= (PCI_EXP_LNKSTA_LT << 16); + if (advk_pcie_link_active(pcie)) + val |= (PCI_EXP_LNKSTA_DLLLA << 16); *value = val; return PCI_BRIDGE_EMUL_HANDLED; } @@ -811,7 +839,6 @@ advk_pci_bridge_emul_pcie_conf_read(stru case PCI_CAP_LIST_ID: case PCI_EXP_DEVCAP: case PCI_EXP_DEVCTL: - case PCI_EXP_LNKCAP: *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); return PCI_BRIDGE_EMUL_HANDLED; default:
From: Pali Rohár pali@kernel.org
commit 46ef6090dbf590711cb12680b6eafde5fa21fe87 upstream.
Commit 366697018c9a ("PCI: aardvark: Add PHY support") introduced configuration of PCIe Reference clock via PCIE_CORE_REF_CLK_REG register, but did it incorrectly.
PCIe Reference clock differential pair is routed from system board to endpoint card, so on CPU side it has output direction. Therefore it is required to enable transmitting and disable receiving.
Default configuration according to Armada 3700 Functional Specifications is enabled receiver part and disabled transmitter.
We need this change because otherwise PCIe Reference clock is configured to some undefined state when differential pair is used for both transmitting and receiving.
Fix this by disabling receiver part.
Link: https://lore.kernel.org/r/20211005180952.6812-6-kabel@kernel.org Fixes: 366697018c9a ("PCI: aardvark: Add PHY support") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -99,6 +99,7 @@ #define PCIE_CORE_CTRL2_MSI_ENABLE BIT(10) #define PCIE_CORE_REF_CLK_REG (CONTROL_BASE_ADDR + 0x14) #define PCIE_CORE_REF_CLK_TX_ENABLE BIT(1) +#define PCIE_CORE_REF_CLK_RX_ENABLE BIT(2) #define PCIE_MSG_LOG_REG (CONTROL_BASE_ADDR + 0x30) #define PCIE_ISR0_REG (CONTROL_BASE_ADDR + 0x40) #define PCIE_MSG_PM_PME_MASK BIT(7) @@ -529,9 +530,15 @@ static void advk_pcie_setup_hw(struct ad u32 reg; int i;
- /* Enable TX */ + /* + * Configure PCIe Reference clock. Direction is from the PCIe + * controller to the endpoint card, so enable transmitting of + * Reference clock differential signal off-chip and disable + * receiving off-chip differential signal. + */ reg = advk_readl(pcie, PCIE_CORE_REF_CLK_REG); reg |= PCIE_CORE_REF_CLK_TX_ENABLE; + reg &= ~PCIE_CORE_REF_CLK_RX_ENABLE; advk_writel(pcie, reg, PCIE_CORE_REF_CLK_REG);
/* Set to Direct mode */
From: Marek Behún kabel@kernel.org
commit e4313be1599d397625c14fb7826996813622decf upstream.
MSI domain callback .alloc() (implemented by advk_msi_irq_domain_alloc() function) should return zero on success, since non-zero value indicates failure.
When the driver was converted to generic MSI API in commit f21a8b1b6837 ("PCI: aardvark: Move to MSI handling using generic MSI support"), it was converted so that it returns hwirq number.
Fix this.
Link: https://lore.kernel.org/r/20211028185659.20329-3-kabel@kernel.org Fixes: f21a8b1b6837 ("PCI: aardvark: Move to MSI handling using generic MSI support") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -1180,7 +1180,7 @@ static int advk_msi_irq_domain_alloc(str domain->host_data, handle_simple_irq, NULL, NULL);
- return hwirq; + return 0; }
static void advk_msi_irq_domain_free(struct irq_domain *domain,
From: Marek Behún kabel@kernel.org
commit 95997723b6402cd6c53e0f9e7ac640ec64eaaff8 upstream.
The PCIE_MSI_PAYLOAD_REG contains 16-bit MSI number, not only lower 8 bits. Fix reading content of this register and add a comment describing the access to this register.
Link: https://lore.kernel.org/r/20211028185659.20329-4-kabel@kernel.org Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -119,6 +119,7 @@ #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) #define PCIE_MSI_MASK_REG (CONTROL_BASE_ADDR + 0x5C) #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C) +#define PCIE_MSI_DATA_MASK GENMASK(15, 0)
/* PCIe window configuration */ #define OB_WIN_BASE_ADDR 0x4c00 @@ -1361,8 +1362,12 @@ static void advk_pcie_handle_msi(struct if (!(BIT(msi_idx) & msi_status)) continue;
+ /* + * msi_idx contains bits [4:0] of the msi_data and msi_data + * contains 16bit MSI interrupt number + */ advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG); - msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF; + msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & PCIE_MSI_DATA_MASK; generic_handle_irq(msi_data); }
From: Pali Rohár pali@kernel.org
commit 771153fc884f566a89af2d30033b7f3bc6e24e84 upstream.
From very vague, ambiguous and incomplete information from Marvell we
deduced that the 32-bit Aardvark register at address 0x4 (PCIE_CORE_CMD_STATUS_REG), which is not documented for Root Complex mode in the Functional Specification (only for Endpoint mode), controls two 16-bit PCIe registers: Command Register and Status Registers of PCIe Root Port.
This means that bit 2 controls bus mastering and forwarding of memory and I/O requests in the upstream direction. According to PCI specifications bits [0:2] of Command Register, this should be by default disabled on reset. So explicitly disable these bits at early setup of the Aardvark driver.
Remove code which unconditionally enables all 3 bits and let kernel code (via pci_set_master() function) to handle bus mastering of Root PCIe Bridge via emulated PCI_COMMAND on emulated bridge.
Link: https://lore.kernel.org/r/20211028185659.20329-5-kabel@kernel.org Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org # b2a56469d550 ("PCI: aardvark: Add FIXME comment for PCIE_CORE_CMD_STATUS_REG access") Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 54 +++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -31,9 +31,6 @@ /* PCIe core registers */ #define PCIE_CORE_DEV_ID_REG 0x0 #define PCIE_CORE_CMD_STATUS_REG 0x4 -#define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) -#define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) -#define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) #define PCIE_CORE_DEV_REV_REG 0x8 #define PCIE_CORE_PCIEXP_CAP 0xc0 #define PCIE_CORE_ERR_CAPCTL_REG 0x118 @@ -563,6 +560,11 @@ static void advk_pcie_setup_hw(struct ad reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; advk_writel(pcie, reg, VENDOR_ID_REG);
+ /* Disable Root Bridge I/O space, memory space and bus mastering */ + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); + /* Set Advanced Error Capabilities and Control PF0 register */ reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | @@ -660,19 +662,6 @@ static void advk_pcie_setup_hw(struct ad advk_pcie_disable_ob_win(pcie, i);
advk_pcie_train_link(pcie); - - /* - * FIXME: The following register update is suspicious. This register is - * applicable only when the PCI controller is configured for Endpoint - * mode, not as a Root Complex. But apparently when this code is - * removed, some cards stop working. This should be investigated and - * a comment explaining this should be put here. - */ - reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); - reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | - PCIE_CORE_CMD_IO_ACCESS_EN | - PCIE_CORE_CMD_MEM_IO_REQ_EN; - advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); }
static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u32 *val) @@ -793,6 +782,37 @@ static int advk_pcie_wait_pio(struct adv return -ETIMEDOUT; }
+static pci_bridge_emul_read_status_t +advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge, + int reg, u32 *value) +{ + struct advk_pcie *pcie = bridge->data; + + switch (reg) { + case PCI_COMMAND: + *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + return PCI_BRIDGE_EMUL_HANDLED; + + default: + return PCI_BRIDGE_EMUL_NOT_HANDLED; + } +} + +static void +advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, + int reg, u32 old, u32 new, u32 mask) +{ + struct advk_pcie *pcie = bridge->data; + + switch (reg) { + case PCI_COMMAND: + advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); + break; + + default: + break; + } +}
static pci_bridge_emul_read_status_t advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, @@ -893,6 +913,8 @@ advk_pci_bridge_emul_pcie_conf_write(str }
static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { + .read_base = advk_pci_bridge_emul_base_conf_read, + .write_base = advk_pci_bridge_emul_base_conf_write, .read_pcie = advk_pci_bridge_emul_pcie_conf_read, .write_pcie = advk_pci_bridge_emul_pcie_conf_write, };
From: Pali Rohár pali@kernel.org
commit bc4fac42e5f8460af09c0a7f2f1915be09e20c71 upstream.
Aardvark supports PCIe Hot Reset via PCIE_CORE_CTRL1_REG.
Use it for implementing PCI_BRIDGE_CTL_BUS_RESET bit of PCI_BRIDGE_CONTROL register on emulated bridge.
With this, the function pci_reset_secondary_bus() starts working and can reset connected PCIe card. Custom userspace script [1] which uses setpci can trigger PCIe Hot Reset and reset the card manually.
[1] https://alexforencich.com/wiki/en/pcie/hot-reset-linux
Link: https://lore.kernel.org/r/20211028185659.20329-7-kabel@kernel.org Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -793,6 +793,22 @@ advk_pci_bridge_emul_base_conf_read(stru *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); return PCI_BRIDGE_EMUL_HANDLED;
+ case PCI_INTERRUPT_LINE: { + /* + * From the whole 32bit register we support reading from HW only + * one bit: PCI_BRIDGE_CTL_BUS_RESET. + * Other bits are retrieved only from emulated config buffer. + */ + __le32 *cfgspace = (__le32 *)&bridge->conf; + u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]); + if (advk_readl(pcie, PCIE_CORE_CTRL1_REG) & HOT_RESET_GEN) + val |= PCI_BRIDGE_CTL_BUS_RESET << 16; + else + val &= ~(PCI_BRIDGE_CTL_BUS_RESET << 16); + *value = val; + return PCI_BRIDGE_EMUL_HANDLED; + } + default: return PCI_BRIDGE_EMUL_NOT_HANDLED; } @@ -809,6 +825,17 @@ advk_pci_bridge_emul_base_conf_write(str advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); break;
+ case PCI_INTERRUPT_LINE: + if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { + u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); + if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16)) + val |= HOT_RESET_GEN; + else + val &= ~HOT_RESET_GEN; + advk_writel(pcie, val, PCIE_CORE_CTRL1_REG); + } + break; + default: break; }
From: Pali Rohár pali@kernel.org
commit 84e1b4045dc887b78bdc87d92927093dc3a465aa upstream.
Aardvark controller has something like config space of a Root Port available at offset 0x0 of internal registers - these registers are used for implementation of the emulated bridge.
The default value of Class Code of this bridge corresponds to a RAID Mass storage controller, though. (This is probably intended for when the controller is used as Endpoint.)
Change the Class Code to correspond to a PCI Bridge.
Add comment explaining this change.
Link: https://lore.kernel.org/r/20211028185659.20329-6-kabel@kernel.org Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -560,6 +560,26 @@ static void advk_pcie_setup_hw(struct ad reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; advk_writel(pcie, reg, VENDOR_ID_REG);
+ /* + * Change Class Code of PCI Bridge device to PCI Bridge (0x600400), + * because the default value is Mass storage controller (0x010400). + * + * Note that this Aardvark PCI Bridge does not have compliant Type 1 + * Configuration Space and it even cannot be accessed via Aardvark's + * PCI config space access method. Something like config space is + * available in internal Aardvark registers starting at offset 0x0 + * and is reported as Type 0. In range 0x10 - 0x34 it has totally + * different registers. + * + * Therefore driver uses emulation of PCI Bridge which emulates + * access to configuration space via internal Aardvark registers or + * emulated configuration buffer. + */ + reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG); + reg &= ~0xffffff00; + reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8; + advk_writel(pcie, reg, PCIE_CORE_DEV_REV_REG); + /* Disable Root Bridge I/O space, memory space and bus mastering */ reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
From: Pali Rohár pali@kernel.org
commit 239edf686c14a9ff926dec2f350289ed7adfefe2 upstream.
This register is exported at address offset 0x30.
Link: https://lore.kernel.org/r/20211028185659.20329-8-kabel@kernel.org Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 9 +++++++++ 1 file changed, 9 insertions(+)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -32,6 +32,7 @@ #define PCIE_CORE_DEV_ID_REG 0x0 #define PCIE_CORE_CMD_STATUS_REG 0x4 #define PCIE_CORE_DEV_REV_REG 0x8 +#define PCIE_CORE_EXP_ROM_BAR_REG 0x30 #define PCIE_CORE_PCIEXP_CAP 0xc0 #define PCIE_CORE_ERR_CAPCTL_REG 0x118 #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) @@ -813,6 +814,10 @@ advk_pci_bridge_emul_base_conf_read(stru *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); return PCI_BRIDGE_EMUL_HANDLED;
+ case PCI_ROM_ADDRESS1: + *value = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG); + return PCI_BRIDGE_EMUL_HANDLED; + case PCI_INTERRUPT_LINE: { /* * From the whole 32bit register we support reading from HW only @@ -845,6 +850,10 @@ advk_pci_bridge_emul_base_conf_write(str advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); break;
+ case PCI_ROM_ADDRESS1: + advk_writel(pcie, new, PCIE_CORE_EXP_ROM_BAR_REG); + break; + case PCI_INTERRUPT_LINE: if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG);
From: Zhang Yi yi.zhang@huawei.com
commit 9bf3d20331295b1ecb81f4ed9ef358c51699a050 upstream.
The block number in the quota tree on disk should be smaller than the v2_disk_dqinfo.dqi_blocks. If the quota file was corrupted, we may be allocating an 'allocated' block and that would lead to a loop in a tree, which will probably trigger oops later. This patch adds a check for the block number in the quota tree to prevent such potential issue.
Link: https://lore.kernel.org/r/20211008093821.1001186-2-yi.zhang@huawei.com Signed-off-by: Zhang Yi yi.zhang@huawei.com Cc: stable@kernel.org Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/quota/quota_tree.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
--- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c @@ -479,6 +479,13 @@ static int remove_tree(struct qtree_mem_ goto out_buf; } newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); + if (newblk < QT_TREEOFF || newblk >= info->dqi_blocks) { + quota_error(dquot->dq_sb, "Getting block too big (%u >= %u)", + newblk, info->dqi_blocks); + ret = -EUCLEAN; + goto out_buf; + } + if (depth == info->dqi_qtree_depth - 1) { ret = free_dqentry(info, dquot, newblk); newblk = 0; @@ -578,6 +585,13 @@ static loff_t find_tree_dqentry(struct q blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); if (!blk) /* No reference? */ goto out_buf; + if (blk < QT_TREEOFF || blk >= info->dqi_blocks) { + quota_error(dquot->dq_sb, "Getting block too big (%u >= %u)", + blk, info->dqi_blocks); + ret = -EUCLEAN; + goto out_buf; + } + if (depth < info->dqi_qtree_depth - 1) ret = find_tree_dqentry(info, dquot, blk, depth+1); else
From: Zhang Yi yi.zhang@huawei.com
commit d0e36a62bd4c60c09acc40e06ba4831a4d0bc75b upstream.
Fix the error path in free_dqentry(), pass out the error number if the block to free is not correct.
Fixes: 1ccd14b9c271 ("quota: Split off quota tree handling into a separate file") Link: https://lore.kernel.org/r/20211008093821.1001186-3-yi.zhang@huawei.com Signed-off-by: Zhang Yi yi.zhang@huawei.com Cc: stable@kernel.org Signed-off-by: Jan Kara jack@suse.cz Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/quota/quota_tree.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c @@ -414,6 +414,7 @@ static int free_dqentry(struct qtree_mem quota_error(dquot->dq_sb, "Quota structure has offset to " "other block (%u) than it should (%u)", blk, (uint)(dquot->dq_off >> info->dqi_blocksize_bits)); + ret = -EIO; goto out_buf; } ret = read_blk(info, blk, buf);
From: Shyam Prasad N sprasad@microsoft.com
commit 7be3248f313930ff3d3436d4e9ddbe9fccc1f541 upstream.
We generally rely on a bunch of factors to differentiate between servers. For example, IP address, port etc.
For certain server types (like Azure), it is important to make sure that the server hostname matches too, even if the both hostnames currently resolve to the same IP address.
Signed-off-by: Shyam Prasad N sprasad@microsoft.com Cc: stable@vger.kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/connect.c | 19 +++++++++++-------- fs/cifs/fs_context.c | 8 ++++++++ fs/cifs/fs_context.h | 1 + 3 files changed, 20 insertions(+), 8 deletions(-)
--- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -794,7 +794,6 @@ static void clean_demultiplex_info(struc */ }
- kfree(server->hostname); kfree(server);
length = atomic_dec_return(&tcpSesAllocCount); @@ -1235,6 +1234,9 @@ static int match_server(struct TCP_Serve if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) return 0;
+ if (strcasecmp(server->hostname, ctx->server_hostname)) + return 0; + if (!match_address(server, addr, (struct sockaddr *)&ctx->srcaddr)) return 0; @@ -1336,6 +1338,7 @@ cifs_put_tcp_session(struct TCP_Server_I kfree(server->session_key.response); server->session_key.response = NULL; server->session_key.len = 0; + kfree(server->hostname);
task = xchg(&server->tsk, NULL); if (task) @@ -1361,14 +1364,15 @@ cifs_get_tcp_session(struct smb3_fs_cont goto out_err; }
+ tcp_ses->hostname = kstrdup(ctx->server_hostname, GFP_KERNEL); + if (!tcp_ses->hostname) { + rc = -ENOMEM; + goto out_err; + } + tcp_ses->ops = ctx->ops; tcp_ses->vals = ctx->vals; cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); - tcp_ses->hostname = extract_hostname(ctx->UNC); - if (IS_ERR(tcp_ses->hostname)) { - rc = PTR_ERR(tcp_ses->hostname); - goto out_err_crypto_release; - }
tcp_ses->conn_id = atomic_inc_return(&tcpSesNextId); tcp_ses->noblockcnt = ctx->rootfs; @@ -1497,8 +1501,7 @@ out_err_crypto_release:
out_err: if (tcp_ses) { - if (!IS_ERR(tcp_ses->hostname)) - kfree(tcp_ses->hostname); + kfree(tcp_ses->hostname); if (tcp_ses->ssocket) sock_release(tcp_ses->ssocket); kfree(tcp_ses); --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -318,6 +318,7 @@ smb3_fs_context_dup(struct smb3_fs_conte DUP_CTX_STR(mount_options); DUP_CTX_STR(username); DUP_CTX_STR(password); + DUP_CTX_STR(server_hostname); DUP_CTX_STR(UNC); DUP_CTX_STR(source); DUP_CTX_STR(domainname); @@ -456,6 +457,11 @@ smb3_parse_devname(const char *devname, if (!pos) return -EINVAL;
+ /* record the server hostname */ + ctx->server_hostname = kstrndup(devname + 2, pos - devname - 2, GFP_KERNEL); + if (!ctx->server_hostname) + return -ENOMEM; + /* skip past delimiter */ ++pos;
@@ -1496,6 +1502,8 @@ smb3_cleanup_fs_context_contents(struct ctx->username = NULL; kfree_sensitive(ctx->password); ctx->password = NULL; + kfree(ctx->server_hostname); + ctx->server_hostname = NULL; kfree(ctx->UNC); ctx->UNC = NULL; kfree(ctx->source); --- a/fs/cifs/fs_context.h +++ b/fs/cifs/fs_context.h @@ -166,6 +166,7 @@ struct smb3_fs_context { char *password; char *domainname; char *source; + char *server_hostname; char *UNC; char *nodename; char *iocharset; /* local code page for mapping to and from Unicode */
From: Paulo Alcantara pc@cjr.nz
commit 4ac0536f8874a903a72bddc57eb88db774261e3a upstream.
With commit 506c1da44fee ("cifs: use the expiry output of dns_query to schedule next resolution") and after triggering the first reconnect, the next async dns resolution of tcp server's hostname would be scheduled based on dns_resolver's key expiry default, which happens to default to 5s on most systems that use key.dns_resolver for upcall.
As per key.dns_resolver.conf(5):
default_ttl=<number> The number of seconds to set as the expiration on a cached record. This will be overridden if the program manages to re- trieve TTL information along with the addresses (if, for exam- ple, it accesses the DNS directly). The default is 5 seconds. The value must be in the range 1 to INT_MAX.
Make the next async dns resolution no shorter than 120s as we do not want to be upcalling too often.
Cc: stable@vger.kernel.org Fixes: 506c1da44fee ("cifs: use the expiry output of dns_query to schedule next resolution") Signed-off-by: Paulo Alcantara (SUSE) pc@cjr.nz Reviewed-by: Shyam Prasad N sprasad@microsoft.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/cifsglob.h | 3 ++- fs/cifs/connect.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-)
--- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -74,7 +74,8 @@ #define SMB_ECHO_INTERVAL_MAX 600 #define SMB_ECHO_INTERVAL_DEFAULT 60
-/* dns resolution interval in seconds */ +/* dns resolution intervals in seconds */ +#define SMB_DNS_RESOLVE_INTERVAL_MIN 120 #define SMB_DNS_RESOLVE_INTERVAL_DEFAULT 600
/* maximum number of PDUs in one compound */ --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -115,7 +115,7 @@ static int reconn_set_ipaddr_from_hostna * To make sure we don't use the cached entry, retry 1s * after expiry. */ - ttl = (expiry - now + 1); + ttl = max_t(unsigned long, expiry - now, SMB_DNS_RESOLVE_INTERVAL_MIN) + 1; } rc = !rc ? -1 : 0;
From: Robert Marko robert.marko@sartura.hr
commit 5dc6dafe62099ade0e7232ce9db4013b7673d860 upstream.
MFD_SIMPLE_MFD_I2C should select the MFD_CORE to a prevent build error:
aarch64-linux-ld: drivers/mfd/simple-mfd-i2c.o: in function `simple_mfd_i2c_probe': drivers/mfd/simple-mfd-i2c.c:55: undefined reference to `devm_mfd_add_devices'
Cc: stable@vger.kernel.org Fixes: c753ea31781aa ("mfd: simple-mfd-i2c: Add support for registering devices via MFD cells") Signed-off-by: Robert Marko robert.marko@sartura.hr Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20211102100420.112215-1-robert.marko@sartura.hr Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mfd/Kconfig | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1194,6 +1194,7 @@ config MFD_SI476X_CORE config MFD_SIMPLE_MFD_I2C tristate depends on I2C + select MFD_CORE select REGMAP_I2C help This driver creates a single register map with the intention for it
From: Yang Yingliang yangyingliang@huawei.com
commit c7892ae13e461ed20154321eb792e07ebe38f5b3 upstream.
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff888020a7a680 (size 64): comm "i2c-mcp23018-41", pid 23090, jiffies 4295160544 (age 8.680s) hex dump (first 32 bytes): 00 48 d3 1e 80 88 ff ff 00 1a 56 c1 ff ff ff ff .H........V..... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<0000000083c79b35>] kmem_cache_alloc_trace+0x16d/0x360 [<0000000051803c95>] pinctrl_init_controller+0x6ed/0xb70 [<0000000064346707>] pinctrl_register+0x27/0x80 [<0000000029b0e186>] devm_pinctrl_register+0x5b/0xe0 [<00000000391f5a3e>] mcp23s08_probe_one+0x968/0x118a [pinctrl_mcp23s08] [<000000006112c039>] mcp230xx_probe+0x266/0x560 [pinctrl_mcp23s08_i2c]
If pinctrl_claim_hogs() fails, the 'pindesc' allocated in pinctrl_register_one_pin() need be freed.
Cc: stable@vger.kernel.org Reported-by: Hulk Robot hulkci@huawei.com Fixes: 950b0d91dc10 ("pinctrl: core: Fix regression caused by delayed work for hogs") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211022014323.1156924-1-yangyingliang@huawei.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pinctrl/core.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -2100,6 +2100,8 @@ int pinctrl_enable(struct pinctrl_dev *p if (error) { dev_err(pctldev->dev, "could not claim hogs: %i\n", error); + pinctrl_free_pindescs(pctldev, pctldev->desc->pins, + pctldev->desc->npins); mutex_destroy(&pctldev->mutex); kfree(pctldev);
From: Tao Zhang quic_taozha@quicinc.com
commit 692c9a499b286ea478f41b23a91fe3873b9e1326 upstream.
The input parameter of the function pm_runtime_put should be the same in the function cti_enable_hw and cti_disable_hw. The correct parameter to use here should be dev->parent.
Signed-off-by: Tao Zhang quic_taozha@quicinc.com Reviewed-by: Leo Yan leo.yan@linaro.org Fixes: 835d722ba10a ("coresight: cti: Initial CoreSight CTI Driver") Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/1629365377-5937-1-git-send-email-quic_taozha@quici... Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/coresight/coresight-cti-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -175,7 +175,7 @@ static int cti_disable_hw(struct cti_drv coresight_disclaim_device_unlocked(csdev); CS_LOCK(drvdata->base); spin_unlock(&drvdata->spinlock); - pm_runtime_put(dev); + pm_runtime_put(dev->parent); return 0;
/* not disabled this call */
From: Suzuki K Poulose suzuki.poulose@arm.com
commit bb5293e334af51b19b62d8bef1852ea13e935e9b upstream.
The TRBE driver wrongly treats the aux private data as the TRBE driver specific buffer for a given perf handle, while it is the ETM PMU's event specific data. Fix this by correcting the instance to use appropriate helper.
Cc: stable stable@vger.kernel.org Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver") Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Reviewed-by: Anshuman Khandual anshuman.khandual@arm.com Link: https://lore.kernel.org/r/20210921134121.2423546-2-suzuki.poulose@arm.com [Fixed 13 character SHA down to 12] Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/coresight/coresight-trbe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -366,7 +366,7 @@ static unsigned long __trbe_normal_offse
static unsigned long trbe_normal_offset(struct perf_output_handle *handle) { - struct trbe_buf *buf = perf_get_aux(handle); + struct trbe_buf *buf = etm_perf_sink_config(handle); u64 limit = __trbe_normal_offset(handle); u64 head = PERF_IDX2OFF(handle->head, buf);
From: Suzuki K Poulose suzuki.poulose@arm.com
commit a08025b3fe56185290a1ea476581f03ca733f967 upstream.
If a CPU is offline during the driver init, we could end up causing a kernel crash trying to register the coresight device for the TRBE instance. The trbe_cpudata for the TRBE instance is initialized only when it is probed. Otherwise, we could end up dereferencing a NULL cpudata->drvdata.
e.g:
[ 0.149999] coresight ete0: CPU0: ete v1.1 initialized [ 0.149999] coresight-etm4x ete_1: ETM arch init failed [ 0.149999] coresight-etm4x: probe of ete_1 failed with error -22 [ 0.150085] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050 [ 0.150085] Mem abort info: [ 0.150085] ESR = 0x96000005 [ 0.150085] EC = 0x25: DABT (current EL), IL = 32 bits [ 0.150085] SET = 0, FnV = 0 [ 0.150085] EA = 0, S1PTW = 0 [ 0.150085] Data abort info: [ 0.150085] ISV = 0, ISS = 0x00000005 [ 0.150085] CM = 0, WnR = 0 [ 0.150085] [0000000000000050] user address but active_mm is swapper [ 0.150085] Internal error: Oops: 96000005 [#1] PREEMPT SMP [ 0.150085] Modules linked in: [ 0.150085] Hardware name: FVP Base RevC (DT) [ 0.150085] pstate: 00800009 (nzcv daif -PAN +UAO -TCO BTYPE=--) [ 0.150155] pc : arm_trbe_register_coresight_cpu+0x74/0x144 [ 0.150155] lr : arm_trbe_register_coresight_cpu+0x48/0x144 ...
[ 0.150237] Call trace: [ 0.150237] arm_trbe_register_coresight_cpu+0x74/0x144 [ 0.150237] arm_trbe_device_probe+0x1c0/0x2d8 [ 0.150259] platform_drv_probe+0x94/0xbc [ 0.150259] really_probe+0x1bc/0x4a8 [ 0.150266] driver_probe_device+0x7c/0xb8 [ 0.150266] device_driver_attach+0x6c/0xac [ 0.150266] __driver_attach+0xc4/0x148 [ 0.150266] bus_for_each_dev+0x7c/0xc8 [ 0.150266] driver_attach+0x24/0x30 [ 0.150266] bus_add_driver+0x100/0x1e0 [ 0.150266] driver_register+0x78/0x110 [ 0.150266] __platform_driver_register+0x44/0x50 [ 0.150266] arm_trbe_init+0x28/0x84 [ 0.150266] do_one_initcall+0x94/0x2bc [ 0.150266] do_initcall_level+0xa4/0x158 [ 0.150266] do_initcalls+0x54/0x94 [ 0.150319] do_basic_setup+0x24/0x30 [ 0.150319] kernel_init_freeable+0xe8/0x14c [ 0.150319] kernel_init+0x14/0x18c [ 0.150319] ret_from_fork+0x10/0x30 [ 0.150319] Code: f94012c8 b0004ce2 9134a442 52819801 (f9402917) [ 0.150319] ---[ end trace d23e0cfe5098535e ]--- [ 0.150346] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
Fix this by skipping the step, if we are unable to probe the CPU.
Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver") Reported-by: Bransilav Rankov branislav.rankov@arm.com Cc: Anshuman Khandual anshuman.khandual@arm.com Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Mike Leach mike.leach@linaro.org Cc: Leo Yan leo.yan@linaro.org Cc: stable stable@vger.kernel.org Tested-by: Branislav Rankov branislav.rankov@arm.com Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Reviewed-by: Anshuman Khandual anshuman.khandual@arm.com Link: https://lore.kernel.org/r/20211014142238.2221248-1-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hwtracing/coresight/coresight-trbe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -869,6 +869,10 @@ static void arm_trbe_register_coresight_ if (WARN_ON(trbe_csdev)) return;
+ /* If the TRBE was not probed on the CPU, we shouldn't be here */ + if (WARN_ON(!cpudata->drvdata)) + return; + dev = &cpudata->drvdata->pdev->dev; desc.name = devm_kasprintf(dev, GFP_KERNEL, "trbe%d", cpu); if (!desc.name) @@ -950,7 +954,9 @@ static int arm_trbe_probe_coresight(stru return -ENOMEM;
for_each_cpu(cpu, &drvdata->supported_cpus) { - smp_call_function_single(cpu, arm_trbe_probe_cpu, drvdata, 1); + /* If we fail to probe the CPU, let us defer it to hotplug callbacks */ + if (smp_call_function_single(cpu, arm_trbe_probe_cpu, drvdata, 1)) + continue; if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) arm_trbe_register_coresight_cpu(drvdata, cpu); if (cpumask_test_cpu(cpu, &drvdata->supported_cpus))
From: Yang Yingliang yangyingliang@huawei.com
commit 2c0ad3f0cc04dec489552a21b80cd6d708bea96d upstream.
Check return value of kstrdup_const() in iio_buffer_wrap_attr(), or it will cause null-ptr-deref in kernfs_name_hash() when calling device_add() as follows:
BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:strlen+0x0/0x20 Call Trace: kernfs_name_hash+0x22/0x110 kernfs_find_ns+0x11d/0x390 kernfs_remove_by_name_ns+0x3b/0xb0 remove_files.isra.1+0x7b/0x190 internal_create_group+0x7f1/0xbb0 internal_create_groups+0xa3/0x150 device_add+0x8f0/0x2020 cdev_device_add+0xc3/0x160 __iio_device_register+0x1427/0x1b40 [industrialio] __devm_iio_device_register+0x22/0x80 [industrialio] adjd_s311_probe+0x195/0x200 [adjd_s311] i2c_device_probe+0xa07/0xbb0
Reported-by: Hulk Robot hulkci@huawei.com Fixes: 15097c7a1adc ("iio: buffer: wrap all buffer attributes into iio_dev_attr") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211013040438.1689277-1-yangyingliang@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-buffer.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1312,6 +1312,11 @@ static struct attribute *iio_buffer_wrap iio_attr->buffer = buffer; memcpy(&iio_attr->dev_attr, dattr, sizeof(iio_attr->dev_attr)); iio_attr->dev_attr.attr.name = kstrdup_const(attr->name, GFP_KERNEL); + if (!iio_attr->dev_attr.attr.name) { + kfree(iio_attr); + return NULL; + } + sysfs_attr_init(&iio_attr->dev_attr.attr);
list_add(&iio_attr->l, &buffer->buffer_attr_list);
From: Yang Yingliang yangyingliang@huawei.com
commit 486a25084155bf633768c26f022201c051d6fd95 upstream.
When 'iio_dev_opaque->buffer_ioctl_handler' alloc fails in iio_buffers_alloc_sysfs_and_mask(), the 'attrs' allocated in iio_buffer_register_legacy_sysfs_groups() will be leaked:
unreferenced object 0xffff888108568d00 (size 128): comm "88", pid 2014, jiffies 4294963294 (age 26.920s) hex dump (first 32 bytes): 80 3e da 02 80 88 ff ff 00 3a da 02 80 88 ff ff .>.......:...... 00 35 da 02 80 88 ff ff 00 38 da 02 80 88 ff ff .5.......8...... backtrace: [<0000000095a9e51e>] __kmalloc+0x1a3/0x2f0 [<00000000faa3735e>] iio_buffers_alloc_sysfs_and_mask+0xfa3/0x1480 [industrialio] [<00000000a46384dc>] __iio_device_register+0x52e/0x1b40 [industrialio] [<00000000210af05e>] __devm_iio_device_register+0x22/0x80 [industrialio] [<00000000730d7b41>] adjd_s311_probe+0x195/0x200 [adjd_s311] [<00000000c0f70eb9>] i2c_device_probe+0xa07/0xbb0
The iio_buffer_register_legacy_sysfs_groups() is called in __iio_buffer_alloc_sysfs_and_mask(), so move the iio_buffer_unregister_legacy_sysfs_groups() into __iio_buffer_free_sysfs_and_mask(), then the memory will be freed.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: d9a625744ed0 ("iio: core: merge buffer/ & scan_elements/ attributes") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211018063718.1971240-1-yangyingliang@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-buffer.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
--- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1588,8 +1588,12 @@ error_cleanup_dynamic: return ret; }
-static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer) +static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer, + struct iio_dev *indio_dev, + int index) { + if (index == 0) + iio_buffer_unregister_legacy_sysfs_groups(indio_dev); bitmap_free(buffer->scan_mask); kfree(buffer->buffer_group.name); kfree(buffer->buffer_group.attrs); @@ -1643,7 +1647,7 @@ int iio_buffers_alloc_sysfs_and_mask(str error_unwind_sysfs_and_mask: for (; unwind_idx >= 0; unwind_idx--) { buffer = iio_dev_opaque->attached_buffers[unwind_idx]; - __iio_buffer_free_sysfs_and_mask(buffer); + __iio_buffer_free_sysfs_and_mask(buffer, indio_dev, unwind_idx); } return ret; } @@ -1660,11 +1664,9 @@ void iio_buffers_free_sysfs_and_mask(str iio_device_ioctl_handler_unregister(iio_dev_opaque->buffer_ioctl_handler); kfree(iio_dev_opaque->buffer_ioctl_handler);
- iio_buffer_unregister_legacy_sysfs_groups(indio_dev); - for (i = iio_dev_opaque->attached_buffers_cnt - 1; i >= 0; i--) { buffer = iio_dev_opaque->attached_buffers[i]; - __iio_buffer_free_sysfs_and_mask(buffer); + __iio_buffer_free_sysfs_and_mask(buffer, indio_dev, i); } }
From: Yang Yingliang yangyingliang@huawei.com
commit 9a2ff8009e53296e47de72d5af0bc31cd53274ff upstream.
When iio_buffer_wrap_attr() returns NULL or buffer->buffer_group.name alloc fails, the 'attr' which is allocated in __iio_buffer_alloc_sysfs_and_mask() is not freed, and cause memory leak.
unreferenced object 0xffff888014882a00 (size 64): comm "i2c-adjd_s311-8", pid 424, jiffies 4294907737 (age 44.396s) hex dump (first 32 bytes): 00 0f 8a 15 80 88 ff ff 00 0e 8a 15 80 88 ff ff ................ 80 04 8a 15 80 88 ff ff 80 05 8a 15 80 88 ff ff ................ backtrace: [<0000000021752e67>] __kmalloc+0x1af/0x3c0 [<0000000043e8305c>] iio_buffers_alloc_sysfs_and_mask+0xe73/0x1570 [industrialio] [<00000000b7aa5a17>] __iio_device_register+0x483/0x1a30 [industrialio] [<000000003fa0fb2f>] __devm_iio_device_register+0x23/0x90 [industrialio] [<000000003ab040cf>] adjd_s311_probe+0x19c/0x200 [adjd_s311] [<0000000080458969>] i2c_device_probe+0xa31/0xbe0 [<00000000e20678ad>] really_probe+0x299/0xc30 [<000000006bea9b27>] __driver_probe_device+0x357/0x500 [<00000000e1df10d4>] driver_probe_device+0x4e/0x140 [<0000000003661beb>] __device_attach_driver+0x257/0x340 [<000000005bb4aa26>] bus_for_each_drv+0x166/0x1e0 [<00000000272c5236>] __device_attach+0x272/0x420 [<00000000d52a96ae>] bus_probe_device+0x1eb/0x2a0 [<00000000129f7737>] device_add+0xbf0/0x1f90 [<000000005eed4e52>] i2c_new_client_device+0x622/0xb20 [<00000000b85a9c43>] new_device_store+0x1fa/0x420
This patch fix to free it before the error return.
Reported-by: Hulk Robot hulkci@huawei.com Fixes: 15097c7a1adc ("iio: buffer: wrap all buffer attributes into iio_dev_attr") Fixes: d9a625744ed0 ("iio: core: merge buffer/ & scan_elements/ attributes") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211013094343.315275-1-yangyingliang@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-buffer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1536,6 +1536,7 @@ static int __iio_buffer_alloc_sysfs_and_ sizeof(struct attribute *) * buffer_attrcount);
buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs); + buffer->buffer_group.attrs = attr;
for (i = 0; i < buffer_attrcount; i++) { struct attribute *wrapped; @@ -1543,7 +1544,7 @@ static int __iio_buffer_alloc_sysfs_and_ wrapped = iio_buffer_wrap_attr(buffer, attr[i]); if (!wrapped) { ret = -ENOMEM; - goto error_free_scan_mask; + goto error_free_buffer_attrs; } attr[i] = wrapped; } @@ -1558,8 +1559,6 @@ static int __iio_buffer_alloc_sysfs_and_ goto error_free_buffer_attrs; }
- buffer->buffer_group.attrs = attr; - ret = iio_device_register_sysfs_group(indio_dev, &buffer->buffer_group); if (ret) goto error_free_buffer_attr_group_name;
From: Yang Yingliang yangyingliang@huawei.com
commit 604faf9a2ecd1addcc0c10a47e5aaef3c4d4fd6b upstream.
If the second iio_device_register_sysfs_group() fails, 'legacy_buffer_group.attrs' need be freed too or it will cause memory leak:
unreferenced object 0xffff888003618280 (size 64): comm "xrun", pid 357, jiffies 4294907259 (age 22.296s) hex dump (first 32 bytes): 80 f6 8c 03 80 88 ff ff 80 fb 8c 03 80 88 ff ff ................ 00 f9 8c 03 80 88 ff ff 80 fc 8c 03 80 88 ff ff ................ backtrace: [<00000000076bfd43>] __kmalloc+0x1a3/0x2f0 [<00000000c32e4886>] iio_buffers_alloc_sysfs_and_mask+0xc31/0x1290 [industrialio]
Reported-by: Hulk Robot hulkci@huawei.com Fixes: d9a625744ed0 ("iio: core: merge buffer/ & scan_elements/ attributes") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211013144242.1685060-1-yangyingliang@huawei.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/industrialio-buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1367,10 +1367,10 @@ static int iio_buffer_register_legacy_sy
return 0;
-error_free_buffer_attrs: - kfree(iio_dev_opaque->legacy_buffer_group.attrs); error_free_scan_el_attrs: kfree(iio_dev_opaque->legacy_scan_el_group.attrs); +error_free_buffer_attrs: + kfree(iio_dev_opaque->legacy_buffer_group.attrs);
return ret; }
From: Mihail Chindris mihail.chindris@analog.com
commit d9de0fbdeb0103a204055efb69cb5cc8f5f12a6a upstream.
In the documentation the name for the property is output-range-microvolts which is a standard name, therefore this name must be used.
Fixes: fd9373e41b9ba ("iio: dac: ad5766: add driver support for AD5766") Signed-off-by: Mihail Chindris mihail.chindris@analog.com Reviewed-by: Alexandru Ardelean ardeleanalex@gmail.com Link: https://lore.kernel.org/r/20211007080035.2531-5-mihail.chindris@analog.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/dac/ad5766.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/iio/dac/ad5766.c +++ b/drivers/iio/dac/ad5766.c @@ -503,13 +503,13 @@ static int ad5766_get_output_range(struc int i, ret, min, max, tmp[2];
ret = device_property_read_u32_array(&st->spi->dev, - "output-range-voltage", + "output-range-microvolts", tmp, 2); if (ret) return ret;
- min = tmp[0] / 1000; - max = tmp[1] / 1000; + min = tmp[0] / 1000000; + max = tmp[1] / 1000000; for (i = 0; i < ARRAY_SIZE(ad5766_span_tbl); i++) { if (ad5766_span_tbl[i].min != min || ad5766_span_tbl[i].max != max)
From: Pekka Korpinen pekka.korpinen@iki.fi
commit 558df982d4ead9cac628153d0d7b60feae05ddc8 upstream.
On success i2c_master_send() returns the number of bytes written. The call from iio_write_channel_info(), however, expects the return value to be zero on success.
This bug causes incorrect consumption of the sysfs buffer in iio_write_channel_info(). When writing more than two characters to out_voltage0_raw, the ad5446 write handler is called multiple times causing unexpected behavior.
Fixes: 3ec36a2cf0d5 ("iio:ad5446: Add support for I2C based DACs") Signed-off-by: Pekka Korpinen pekka.korpinen@iki.fi Link: https://lore.kernel.org/r/20210929185755.2384-1-pekka.korpinen@iki.fi Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/dac/ad5446.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -531,8 +531,15 @@ static int ad5622_write(struct ad5446_st { struct i2c_client *client = to_i2c_client(st->dev); __be16 data = cpu_to_be16(val); + int ret;
- return i2c_master_send(client, (char *)&data, sizeof(data)); + ret = i2c_master_send(client, (char *)&data, sizeof(data)); + if (ret < 0) + return ret; + if (ret != sizeof(data)) + return -EIO; + + return 0; }
/*
From: Nuno Sá nuno.sa@analog.com
commit 26df977a909f818b7d346b3990735513e7e0bf93 upstream.
The bindings file for this driver is defining the property as 'reg' but the driver was reading it with the 'num' name. The bindings actually had the 'num' property when added in commit ea52c21268e6 ("dt-bindings: iio: dac: Add docs for AD5770R DAC") and then changed it to 'reg' in commit 2cf3818f18b2 ("dt-bindings: iio: dac: AD5570R fix bindings errors"). However, both these commits landed in v5.7 so the assumption is that either 'num' is not being used or if it is, the validations were not done.
Anyways, if someone comes back yelling about this, we might just support both of the properties in the future. Not ideal, but that's life...
Fixes: 2cf3818f18b2 ("dt-bindings: iio: dac: AD5570R fix bindings errors") Signed-off-by: Nuno Sá nuno.sa@analog.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Link: https://lore.kernel.org/r/20210818080525.62790-1-nuno.sa@analog.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/iio/dac/ad5770r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/iio/dac/ad5770r.c +++ b/drivers/iio/dac/ad5770r.c @@ -522,7 +522,7 @@ static int ad5770r_channel_config(struct return -EINVAL;
device_for_each_child_node(&st->spi->dev, child) { - ret = fwnode_property_read_u32(child, "num", &num); + ret = fwnode_property_read_u32(child, "reg", &num); if (ret) goto err_child_out; if (num >= AD5770R_MAX_CHANNELS) {
From: Mihail Chindris mihail.chindris@analog.com
commit 8fc4f038fa832ec3543907fdcbe1334e1b0a8950 upstream.
A correct value for output-range-microvolts is -5 to 5 Volts not -5 to 5 milivolts
Fixes: e904cc899293f ("dt-bindings: iio: dac: AD5766 yaml documentation") Signed-off-by: Mihail Chindris mihail.chindris@analog.com Reviewed-by: Alexandru Ardelean ardeleanalex@gmail.com Link: https://lore.kernel.org/r/20211007080035.2531-6-mihail.chindris@analog.com Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml +++ b/Documentation/devicetree/bindings/iio/dac/adi,ad5766.yaml @@ -54,7 +54,7 @@ examples:
ad5766@0 { compatible = "adi,ad5766"; - output-range-microvolts = <(-5000) 5000>; + output-range-microvolts = <(-5000000) 5000000>; reg = <0>; spi-cpol; spi-max-frequency = <1000000>;
From: Wang Hai wanghai38@huawei.com
commit 910c996335c37552ee30fcb837375b808bb4f33b upstream.
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff888258228440 (size 64): comm "kworker/7:2", pid 2005, jiffies 4294989509 (age 824.540s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<ffffffff8167939c>] slab_post_alloc_hook+0x9c/0x490 [<ffffffff8167f627>] kmem_cache_alloc_trace+0x1f7/0x470 [<ffffffffa02ac0e4>] keyspan_port_probe+0xa4/0x5d0 [keyspan] [<ffffffffa0294c07>] usb_serial_device_probe+0x97/0x1d0 [usbserial] [<ffffffff82b50ca7>] really_probe+0x167/0x460 [<ffffffff82b51099>] __driver_probe_device+0xf9/0x180 [<ffffffff82b51173>] driver_probe_device+0x53/0x130 [<ffffffff82b516f5>] __device_attach_driver+0x105/0x130 [<ffffffff82b4cfe9>] bus_for_each_drv+0x129/0x190 [<ffffffff82b50a69>] __device_attach+0x1c9/0x270 [<ffffffff82b518d0>] device_initial_probe+0x20/0x30 [<ffffffff82b4f062>] bus_probe_device+0x142/0x160 [<ffffffff82b4a4e9>] device_add+0x829/0x1300 [<ffffffffa0295fda>] usb_serial_probe.cold+0xc9b/0x14ac [usbserial] [<ffffffffa02266aa>] usb_probe_interface+0x1aa/0x3c0 [usbcore] [<ffffffff82b50ca7>] really_probe+0x167/0x460
If keyspan_port_probe() fails to allocate memory for an out_buffer[i] or in_buffer[i], the previously allocated memory for out_buffer or in_buffer needs to be freed on the error handling path, otherwise a memory leak will result.
Fixes: bad41a5bf177 ("USB: keyspan: fix port DMA-buffer allocations") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wang Hai wanghai38@huawei.com Link: https://lore.kernel.org/r/20211015085543.1203011-1-wanghai38@huawei.com Cc: stable@vger.kernel.org # 3.12 Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/keyspan.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
--- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2890,22 +2890,22 @@ static int keyspan_port_probe(struct usb for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i) { p_priv->in_buffer[i] = kzalloc(IN_BUFLEN, GFP_KERNEL); if (!p_priv->in_buffer[i]) - goto err_in_buffer; + goto err_free_in_buffer; }
for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i) { p_priv->out_buffer[i] = kzalloc(OUT_BUFLEN, GFP_KERNEL); if (!p_priv->out_buffer[i]) - goto err_out_buffer; + goto err_free_out_buffer; }
p_priv->inack_buffer = kzalloc(INACK_BUFLEN, GFP_KERNEL); if (!p_priv->inack_buffer) - goto err_inack_buffer; + goto err_free_out_buffer;
p_priv->outcont_buffer = kzalloc(OUTCONT_BUFLEN, GFP_KERNEL); if (!p_priv->outcont_buffer) - goto err_outcont_buffer; + goto err_free_inack_buffer;
p_priv->device_details = d_details;
@@ -2951,15 +2951,14 @@ static int keyspan_port_probe(struct usb
return 0;
-err_outcont_buffer: +err_free_inack_buffer: kfree(p_priv->inack_buffer); -err_inack_buffer: +err_free_out_buffer: for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i) kfree(p_priv->out_buffer[i]); -err_out_buffer: +err_free_in_buffer: for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i) kfree(p_priv->in_buffer[i]); -err_in_buffer: kfree(p_priv);
return -ENOMEM;
From: Johan Hovold johan@kernel.org
commit 211cde4f5817dc88ef7f8f2fa286e57fbf14c8ee upstream.
Commit 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") added a hack to support SoCs where the UART reference clock can change behind the back of the driver but failed to add the proper locking.
First, make sure to take a reference to the tty struct to avoid dereferencing a NULL pointer if the clock change races with a hangup.
Second, the termios semaphore must be held during the update to prevent a racing termios change.
Fixes: 868f3ee6e452 ("serial: 8250: Add 8250 port clock update method") Fixes: c8dff3aa8241 ("serial: 8250: Skip uninitialized TTY port baud rate update") Cc: stable@vger.kernel.org # 5.9 Cc: Serge Semin Sergey.Semin@baikalelectronics.ru Tested-by: Serge Semin fancer.lancer@gmail.com Reviewed-by: Serge Semin fancer.lancer@gmail.com Acked-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211015111422.1027-2-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250_port.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 66374704747e..e4dd82fd7c2a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2696,21 +2696,32 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) { struct uart_8250_port *up = up_to_u8250p(port); + struct tty_port *tport = &port->state->port; unsigned int baud, quot, frac = 0; struct ktermios *termios; + struct tty_struct *tty; unsigned long flags;
- mutex_lock(&port->state->port.mutex); + tty = tty_port_tty_get(tport); + if (!tty) { + mutex_lock(&tport->mutex); + port->uartclk = uartclk; + mutex_unlock(&tport->mutex); + return; + } + + down_write(&tty->termios_rwsem); + mutex_lock(&tport->mutex);
if (port->uartclk == uartclk) goto out_lock;
port->uartclk = uartclk;
- if (!tty_port_initialized(&port->state->port)) + if (!tty_port_initialized(tport)) goto out_lock;
- termios = &port->state->port.tty->termios; + termios = &tty->termios;
baud = serial8250_get_baud_rate(port, termios, NULL); quot = serial8250_get_divisor(port, baud, &frac); @@ -2727,7 +2738,9 @@ void serial8250_update_uartclk(struct uart_port *port, unsigned int uartclk) serial8250_rpm_put(up);
out_lock: - mutex_unlock(&port->state->port.mutex); + mutex_unlock(&tport->mutex); + up_write(&tty->termios_rwsem); + tty_kref_put(tty); } EXPORT_SYMBOL_GPL(serial8250_update_uartclk);
From: Namjae Jeon linkinjeon@kernel.org
commit 5d2f0b1083eb158bdff01dd557e2c25046c0a7d2 upstream.
Steve French reported ksmbd set fixed value to volume serial field in FS_VOLUME_INFORMATION. Volume serial value needs to be set to a unique value for client fscache. This patch set crc value that is generated with share name, path name and netbios name to volume serial.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org # v5.15 Reported-by: Steve French smfrench@gmail.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/Kconfig | 1 + fs/ksmbd/server.c | 1 + fs/ksmbd/smb2pdu.c | 9 ++++++++- 3 files changed, 10 insertions(+), 1 deletion(-)
--- a/fs/ksmbd/Kconfig +++ b/fs/ksmbd/Kconfig @@ -19,6 +19,7 @@ config SMB_SERVER select CRYPTO_GCM select ASN1 select OID_REGISTRY + select CRC32 default n help Choose Y here if you want to allow SMB3 compliant clients --- a/fs/ksmbd/server.c +++ b/fs/ksmbd/server.c @@ -632,5 +632,6 @@ MODULE_SOFTDEP("pre: sha512"); MODULE_SOFTDEP("pre: aead2"); MODULE_SOFTDEP("pre: ccm"); MODULE_SOFTDEP("pre: gcm"); +MODULE_SOFTDEP("pre: crc32"); module_init(ksmbd_server_init) module_exit(ksmbd_server_exit) --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -4891,11 +4891,18 @@ static int smb2_get_info_filesystem(stru { struct filesystem_vol_info *info; size_t sz; + unsigned int serial_crc = 0;
info = (struct filesystem_vol_info *)(rsp->Buffer); info->VolumeCreationTime = 0; + serial_crc = crc32_le(serial_crc, share->name, + strlen(share->name)); + serial_crc = crc32_le(serial_crc, share->path, + strlen(share->path)); + serial_crc = crc32_le(serial_crc, ksmbd_netbios_name(), + strlen(ksmbd_netbios_name())); /* Taking dummy value of serial number*/ - info->SerialNumber = cpu_to_le32(0xbc3ac512); + info->SerialNumber = cpu_to_le32(serial_crc); len = smbConvertToUTF16((__le16 *)info->VolumeLabel, share->name, PATH_MAX, conn->local_nls, 0);
From: Jens Axboe axboe@kernel.dk
commit d3e3c102d107bb84251455a298cf475f24bab995 upstream.
We need to ensure that we serialize the stalled and hash bits with the wait_queue wait handler, or we could be racing with someone modifying the hashed state after we find it busy, but before we then give up and wait for it to be cleared. This can cause random delays or stalls when handling buffered writes for many files, where some of these files cause hash collisions between the worker threads.
Cc: stable@vger.kernel.org Reported-by: Daniel Black daniel@mariadb.org Fixes: e941894eae31 ("io-wq: make buffered file write hashed work map per-ctx") Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/io-wq.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
--- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -421,9 +421,10 @@ static inline unsigned int io_get_work_h return work->flags >> IO_WQ_HASH_SHIFT; }
-static void io_wait_on_hash(struct io_wqe *wqe, unsigned int hash) +static bool io_wait_on_hash(struct io_wqe *wqe, unsigned int hash) { struct io_wq *wq = wqe->wq; + bool ret = false;
spin_lock_irq(&wq->hash->wait.lock); if (list_empty(&wqe->wait.entry)) { @@ -431,9 +432,11 @@ static void io_wait_on_hash(struct io_wq if (!test_bit(hash, &wq->hash->map)) { __set_current_state(TASK_RUNNING); list_del_init(&wqe->wait.entry); + ret = true; } } spin_unlock_irq(&wq->hash->wait.lock); + return ret; }
static struct io_wq_work *io_get_next_work(struct io_wqe_acct *acct, @@ -473,14 +476,21 @@ static struct io_wq_work *io_get_next_wo }
if (stall_hash != -1U) { + bool unstalled; + /* * Set this before dropping the lock to avoid racing with new * work being added and clearing the stalled bit. */ set_bit(IO_ACCT_STALLED_BIT, &acct->flags); raw_spin_unlock(&wqe->lock); - io_wait_on_hash(wqe, stall_hash); + unstalled = io_wait_on_hash(wqe, stall_hash); raw_spin_lock(&wqe->lock); + if (unstalled) { + clear_bit(IO_ACCT_STALLED_BIT, &acct->flags); + if (wq_has_sleeper(&wqe->wq->hash->wait)) + wake_up(&wqe->wq->hash->wait); + } }
return NULL; @@ -562,8 +572,11 @@ get_next: io_wqe_enqueue(wqe, linked);
if (hash != -1U && !next_hashed) { + /* serialize hash clear with wake_up() */ + spin_lock_irq(&wq->hash->wait.lock); clear_bit(hash, &wq->hash->map); clear_bit(IO_ACCT_STALLED_BIT, &acct->flags); + spin_unlock_irq(&wq->hash->wait.lock); if (wq_has_sleeper(&wq->hash->wait)) wake_up(&wq->hash->wait); raw_spin_lock(&wqe->lock);
From: Pali Rohár pali@kernel.org
commit 32262e2e429cdb31f9e957e997d53458762931b7 upstream.
In most cases it is not possible to set exact baudrate value to hardware.
So fix reporting real baudrate value which was set to hardware via c_ospeed termios field. It can be retrieved by ioctl(TCGETS2) from userspace.
Real baudrate value is calculated from chosen hardware divisor and base clock. It is implemented in a new function serial8250_compute_baud_rate() which is inverse of serial8250_get_divisor() function.
With this change is fixed also UART timeout value (it is updated via uart_update_timeout() function), which is calculated from the now fixed baudrate value too.
Cc: stable@vger.kernel.org Signed-off-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/20210927093704.19768-1-pali@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250_port.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
--- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2584,6 +2584,19 @@ static unsigned int serial8250_get_divis return serial8250_do_get_divisor(port, baud, frac); }
+static unsigned int serial8250_compute_baud_rate(struct uart_port *port, + unsigned int quot) +{ + if ((port->flags & UPF_MAGIC_MULTIPLIER) && quot == 0x8001) + return port->uartclk / 4; + else if ((port->flags & UPF_MAGIC_MULTIPLIER) && quot == 0x8002) + return port->uartclk / 8; + else if (port->type == PORT_NPCM) + return DIV_ROUND_CLOSEST(port->uartclk - 2 * (quot + 2), 16 * (quot + 2)); + else + return DIV_ROUND_CLOSEST(port->uartclk, 16 * quot); +} + static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, tcflag_t c_cflag) { @@ -2725,11 +2738,14 @@ void serial8250_update_uartclk(struct ua
baud = serial8250_get_baud_rate(port, termios, NULL); quot = serial8250_get_divisor(port, baud, &frac); + baud = serial8250_compute_baud_rate(port, quot);
serial8250_rpm_get(up); spin_lock_irqsave(&port->lock, flags);
uart_update_timeout(port, termios->c_cflag, baud); + if (tty_termios_baud_rate(termios)) + tty_termios_encode_baud_rate(termios, baud, baud);
serial8250_set_divisor(port, baud, quot, frac); serial_port_out(port, UART_LCR, up->lcr); @@ -2763,6 +2779,7 @@ serial8250_do_set_termios(struct uart_po
baud = serial8250_get_baud_rate(port, termios, old); quot = serial8250_get_divisor(port, baud, &frac); + baud = serial8250_compute_baud_rate(port, quot);
/* * Ok, we're now changing the port state. Do it with
From: Johan Hovold johan@kernel.org
commit d02b006b29de14968ba4afa998bede0d55469e29 upstream.
This reverts commit 32262e2e429cdb31f9e957e997d53458762931b7.
The commit in question claims to determine the inverse of serial8250_get_divisor() but failed to notice that some drivers override the default implementation using a get_divisor() callback.
This means that the computed line-speed values can be completely wrong and results in regular TCSETS requests failing (the incorrect values would also be passed to any overridden set_divisor() callback).
Similarly, it also failed to honour the old (deprecated) ASYNC_SPD_FLAGS and would break applications relying on those when re-encoding the actual line speed.
There are also at least two quirks, UART_BUG_QUOT and an OMAP1510 workaround, which were happily ignored and that are now broken.
Finally, even if the offending commit were to be implemented correctly, this is a new feature and not something which should be backported to stable.
Cc: Pali Rohár pali@kernel.org Fixes: 32262e2e429c ("serial: 8250: Fix reporting real baudrate value in c_ospeed field") Cc: stable stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211007133146.28949-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/8250/8250_port.c | 17 ----------------- 1 file changed, 17 deletions(-)
--- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2584,19 +2584,6 @@ static unsigned int serial8250_get_divis return serial8250_do_get_divisor(port, baud, frac); }
-static unsigned int serial8250_compute_baud_rate(struct uart_port *port, - unsigned int quot) -{ - if ((port->flags & UPF_MAGIC_MULTIPLIER) && quot == 0x8001) - return port->uartclk / 4; - else if ((port->flags & UPF_MAGIC_MULTIPLIER) && quot == 0x8002) - return port->uartclk / 8; - else if (port->type == PORT_NPCM) - return DIV_ROUND_CLOSEST(port->uartclk - 2 * (quot + 2), 16 * (quot + 2)); - else - return DIV_ROUND_CLOSEST(port->uartclk, 16 * quot); -} - static unsigned char serial8250_compute_lcr(struct uart_8250_port *up, tcflag_t c_cflag) { @@ -2738,14 +2725,11 @@ void serial8250_update_uartclk(struct ua
baud = serial8250_get_baud_rate(port, termios, NULL); quot = serial8250_get_divisor(port, baud, &frac); - baud = serial8250_compute_baud_rate(port, quot);
serial8250_rpm_get(up); spin_lock_irqsave(&port->lock, flags);
uart_update_timeout(port, termios->c_cflag, baud); - if (tty_termios_baud_rate(termios)) - tty_termios_encode_baud_rate(termios, baud, baud);
serial8250_set_divisor(port, baud, quot, frac); serial_port_out(port, UART_LCR, up->lcr); @@ -2779,7 +2763,6 @@ serial8250_do_set_termios(struct uart_po
baud = serial8250_get_baud_rate(port, termios, old); quot = serial8250_get_divisor(port, baud, &frac); - baud = serial8250_compute_baud_rate(port, quot);
/* * Ok, we're now changing the port state. Do it with
From: Johan Hovold johan@kernel.org
commit 63b3e810eff65fb8587fcb26fa0b56802be12dcf upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Use the common control-message timeout defines for the five-second timeouts.
Fixes: 97a6f772f36b ("drivers: most: add USB adapter driver") Cc: stable@vger.kernel.org # 5.9 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211025115811.5410-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/most/most_usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/most/most_usb.c +++ b/drivers/most/most_usb.c @@ -149,7 +149,8 @@ static inline int drci_rd_reg(struct usb retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), DRCI_READ_REQ, req_type, 0x0000, - reg, dma_buf, sizeof(*dma_buf), 5 * HZ); + reg, dma_buf, sizeof(*dma_buf), + USB_CTRL_GET_TIMEOUT); *buf = le16_to_cpu(*dma_buf); kfree(dma_buf);
@@ -176,7 +177,7 @@ static inline int drci_wr_reg(struct usb reg, NULL, 0, - 5 * HZ); + USB_CTRL_SET_TIMEOUT); }
static inline int start_sync_ep(struct usb_device *usb_dev, u16 ep)
From: Johan Hovold johan@kernel.org
commit 79a4479a17b83310deb0b1a2a274fe5be12d2318 upstream.
USB control-message timeouts are specified in milliseconds and should specifically not vary with CONFIG_HZ.
Use the common control-message timeout define for the five-second timeout and drop the driver-specific one.
Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.") Cc: stable@vger.kernel.org # 2.6.21 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211025115159.4954-3-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/misc/iowarrior.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
--- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -99,10 +99,6 @@ struct iowarrior { /* globals */ /*--------------*/
-/* - * USB spec identifies 5 second timeouts. - */ -#define GET_TIMEOUT 5 #define USB_REQ_GET_REPORT 0x01 //#if 0 static int usb_get_report(struct usb_device *dev, @@ -114,7 +110,7 @@ static int usb_get_report(struct usb_dev USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, (type << 8) + id, inter->desc.bInterfaceNumber, buf, size, - GET_TIMEOUT*HZ); + USB_CTRL_GET_TIMEOUT); } //#endif
@@ -129,7 +125,7 @@ static int usb_set_report(struct usb_int USB_TYPE_CLASS | USB_RECIP_INTERFACE, (type << 8) + id, intf->cur_altsetting->desc.bInterfaceNumber, buf, - size, HZ); + size, 1000); }
/*---------------------*/
From: Johan Hovold johan@kernel.org
commit 9aaa81c3366e8393a62374e3a1c67c69edc07b8a upstream.
Chipidea core was calling the interrupt handler from non-IRQ context with interrupts enabled, something which can lead to a deadlock if there's an actual interrupt trying to take a lock that's already held (e.g. the controller lock in udc_irq()).
Add a wrapper that can be used to fake interrupts instead of calling the handler directly.
Fixes: 3ecb3e09b042 ("usb: chipidea: Use extcon framework for VBUS and ID detect") Fixes: 876d4e1e8298 ("usb: chipidea: core: add wakeup support for extcon") Cc: Peter Chen peter.chen@kernel.org Cc: stable@vger.kernel.org # 4.4 Signed-off-by: Johan Hovold johan@kernel.org Link: https://lore.kernel.org/r/20211021083447.20078-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/chipidea/core.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
--- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -514,7 +514,7 @@ int hw_device_reset(struct ci_hdrc *ci) return 0; }
-static irqreturn_t ci_irq(int irq, void *data) +static irqreturn_t ci_irq_handler(int irq, void *data) { struct ci_hdrc *ci = data; irqreturn_t ret = IRQ_NONE; @@ -567,6 +567,15 @@ static irqreturn_t ci_irq(int irq, void return ret; }
+static void ci_irq(struct ci_hdrc *ci) +{ + unsigned long flags; + + local_irq_save(flags); + ci_irq_handler(ci->irq, ci); + local_irq_restore(flags); +} + static int ci_cable_notifier(struct notifier_block *nb, unsigned long event, void *ptr) { @@ -576,7 +585,7 @@ static int ci_cable_notifier(struct noti cbl->connected = event; cbl->changed = true;
- ci_irq(ci->irq, ci); + ci_irq(ci); return NOTIFY_DONE; }
@@ -617,7 +626,7 @@ static int ci_usb_role_switch_set(struct if (cable) { cable->changed = true; cable->connected = false; - ci_irq(ci->irq, ci); + ci_irq(ci); spin_unlock_irqrestore(&ci->lock, flags); if (ci->wq && role != USB_ROLE_NONE) flush_workqueue(ci->wq); @@ -635,7 +644,7 @@ static int ci_usb_role_switch_set(struct if (cable) { cable->changed = true; cable->connected = true; - ci_irq(ci->irq, ci); + ci_irq(ci); } spin_unlock_irqrestore(&ci->lock, flags); pm_runtime_put_sync(ci->dev); @@ -1174,7 +1183,7 @@ static int ci_hdrc_probe(struct platform } }
- ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, + ret = devm_request_irq(dev, ci->irq, ci_irq_handler, IRQF_SHARED, ci->platdata->name, ci); if (ret) goto stop; @@ -1295,11 +1304,11 @@ static void ci_extcon_wakeup_int(struct
if (!IS_ERR(cable_id->edev) && ci->is_otg && (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) - ci_irq(ci->irq, ci); + ci_irq(ci);
if (!IS_ERR(cable_vbus->edev) && ci->is_otg && (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) - ci_irq(ci->irq, ci); + ci_irq(ci); }
static int ci_controller_resume(struct device *dev)
From: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm
commit 0cf48167b87e388fa1268c9fe6d2443ae7f43d8a upstream.
The gauge requires us to clear the status bits manually for some alerts to be properly dismissed. Previously the IRQ was configured to react only on falling edge, which wasn't technically correct (the ALRT line is active low), but it had a happy side-effect of preventing interrupt storms on uncleared alerts from happening.
Fixes: 7fbf6b731bca ("power: supply: max17042: Do not enforce (incorrect) interrupt trigger type") Cc: stable@vger.kernel.org Signed-off-by: Sebastian Krzyszkowiak sebastian.krzyszkowiak@puri.sm Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/power/supply/max17042_battery.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -880,6 +880,10 @@ static irqreturn_t max17042_thread_handl max17042_set_soc_threshold(chip, 1); }
+ /* we implicitly handle all alerts via power_supply_changed */ + regmap_clear_bits(chip->regmap, MAX17042_STATUS, + 0xFFFF & ~(STATUS_POR_BIT | STATUS_BST_BIT)); + power_supply_changed(chip->battery); return IRQ_HANDLED; }
From: Kai Vehmanen kai.vehmanen@linux.intel.com
commit c87761db2100677a69be551365105125d872af5b upstream.
In current code, the devres group for aggregate master is left open after call to component_master_add_*(). This leads to problems when the master does further managed allocations on its own. When any participating driver calls component_del(), this leads to immediate release of resources.
This came up when investigating a page fault occurring with i915 DRM driver unbind with 5.15-rc1 kernel. The following sequence occurs:
i915_pci_remove() -> intel_display_driver_unregister() -> i915_audio_component_cleanup() -> component_del() -> component.c:take_down_master() -> hdac_component_master_unbind() [via master->ops->unbind()] -> devres_release_group(master->parent, NULL)
With older kernels this has not caused issues, but with audio driver moving to use managed interfaces for more of its allocations, this no longer works. Devres log shows following to occur:
component_master_add_with_match() [ 126.886032] snd_hda_intel 0000:00:1f.3: DEVRES ADD 00000000323ccdc5 devm_component_match_release (24 bytes) [ 126.886045] snd_hda_intel 0000:00:1f.3: DEVRES ADD 00000000865cdb29 grp< (0 bytes) [ 126.886049] snd_hda_intel 0000:00:1f.3: DEVRES ADD 000000001b480725 grp< (0 bytes)
audio driver completes its PCI probe() [ 126.892238] snd_hda_intel 0000:00:1f.3: DEVRES ADD 000000001b480725 pcim_iomap_release (48 bytes)
component_del() called() at DRM/i915 unbind() [ 137.579422] i915 0000:00:02.0: DEVRES REL 00000000ef44c293 grp< (0 bytes) [ 137.579445] snd_hda_intel 0000:00:1f.3: DEVRES REL 00000000865cdb29 grp< (0 bytes) [ 137.579458] snd_hda_intel 0000:00:1f.3: DEVRES REL 000000001b480725 pcim_iomap_release (48 bytes)
So the "devres_release_group(master->parent, NULL)" ends up freeing the pcim_iomap allocation. Upon next runtime resume, the audio driver will cause a page fault as the iomap alloc was released without the driver knowing about it.
Fix this issue by using the "struct master" pointer as identifier for the devres group, and by closing the devres group after the master->ops->bind() call is done. This allows devres allocations done by the driver acting as master to be isolated from the binding state of the aggregate driver. This modifies the logic originally introduced in commit 9e1ccb4a7700 ("drivers/base: fix devres handling for master device")
Fixes: 9e1ccb4a7700 ("drivers/base: fix devres handling for master device") Cc: stable@vger.kernel.org Acked-by: Imre Deak imre.deak@intel.com Acked-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com BugLink: https://gitlab.freedesktop.org/drm/intel/-/issues/4136 Link: https://lore.kernel.org/r/20211013161345.3755341-1-kai.vehmanen@linux.intel.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/component.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -246,7 +246,7 @@ static int try_to_bring_up_master(struct return 0; }
- if (!devres_open_group(master->parent, NULL, GFP_KERNEL)) + if (!devres_open_group(master->parent, master, GFP_KERNEL)) return -ENOMEM;
/* Found all components */ @@ -258,6 +258,7 @@ static int try_to_bring_up_master(struct return ret; }
+ devres_close_group(master->parent, NULL); master->bound = true; return 1; } @@ -282,7 +283,7 @@ static void take_down_master(struct mast { if (master->bound) { master->ops->unbind(master->parent); - devres_release_group(master->parent, NULL); + devres_release_group(master->parent, master); master->bound = false; } }
From: Charan Teja Reddy charante@codeaurora.org
[ Upstream commit f492283b157053e9555787262f058ae33096f568 ]
It is expected from the clients to follow the below steps on an imported dmabuf fd: a) dmabuf = dma_buf_get(fd) // Get the dmabuf from fd b) dma_buf_attach(dmabuf); // Clients attach to the dmabuf o Here the kernel does some slab allocations, say for dma_buf_attachment and may be some other slab allocation in the dmabuf->ops->attach(). c) Client may need to do dma_buf_map_attachment(). d) Accordingly dma_buf_unmap_attachment() should be called. e) dma_buf_detach () // Clients detach to the dmabuf. o Here the slab allocations made in b) are freed. f) dma_buf_put(dmabuf) // Can free the dmabuf if it is the last reference.
Now say an erroneous client failed at step c) above thus it directly called dma_buf_put(), step f) above. Considering that it may be the last reference to the dmabuf, buffer will be freed with pending attachments left to the dmabuf which can show up as the 'memory leak'. This should at least be reported as the WARN().
Signed-off-by: Charan Teja Reddy charante@codeaurora.org Reviewed-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/1627043468-16381-1-git-send-em... Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma-buf/dma-buf.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 9f68f76c985e3..61e20ae7b08b7 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -82,6 +82,7 @@ static void dma_buf_release(struct dentry *dentry) if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) dma_resv_fini(dmabuf->resv);
+ WARN_ON(!list_empty(&dmabuf->attachments)); module_put(dmabuf->owner); kfree(dmabuf->name); kfree(dmabuf);
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 820a2ab23d5eab4ccfb82581eda8ad4acf18458f ]
2 improvements to the Lenovo Ideapad D330 panel-orientation quirks:
1. Some versions of the Lenovo Ideapad D330 have a DMI_PRODUCT_NAME of "81H3" and others have "81MD". Testing has shown that the "81MD" also has a 90 degree mounted panel. Drop the DMI_PRODUCT_NAME from the existing quirk so that the existing quirk matches both variants.
2. Some of the Lenovo Ideapad D330 models have a HD (800x1280) screen instead of a FHD (1200x1920) screen (both are mounted right-side-up) add a second Lenovo Ideapad D330 quirk for the HD version.
Changes in v2: - Add a new quirk for Lenovo Ideapad D330 models with a HD screen instead of a FHD screen
Link: https://github.com/systemd/systemd/pull/18884 Acked-by: Simon Ser contact@emersion.fr Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20210530110428.12994-2-hdegoed... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index e1b2ce4921ae7..5d0942e3985b2 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -223,10 +223,15 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), }, .driver_data = (void *)&lcd800x1280_rightside_up, - }, { /* Lenovo Ideapad D330 */ + }, { /* Lenovo Ideapad D330-10IGM (HD) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Lenovo Ideapad D330-10IGM (FHD) */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81H3"), DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), }, .driver_data = (void *)&lcd1200x1920_rightside_up,
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit a53f1dd3ab9fec715c6c2e8e01bf4d3c07eef8e5 ]
The KD Kurio Smart C15200 2-in-1 uses a panel which has been mounted 90 degrees rotated. Add a quirk for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Simon Ser contact@emersion.fr Link: https://patchwork.freedesktop.org/patch/msgid/20210530110428.12994-3-hdegoed... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 5d0942e3985b2..cf4db2cdebbbd 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -205,6 +205,13 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"), }, .driver_data = (void *)&itworks_tw891, + }, { /* KD Kurio Smart C15200 2-in-1 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "KD Interactive"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Kurio Smart"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "KDM960BCP"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* * Lenovo Ideapad Miix 310 laptop, only some production batches * have a portrait screen, the resolution checks makes the quirk
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 88fa1fde918951c175ae5ea0f31efc4bb1736ab9 ]
The Samsung Galaxy Book 10.6 uses a panel which has been mounted 90 degrees rotated. Add a quirk for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Simon Ser contact@emersion.fr Link: https://patchwork.freedesktop.org/patch/msgid/20210530110428.12994-4-hdegoed... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index cf4db2cdebbbd..926094b83e2f4 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -109,6 +109,12 @@ static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = { .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, };
+static const struct drm_dmi_panel_orientation_data lcd1280x1920_rightside_up = { + .width = 1280, + .height = 1920, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct dmi_system_id orientation_data[] = { { /* Acer One 10 (S1003) */ .matches = { @@ -249,6 +255,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), }, .driver_data = (void *)&onegx1_pro, + }, { /* Samsung GalaxyBook 10.6 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"), + }, + .driver_data = (void *)&lcd1280x1920_rightside_up, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 99c23da0eed4fd20cae8243f2b51e10e66aa0951 ]
The sco_send_frame() also takes lock_sock() during memcpy_from_msg() call that may be endlessly blocked by a task with userfaultd technique, and this will result in a hung task watchdog trigger.
Just like the similar fix for hci_sock_sendmsg() in commit 92c685dc5de0 ("Bluetooth: reorganize functions..."), this patch moves the memcpy_from_msg() out of lock_sock() for addressing the hang.
This should be the last piece for fixing CVE-2021-3640 after a few already queued fixes.
Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 98a8815865128..b62c91c627e2c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -280,7 +280,8 @@ static int sco_connect(struct hci_dev *hdev, struct sock *sk) return err; }
-static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) +static int sco_send_frame(struct sock *sk, void *buf, int len, + unsigned int msg_flags) { struct sco_conn *conn = sco_pi(sk)->conn; struct sk_buff *skb; @@ -292,15 +293,11 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
BT_DBG("sk %p len %d", sk, len);
- skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err); + skb = bt_skb_send_alloc(sk, len, msg_flags & MSG_DONTWAIT, &err); if (!skb) return err;
- if (memcpy_from_msg(skb_put(skb, len), msg, len)) { - kfree_skb(skb); - return -EFAULT; - } - + memcpy(skb_put(skb, len), buf, len); hci_send_sco(conn->hcon, skb);
return len; @@ -725,6 +722,7 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; + void *buf; int err;
BT_DBG("sock %p, sk %p", sock, sk); @@ -736,14 +734,24 @@ static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, if (msg->msg_flags & MSG_OOB) return -EOPNOTSUPP;
+ buf = kmalloc(len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (memcpy_from_msg(buf, msg, len)) { + kfree(buf); + return -EFAULT; + } + lock_sock(sk);
if (sk->sk_state == BT_CONNECTED) - err = sco_send_frame(sk, msg, len); + err = sco_send_frame(sk, buf, len, msg->msg_flags); else err = -ENOTCONN;
release_sock(sk); + kfree(buf); return err; }
From: Wang ShaoBo bobo.shaobowang@huawei.com
[ Upstream commit 1bff51ea59a9afb67d2dd78518ab0582a54a472c ]
use-after-free error in lock_sock_nested is reported:
[ 179.140137][ T3731] ===================================================== [ 179.142675][ T3731] BUG: KMSAN: use-after-free in lock_sock_nested+0x280/0x2c0 [ 179.145494][ T3731] CPU: 4 PID: 3731 Comm: kworker/4:2 Not tainted 5.12.0-rc6+ #54 [ 179.148432][ T3731] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 [ 179.151806][ T3731] Workqueue: events l2cap_chan_timeout [ 179.152730][ T3731] Call Trace: [ 179.153301][ T3731] dump_stack+0x24c/0x2e0 [ 179.154063][ T3731] kmsan_report+0xfb/0x1e0 [ 179.154855][ T3731] __msan_warning+0x5c/0xa0 [ 179.155579][ T3731] lock_sock_nested+0x280/0x2c0 [ 179.156436][ T3731] ? kmsan_get_metadata+0x116/0x180 [ 179.157257][ T3731] l2cap_sock_teardown_cb+0xb8/0x890 [ 179.158154][ T3731] ? __msan_metadata_ptr_for_load_8+0x10/0x20 [ 179.159141][ T3731] ? kmsan_get_metadata+0x116/0x180 [ 179.159994][ T3731] ? kmsan_get_shadow_origin_ptr+0x84/0xb0 [ 179.160959][ T3731] ? l2cap_sock_recv_cb+0x420/0x420 [ 179.161834][ T3731] l2cap_chan_del+0x3e1/0x1d50 [ 179.162608][ T3731] ? kmsan_get_metadata+0x116/0x180 [ 179.163435][ T3731] ? kmsan_get_shadow_origin_ptr+0x84/0xb0 [ 179.164406][ T3731] l2cap_chan_close+0xeea/0x1050 [ 179.165189][ T3731] ? kmsan_internal_unpoison_shadow+0x42/0x70 [ 179.166180][ T3731] l2cap_chan_timeout+0x1da/0x590 [ 179.167066][ T3731] ? __msan_metadata_ptr_for_load_8+0x10/0x20 [ 179.168023][ T3731] ? l2cap_chan_create+0x560/0x560 [ 179.168818][ T3731] process_one_work+0x121d/0x1ff0 [ 179.169598][ T3731] worker_thread+0x121b/0x2370 [ 179.170346][ T3731] kthread+0x4ef/0x610 [ 179.171010][ T3731] ? process_one_work+0x1ff0/0x1ff0 [ 179.171828][ T3731] ? kthread_blkcg+0x110/0x110 [ 179.172587][ T3731] ret_from_fork+0x1f/0x30 [ 179.173348][ T3731] [ 179.173752][ T3731] Uninit was created at: [ 179.174409][ T3731] kmsan_internal_poison_shadow+0x5c/0xf0 [ 179.175373][ T3731] kmsan_slab_free+0x76/0xc0 [ 179.176060][ T3731] kfree+0x3a5/0x1180 [ 179.176664][ T3731] __sk_destruct+0x8af/0xb80 [ 179.177375][ T3731] __sk_free+0x812/0x8c0 [ 179.178032][ T3731] sk_free+0x97/0x130 [ 179.178686][ T3731] l2cap_sock_release+0x3d5/0x4d0 [ 179.179457][ T3731] sock_close+0x150/0x450 [ 179.180117][ T3731] __fput+0x6bd/0xf00 [ 179.180787][ T3731] ____fput+0x37/0x40 [ 179.181481][ T3731] task_work_run+0x140/0x280 [ 179.182219][ T3731] do_exit+0xe51/0x3e60 [ 179.182930][ T3731] do_group_exit+0x20e/0x450 [ 179.183656][ T3731] get_signal+0x2dfb/0x38f0 [ 179.184344][ T3731] arch_do_signal_or_restart+0xaa/0xe10 [ 179.185266][ T3731] exit_to_user_mode_prepare+0x2d2/0x560 [ 179.186136][ T3731] syscall_exit_to_user_mode+0x35/0x60 [ 179.186984][ T3731] do_syscall_64+0xc5/0x140 [ 179.187681][ T3731] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 179.188604][ T3731] =====================================================
In our case, there are two Thread A and B:
Context: Thread A: Context: Thread B:
l2cap_chan_timeout() __se_sys_shutdown() l2cap_chan_close() l2cap_sock_shutdown() l2cap_chan_del() l2cap_chan_close() l2cap_sock_teardown_cb() l2cap_sock_teardown_cb()
Once l2cap_sock_teardown_cb() excuted, this sock will be marked as SOCK_ZAPPED, and can be treated as killable in l2cap_sock_kill() if sock_orphan() has excuted, at this time we close sock through sock_close() which end to call l2cap_sock_kill() like Thread C:
Context: Thread C:
sock_close() l2cap_sock_release() sock_orphan() l2cap_sock_kill() #free sock if refcnt is 1
If C completed, Once A or B reaches l2cap_sock_teardown_cb() again, use-after-free happened.
We should set chan->data to NULL if sock is destructed, for telling teardown operation is not allowed in l2cap_sock_teardown_cb(), and also we should avoid killing an already killed socket in l2cap_sock_close_cb().
Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/l2cap_sock.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index c99d65ef13b1e..160c016a5dfb9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1508,6 +1508,9 @@ static void l2cap_sock_close_cb(struct l2cap_chan *chan) { struct sock *sk = chan->data;
+ if (!sk) + return; + l2cap_sock_kill(sk); }
@@ -1516,6 +1519,9 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) struct sock *sk = chan->data; struct sock *parent;
+ if (!sk) + return; + BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
/* This callback can be called both for server (BT_LISTEN) @@ -1707,8 +1713,10 @@ static void l2cap_sock_destruct(struct sock *sk) { BT_DBG("sk %p", sk);
- if (l2cap_pi(sk)->chan) + if (l2cap_pi(sk)->chan) { + l2cap_pi(sk)->chan->data = NULL; l2cap_chan_put(l2cap_pi(sk)->chan); + }
if (l2cap_pi(sk)->rx_busy_skb) { kfree_skb(l2cap_pi(sk)->rx_busy_skb);
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit f4712fa993f688d0a48e0c28728fcdeb88c1ea58 ]
In sco_conn_del, conn->sk is read while holding on to the sco_conn.lock to avoid races with a socket that could be released concurrently.
However, in between unlocking sco_conn.lock and calling sock_hold, it's possible for the socket to be freed, which would cause a use-after-free write when sock_hold is finally called.
To fix this, the reference count of the socket should be increased while the sco_conn.lock is still held.
Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index b62c91c627e2c..4a057f99b60aa 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -187,10 +187,11 @@ static void sco_conn_del(struct hci_conn *hcon, int err) /* Kill socket */ sco_conn_lock(conn); sk = conn->sk; + if (sk) + sock_hold(sk); sco_conn_unlock(conn);
if (sk) { - sock_hold(sk); lock_sock(sk); sco_sock_clear_timer(sk); sco_chan_del(sk, err);
From: Simon Ser contact@emersion.fr
[ Upstream commit 9eeb7b4e40bfd69d8aaa920c7e9df751c9e11dce ]
Valve's Steam Deck has a 800x1280 LCD screen.
Signed-off-by: Simon Ser contact@emersion.fr Cc: Jared Baldridge jrb@expunge.us Cc: Emil Velikov emil.l.velikov@gmail.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Cc: Hans de Goede hdegoede@redhat.com Acked-by: Sam Ravnborg sam@ravnborg.org Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20210911102430.253986-1-contac... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 926094b83e2f4..a950d5db211c5 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -261,6 +261,13 @@ static const struct dmi_system_id orientation_data[] = { DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"), }, .driver_data = (void *)&lcd1280x1920_rightside_up, + }, { /* Valve Steam Deck */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
From: Scott Wood swood@redhat.com
[ Upstream commit 71921a9606ddbcc1d98c00eca7ae82c373d1fecd ]
rcutorture is generating some nesting scenarios that are not compatible on PREEMPT_RT. For example: preempt_disable(); rcu_read_lock_bh(); preempt_enable(); rcu_read_unlock_bh();
The problem here is that on PREEMPT_RT the bottom halves have to be disabled and enabled in preemptible context.
Reorder locking: start with BH locking and continue with then with disabling preemption or interrupts. In the unlocking do it reverse by first enabling interrupts and preemption and BH at the very end. Ensure that on PREEMPT_RT BH locking remains unchanged if in non-preemptible context.
Link: https://lkml.kernel.org/r/20190911165729.11178-6-swood@redhat.com Link: https://lkml.kernel.org/r/20210819182035.GF4126399@paulmck-ThinkPad-P17-Gen-... Signed-off-by: Scott Wood swood@redhat.com [bigeasy: Drop ATOM_BH, make it only about changing BH in atomic context. Allow enabling RCU in IRQ-off section. Reword commit message.] Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/rcutorture.c | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index ab4215266ebee..968696ace8f3f 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -1432,28 +1432,34 @@ static void rcutorture_one_extend(int *readstate, int newstate, /* First, put new protection in place to avoid critical-section gap. */ if (statesnew & RCUTORTURE_RDR_BH) local_bh_disable(); + if (statesnew & RCUTORTURE_RDR_RBH) + rcu_read_lock_bh(); if (statesnew & RCUTORTURE_RDR_IRQ) local_irq_disable(); if (statesnew & RCUTORTURE_RDR_PREEMPT) preempt_disable(); - if (statesnew & RCUTORTURE_RDR_RBH) - rcu_read_lock_bh(); if (statesnew & RCUTORTURE_RDR_SCHED) rcu_read_lock_sched(); if (statesnew & RCUTORTURE_RDR_RCU) idxnew = cur_ops->readlock() << RCUTORTURE_RDR_SHIFT;
- /* Next, remove old protection, irq first due to bh conflict. */ + /* + * Next, remove old protection, in decreasing order of strength + * to avoid unlock paths that aren't safe in the stronger + * context. Namely: BH can not be enabled with disabled interrupts. + * Additionally PREEMPT_RT requires that BH is enabled in preemptible + * context. + */ if (statesold & RCUTORTURE_RDR_IRQ) local_irq_enable(); - if (statesold & RCUTORTURE_RDR_BH) - local_bh_enable(); if (statesold & RCUTORTURE_RDR_PREEMPT) preempt_enable(); - if (statesold & RCUTORTURE_RDR_RBH) - rcu_read_unlock_bh(); if (statesold & RCUTORTURE_RDR_SCHED) rcu_read_unlock_sched(); + if (statesold & RCUTORTURE_RDR_BH) + local_bh_enable(); + if (statesold & RCUTORTURE_RDR_RBH) + rcu_read_unlock_bh(); if (statesold & RCUTORTURE_RDR_RCU) { bool lockit = !statesnew && !(torture_random(trsp) & 0xffff);
@@ -1496,6 +1502,9 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp) int mask = rcutorture_extend_mask_max(); unsigned long randmask1 = torture_random(trsp) >> 8; unsigned long randmask2 = randmask1 >> 3; + unsigned long preempts = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED; + unsigned long preempts_irq = preempts | RCUTORTURE_RDR_IRQ; + unsigned long bhs = RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH;
WARN_ON_ONCE(mask >> RCUTORTURE_RDR_SHIFT); /* Mostly only one bit (need preemption!), sometimes lots of bits. */ @@ -1503,11 +1512,26 @@ rcutorture_extend_mask(int oldmask, struct torture_random_state *trsp) mask = mask & randmask2; else mask = mask & (1 << (randmask2 % RCUTORTURE_RDR_NBITS)); - /* Can't enable bh w/irq disabled. */ - if ((mask & RCUTORTURE_RDR_IRQ) && - ((!(mask & RCUTORTURE_RDR_BH) && (oldmask & RCUTORTURE_RDR_BH)) || - (!(mask & RCUTORTURE_RDR_RBH) && (oldmask & RCUTORTURE_RDR_RBH)))) - mask |= RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH; + + /* + * Can't enable bh w/irq disabled. + */ + if (mask & RCUTORTURE_RDR_IRQ) + mask |= oldmask & bhs; + + /* + * Ideally these sequences would be detected in debug builds + * (regardless of RT), but until then don't stop testing + * them on non-RT. + */ + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { + /* Can't modify BH in atomic context */ + if (oldmask & preempts_irq) + mask &= ~bhs; + if ((oldmask | mask) & preempts_irq) + mask |= oldmask & bhs; + } + return mask ?: RCUTORTURE_RDR_RCU; }
From: Barnabás Pőcze pobrn@protonmail.com
[ Upstream commit 1975718c488a39128f1f515b23ae61a5a214cc3d ]
Previously, `__query_block()` would fail if the second WCxx method call failed. However, the WQxx method might have succeeded, and potentially allocated memory for the result. Instead of throwing away the result and potentially leaking memory, ignore the result of the second WCxx call.
Signed-off-by: Barnabás Pőcze pobrn@protonmail.com Link: https://lore.kernel.org/r/20210904175450.156801-25-pobrn@protonmail.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/platform/x86/wmi.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index a76313006bdc4..1b65bb61ce888 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -353,7 +353,14 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance, * the WQxx method failed - we should disable collection anyway. */ if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { - status = acpi_execute_simple_method(handle, wc_method, 0); + /* + * Ignore whether this WCxx call succeeds or not since + * the previously executed WQxx method call might have + * succeeded, and returning the failing status code + * of this call would throw away the result of the WQxx + * call, potentially leaking memory. + */ + acpi_execute_simple_method(handle, wc_method, 0); }
return status;
From: James Zhu James.Zhu@amd.com
[ Upstream commit 9cec53c18a3170c7e5673c414da56aeecee94832 ]
Separate iommu_resume from kfd_resume, and move it before other amdgpu ip init/resume.
Bug: https://bugzilla.kernel.org/show_bug.cgi?id=211277 Signed-off-by: James Zhu James.Zhu@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index b8d9004fb1635..5b88c873c8a89 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2394,6 +2394,10 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) if (r) goto init_failed;
+ r = amdgpu_amdkfd_resume_iommu(adev); + if (r) + goto init_failed; + r = amdgpu_device_ip_hw_init_phase1(adev); if (r) goto init_failed;
From: Aleksander Jan Bajkowski olek2@wp.pl
[ Upstream commit c12aa581f6d5e80c3c3675ab26a52c2b3b62f76e ]
Reading the DMA registers immediately after the reset causes Data Bus Error. Adding a small delay fixes this issue.
Signed-off-by: Aleksander Jan Bajkowski olek2@wp.pl Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/lantiq/xway/dma.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 63dccb2ed08b2..2784715933d13 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -11,6 +11,7 @@ #include <linux/export.h> #include <linux/spinlock.h> #include <linux/clk.h> +#include <linux/delay.h> #include <linux/err.h> #include <linux/of.h>
@@ -222,6 +223,8 @@ ltq_dma_init(struct platform_device *pdev) clk_enable(clk); ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
+ usleep_range(1, 10); + /* disable all interrupts */ ltq_dma_w32(0, LTQ_DMA_IRNEN);
From: Aleksander Jan Bajkowski olek2@wp.pl
[ Upstream commit 5ca9ce2ba4d5884cd94d1a856c675ab1242cd242 ]
Different SoCs have a different number of channels, e.g .: * amazon-se has 10 channels, * danube+ar9 have 20 channels, * vr9 has 28 channels, * ar10 has 24 channels.
We can read the ID register and, depending on the reported number of channels, reset the appropriate number of channels.
Signed-off-by: Aleksander Jan Bajkowski olek2@wp.pl Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/lantiq/xway/dma.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 2784715933d13..364ab39eb8a41 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -31,6 +31,7 @@ #define LTQ_DMA_PCTRL 0x44 #define LTQ_DMA_IRNEN 0xf4
+#define DMA_ID_CHNR GENMASK(26, 20) /* channel number */ #define DMA_DESCPT BIT(3) /* descriptor complete irq */ #define DMA_TX BIT(8) /* TX channel direction */ #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ @@ -41,7 +42,6 @@ #define DMA_POLL BIT(31) /* turn on channel polling */ #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ #define DMA_2W_BURST BIT(1) /* 2 word burst length */ -#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */
@@ -207,7 +207,7 @@ ltq_dma_init(struct platform_device *pdev) { struct clk *clk; struct resource *res; - unsigned id; + unsigned int id, nchannels; int i;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -229,17 +229,18 @@ ltq_dma_init(struct platform_device *pdev) ltq_dma_w32(0, LTQ_DMA_IRNEN);
/* reset/configure each channel */ - for (i = 0; i < DMA_MAX_CHANNEL; i++) { + id = ltq_dma_r32(LTQ_DMA_ID); + nchannels = ((id & DMA_ID_CHNR) >> 20); + for (i = 0; i < nchannels; i++) { ltq_dma_w32(i, LTQ_DMA_CS); ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); }
- id = ltq_dma_r32(LTQ_DMA_ID); dev_info(&pdev->dev, "Init done - hw rev: %X, ports: %d, channels: %d\n", - id & 0x1f, (id >> 16) & 0xf, id >> 20); + id & 0x1f, (id >> 16) & 0xf, nchannels);
return 0; }
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit ce0b9c805dd66d5e49fd53ec5415ae398f4c56e6 ]
vmlinux.o: warning: objtool: look_up_lock_class()+0xc7: call to rcu_read_lock_any_held() leaves .noinstr.text section
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lore.kernel.org/r/20210624095148.311980536@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/lockdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index bf1c00c881e48..8a509672a4cc9 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -888,7 +888,7 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass) if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) return NULL;
- hlist_for_each_entry_rcu(class, hash_head, hash_entry) { + hlist_for_each_entry_rcu_notrace(class, hash_head, hash_entry) { if (class->key == key) { /* * Huh! same key, different name? Did someone trample
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 1e080f17750d1083e8a32f7b350584ae1cd7ff20 ]
mq / mqprio make the default child qdiscs visible. They only do so for the qdiscs which are within real_num_tx_queues when the device is registered. Depending on order of calls in the driver, or if user space changes config via ethtool -L the number of qdiscs visible under tc qdisc show will differ from the number of queues. This is confusing to users and potentially to system configuration scripts which try to make sure qdiscs have the right parameters.
Add a new Qdisc_ops callback and make relevant qdiscs TTRT.
Note that this uncovers the "shortcut" created by commit 1f27cde313d7 ("net: sched: use pfifo_fast for non real queues") The default child qdiscs beyond initial real_num_tx are always pfifo_fast, no matter what the sysfs setting is. Fixing this gets a little tricky because we'd need to keep a reference on whatever the default qdisc was at the time of creation. In practice this is likely an non-issue the qdiscs likely have to be configured to non-default settings, so whatever user space is doing such configuration can replace the pfifos... now that it will see them.
Reported-by: Matthew Massey matthewmassey@fb.com Reviewed-by: Dave Taht dave.taht@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/sch_generic.h | 4 ++++ net/core/dev.c | 2 ++ net/sched/sch_generic.c | 9 +++++++++ net/sched/sch_mq.c | 24 ++++++++++++++++++++++++ net/sched/sch_mqprio.c | 23 +++++++++++++++++++++++ 5 files changed, 62 insertions(+)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c0069ac00e62d..8c2d611639fca 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -308,6 +308,8 @@ struct Qdisc_ops { struct netlink_ext_ack *extack); void (*attach)(struct Qdisc *sch); int (*change_tx_queue_len)(struct Qdisc *, unsigned int); + void (*change_real_num_tx)(struct Qdisc *sch, + unsigned int new_real_tx);
int (*dump)(struct Qdisc *, struct sk_buff *); int (*dump_stats)(struct Qdisc *, struct gnet_dump *); @@ -684,6 +686,8 @@ void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *); void qdisc_class_hash_destroy(struct Qdisc_class_hash *);
int dev_qdisc_change_tx_queue_len(struct net_device *dev); +void dev_qdisc_change_real_num_tx(struct net_device *dev, + unsigned int new_real_tx); void dev_init_scheduler(struct net_device *dev); void dev_shutdown(struct net_device *dev); void dev_activate(struct net_device *dev); diff --git a/net/core/dev.c b/net/core/dev.c index eb3a366bf212c..aa7a98fd2d64b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2921,6 +2921,8 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) if (dev->num_tc) netif_setup_tc(dev, txq);
+ dev_qdisc_change_real_num_tx(dev, txq); + dev->real_num_tx_queues = txq;
if (disabling) { diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index a8dd06c74e318..66d2fbe9ef501 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -1330,6 +1330,15 @@ static int qdisc_change_tx_queue_len(struct net_device *dev, return 0; }
+void dev_qdisc_change_real_num_tx(struct net_device *dev, + unsigned int new_real_tx) +{ + struct Qdisc *qdisc = dev->qdisc; + + if (qdisc->ops->change_real_num_tx) + qdisc->ops->change_real_num_tx(qdisc, new_real_tx); +} + int dev_qdisc_change_tx_queue_len(struct net_device *dev) { bool up = dev->flags & IFF_UP; diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index e79f1afe0cfd6..db18d8a860f9c 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -125,6 +125,29 @@ static void mq_attach(struct Qdisc *sch) priv->qdiscs = NULL; }
+static void mq_change_real_num_tx(struct Qdisc *sch, unsigned int new_real_tx) +{ +#ifdef CONFIG_NET_SCHED + struct net_device *dev = qdisc_dev(sch); + struct Qdisc *qdisc; + unsigned int i; + + for (i = new_real_tx; i < dev->real_num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + /* Only update the default qdiscs we created, + * qdiscs with handles are always hashed. + */ + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_del(qdisc); + } + for (i = dev->real_num_tx_queues; i < new_real_tx; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_add(qdisc, false); + } +#endif +} + static int mq_dump(struct Qdisc *sch, struct sk_buff *skb) { struct net_device *dev = qdisc_dev(sch); @@ -288,6 +311,7 @@ struct Qdisc_ops mq_qdisc_ops __read_mostly = { .init = mq_init, .destroy = mq_destroy, .attach = mq_attach, + .change_real_num_tx = mq_change_real_num_tx, .dump = mq_dump, .owner = THIS_MODULE, }; diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index 5eb3b1b7ae5e7..50e15add6068f 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -306,6 +306,28 @@ static void mqprio_attach(struct Qdisc *sch) priv->qdiscs = NULL; }
+static void mqprio_change_real_num_tx(struct Qdisc *sch, + unsigned int new_real_tx) +{ + struct net_device *dev = qdisc_dev(sch); + struct Qdisc *qdisc; + unsigned int i; + + for (i = new_real_tx; i < dev->real_num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + /* Only update the default qdiscs we created, + * qdiscs with handles are always hashed. + */ + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_del(qdisc); + } + for (i = dev->real_num_tx_queues; i < new_real_tx; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc_sleeping; + if (qdisc != &noop_qdisc && !qdisc->handle) + qdisc_hash_add(qdisc, false); + } +} + static struct netdev_queue *mqprio_queue_get(struct Qdisc *sch, unsigned long cl) { @@ -629,6 +651,7 @@ static struct Qdisc_ops mqprio_qdisc_ops __read_mostly = { .init = mqprio_init, .destroy = mqprio_destroy, .attach = mqprio_attach, + .change_real_num_tx = mqprio_change_real_num_tx, .dump = mqprio_dump, .owner = THIS_MODULE, };
From: Hui Wang hui.wang@canonical.com
[ Upstream commit 892a012699fc0b91a2ed6309078936191447f480 ]
After the commit 0ec4e55e9f57 ("ACPI: resources: Add checks for ACPI IRQ override") is reverted, the keyboard on Medion laptops can't work again.
To fix the keyboard issue, add a DMI-based override check that will not affect other machines along the lines of prt_quirks[] in drivers/acpi/pci_irq.c.
If similar issues are seen on other platforms, the quirk table could be expanded in the future.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=213031 BugLink: http://bugs.launchpad.net/bugs/1909814 Suggested-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Reported-by: Manuel Krause manuelkrause@netscape.net Tested-by: Manuel Krause manuelkrause@netscape.net Signed-off-by: Hui Wang hui.wang@canonical.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/resource.c | 49 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index ee78a210c6068..7bf38652e6aca 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -16,6 +16,7 @@ #include <linux/ioport.h> #include <linux/slab.h> #include <linux/irq.h> +#include <linux/dmi.h>
#ifdef CONFIG_X86 #define valid_IRQ(i) (((i) != 0) && ((i) != 2)) @@ -380,9 +381,51 @@ unsigned int acpi_dev_get_irq_type(int triggering, int polarity) } EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type);
+static const struct dmi_system_id medion_laptop[] = { + { + .ident = "MEDION P15651", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_BOARD_NAME, "M15T"), + }, + }, + { } +}; + +struct irq_override_cmp { + const struct dmi_system_id *system; + unsigned char irq; + unsigned char triggering; + unsigned char polarity; + unsigned char shareable; +}; + +static const struct irq_override_cmp skip_override_table[] = { + { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, +}; + +static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, + u8 shareable) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) { + const struct irq_override_cmp *entry = &skip_override_table[i]; + + if (dmi_check_system(entry->system) && + entry->irq == gsi && + entry->triggering == triggering && + entry->polarity == polarity && + entry->shareable == shareable) + return false; + } + + return true; +} + static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, - bool legacy) + bool check_override) { int irq, p, t;
@@ -401,7 +444,9 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, * using extended IRQ descriptors we take the IRQ configuration * from _CRS directly. */ - if (legacy && !acpi_get_override_irq(gsi, &t, &p)) { + if (check_override && + acpi_dev_irq_override(gsi, triggering, polarity, shareable) && + !acpi_get_override_irq(gsi, &t, &p)) { u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
From: Paul E. McKenney paulmck@kernel.org
[ Upstream commit 0db7c32ad3160ae06f497d48a74bd46a2a35e6bf ]
Early in debugging, it made some sense to differentiate the first iteration from subsequent iterations, but now this just causes confusion. This commit therefore moves the "set_tasks_gp_state(rtp, RTGS_WAIT_CBS)" statement to the beginning of the "for" loop in rcu_tasks_kthread().
Reported-by: Neeraj Upadhyay neeraju@codeaurora.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tasks.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 806160c44b172..6591914af4864 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -197,6 +197,7 @@ static int __noreturn rcu_tasks_kthread(void *arg) * This loop is terminated by the system going down. ;-) */ for (;;) { + set_tasks_gp_state(rtp, RTGS_WAIT_CBS);
/* Pick up any new callbacks. */ raw_spin_lock_irqsave(&rtp->cbs_lock, flags); @@ -236,8 +237,6 @@ static int __noreturn rcu_tasks_kthread(void *arg) } /* Paranoid sleep to keep this from entering a tight loop */ schedule_timeout_idle(rtp->gp_sleep); - - set_tasks_gp_state(rtp, RTGS_WAIT_CBS); } }
From: Pawan Gupta pawan.kumar.gupta@linux.intel.com
[ Upstream commit 0817534ff9ea809fac1322c5c8c574be8483ea57 ]
Syzkaller reported use-after-free bug as described in [1]. The bug is triggered when smk_set_cipso() tries to free stale category bitmaps while there are concurrent reader(s) using the same bitmaps.
Wait for RCU grace period to finish before freeing the category bitmaps in smk_set_cipso(). This makes sure that there are no more readers using the stale bitmaps and freeing them should be safe.
[1] https://lore.kernel.org/netdev/000000000000a814c505ca657a4e@google.com/
Reported-by: syzbot+3f91de0b813cc3d19a80@syzkaller.appspotmail.com Signed-off-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smackfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 3a75d2a8f5178..9d853c0e55b84 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -831,6 +831,7 @@ static int smk_open_cipso(struct inode *inode, struct file *file) static ssize_t smk_set_cipso(struct file *file, const char __user *buf, size_t count, loff_t *ppos, int format) { + struct netlbl_lsm_catmap *old_cat; struct smack_known *skp; struct netlbl_lsm_secattr ncats; char mapcatset[SMK_CIPSOLEN]; @@ -920,9 +921,11 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
rc = smk_netlbl_mls(maplevel, mapcatset, &ncats, SMK_CIPSOLEN); if (rc >= 0) { - netlbl_catmap_free(skp->smk_netlabel.attr.mls.cat); + old_cat = skp->smk_netlabel.attr.mls.cat; skp->smk_netlabel.attr.mls.cat = ncats.attr.mls.cat; skp->smk_netlabel.attr.mls.lvl = ncats.attr.mls.lvl; + synchronize_rcu(); + netlbl_catmap_free(old_cat); rc = count; /* * This mapping may have been cached, so clear the cache.
From: Seevalamuthu Mariappan seevalam@codeaurora.org
[ Upstream commit feab5bb8f1d4621025dceae7eef62d5f92de34ac ]
pdev_id in structure 'wmi_pdev_bss_chan_info_event' is wrongly placed at the beginning. This causes invalid values in survey dump. Hence, align the structure with the firmware.
Note: The firmware releases follow this order since the feature was implemented. Also, it is not changing across the branches including QCA6390.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-01228-QCAHKSWPL_SILICONZ-1
Signed-off-by: Ritesh Singh ritesi@codeaurora.org Signed-off-by: Seevalamuthu Mariappan seevalam@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210720214922.118078-3-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/wmi.c | 1 + drivers/net/wireless/ath/ath11k/wmi.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 6c253eae9d069..27c060dd3fb47 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -1339,6 +1339,7 @@ int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k *ar, WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST) | FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE); cmd->req_type = type; + cmd->pdev_id = ar->pdev->pdev_id;
ath11k_dbg(ar->ab, ATH11K_DBG_WMI, "WMI bss chan info req type %d\n", type); diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h index d35c47e0b19d4..0b7d337b36930 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -2960,6 +2960,7 @@ struct wmi_pdev_bss_chan_info_req_cmd { u32 tlv_header; /* ref wmi_bss_chan_info_req_type */ u32 req_type; + u32 pdev_id; } __packed;
struct wmi_ap_ps_peer_cmd { @@ -4056,7 +4057,6 @@ struct wmi_vdev_stopped_event { } __packed;
struct wmi_pdev_bss_chan_info_event { - u32 pdev_id; u32 freq; /* Units in MHz */ u32 noise_floor; /* units are dBm */ /* rx clear - how often the channel was unused */ @@ -4074,6 +4074,7 @@ struct wmi_pdev_bss_chan_info_event { /*rx_cycle cnt for my bss in 64bits format */ u32 rx_bss_cycle_count_low; u32 rx_bss_cycle_count_high; + u32 pdev_id; } __packed;
#define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0
From: Shreyansh Chouhan chouhan.shreyansh630@gmail.com
[ Upstream commit a2d3cbc80d2527b435154ff0f89b56ef4b84370f ]
In the code for xts_crypt(), we check for the err value returned by skcipher_walk_virt() and return from the function if it is non zero. However, skcipher_walk_virt() can set walk.nbytes to 0, which would cause us to call kernel_fpu_begin(), and then skip the kernel_fpu_end() call.
This patch checks for the walk.nbytes value instead, and returns if walk.nbytes is 0. This prevents us from calling kernel_fpu_begin() in the first place and also covers the case of having a non zero err value returned from skcipher_walk_virt().
Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Shreyansh Chouhan chouhan.shreyansh630@gmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/crypto/aesni-intel_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 0fc961bef299c..e09f4672dd382 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -866,7 +866,7 @@ static int xts_crypt(struct skcipher_request *req, bool encrypt) req = &subreq;
err = skcipher_walk_virt(&walk, req, false); - if (err) + if (!walk.nbytes) return err; } else { tail = 0;
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 44b979fa302cab91bdd2cc982823e5c13202cd4e ]
Current code has an explicit check for hitting the task stack guard; but overflowing any of the other stacks will get you a non-descript general #DF warning.
Improve matters by using get_stack_info_noinstr() to detetrmine if and which stack guard page got hit, enabling a better stack warning.
In specific, Michael Wang reported what turned out to be an NMI exception stack overflow, which is now clearly reported as such:
[] BUG: NMI stack guard page was hit at 0000000085fd977b (stack is 000000003a55b09e..00000000d8cce1a5)
Reported-by: Michael Wang yun.wang@linux.alibaba.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: Michael Wang yun.wang@linux.alibaba.com Link: https://lkml.kernel.org/r/YUTE/NuqnaWbST8n@hirez.programming.kicks-ass.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/irq_stack.h | 37 +++++++++++++++++++++---------- arch/x86/include/asm/stacktrace.h | 10 +++++++++ arch/x86/include/asm/traps.h | 6 ++--- arch/x86/kernel/dumpstack_64.c | 6 +++++ arch/x86/kernel/traps.c | 25 +++++++++++---------- arch/x86/mm/fault.c | 20 ++++++++--------- 6 files changed, 67 insertions(+), 37 deletions(-)
diff --git a/arch/x86/include/asm/irq_stack.h b/arch/x86/include/asm/irq_stack.h index 562854c608082..8d55bd11848cb 100644 --- a/arch/x86/include/asm/irq_stack.h +++ b/arch/x86/include/asm/irq_stack.h @@ -77,11 +77,11 @@ * Function calls can clobber anything except the callee-saved * registers. Tell the compiler. */ -#define call_on_irqstack(func, asm_call, argconstr...) \ +#define call_on_stack(stack, func, asm_call, argconstr...) \ { \ register void *tos asm("r11"); \ \ - tos = ((void *)__this_cpu_read(hardirq_stack_ptr)); \ + tos = ((void *)(stack)); \ \ asm_inline volatile( \ "movq %%rsp, (%[tos]) \n" \ @@ -98,6 +98,25 @@ ); \ }
+#define ASM_CALL_ARG0 \ + "call %P[__func] \n" + +#define ASM_CALL_ARG1 \ + "movq %[arg1], %%rdi \n" \ + ASM_CALL_ARG0 + +#define ASM_CALL_ARG2 \ + "movq %[arg2], %%rsi \n" \ + ASM_CALL_ARG1 + +#define ASM_CALL_ARG3 \ + "movq %[arg3], %%rdx \n" \ + ASM_CALL_ARG2 + +#define call_on_irqstack(func, asm_call, argconstr...) \ + call_on_stack(__this_cpu_read(hardirq_stack_ptr), \ + func, asm_call, argconstr) + /* Macros to assert type correctness for run_*_on_irqstack macros */ #define assert_function_type(func, proto) \ static_assert(__builtin_types_compatible_p(typeof(&func), proto)) @@ -147,8 +166,7 @@ */ #define ASM_CALL_SYSVEC \ "call irq_enter_rcu \n" \ - "movq %[arg1], %%rdi \n" \ - "call %P[__func] \n" \ + ASM_CALL_ARG1 \ "call irq_exit_rcu \n"
#define SYSVEC_CONSTRAINTS , [arg1] "r" (regs) @@ -168,12 +186,10 @@ */ #define ASM_CALL_IRQ \ "call irq_enter_rcu \n" \ - "movq %[arg1], %%rdi \n" \ - "movl %[arg2], %%esi \n" \ - "call %P[__func] \n" \ + ASM_CALL_ARG2 \ "call irq_exit_rcu \n"
-#define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" (vector) +#define IRQ_CONSTRAINTS , [arg1] "r" (regs), [arg2] "r" ((unsigned long)vector)
#define run_irq_on_irqstack_cond(func, regs, vector) \ { \ @@ -185,9 +201,6 @@ IRQ_CONSTRAINTS, regs, vector); \ }
-#define ASM_CALL_SOFTIRQ \ - "call %P[__func] \n" - /* * Macro to invoke __do_softirq on the irq stack. This is only called from * task context when bottom halves are about to be reenabled and soft @@ -197,7 +210,7 @@ #define do_softirq_own_stack() \ { \ __this_cpu_write(hardirq_stack_inuse, true); \ - call_on_irqstack(__do_softirq, ASM_CALL_SOFTIRQ); \ + call_on_irqstack(__do_softirq, ASM_CALL_ARG0); \ __this_cpu_write(hardirq_stack_inuse, false); \ }
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index f248eb2ac2d4a..3881b5333eb81 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h @@ -38,6 +38,16 @@ int get_stack_info(unsigned long *stack, struct task_struct *task, bool get_stack_info_noinstr(unsigned long *stack, struct task_struct *task, struct stack_info *info);
+static __always_inline +bool get_stack_guard_info(unsigned long *stack, struct stack_info *info) +{ + /* make sure it's not in the stack proper */ + if (get_stack_info_noinstr(stack, current, info)) + return false; + /* but if it is in the page below it, we hit a guard */ + return get_stack_info_noinstr((void *)stack + PAGE_SIZE, current, info); +} + const char *stack_type_name(enum stack_type type);
static inline bool on_stack(struct stack_info *info, void *addr, size_t len) diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 7f7200021bd13..6221be7cafc3b 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -40,9 +40,9 @@ void math_emulate(struct math_emu_info *); bool fault_in_kernel_space(unsigned long address);
#ifdef CONFIG_VMAP_STACK -void __noreturn handle_stack_overflow(const char *message, - struct pt_regs *regs, - unsigned long fault_address); +void __noreturn handle_stack_overflow(struct pt_regs *regs, + unsigned long fault_address, + struct stack_info *info); #endif
#endif /* _ASM_X86_TRAPS_H */ diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index 5601b95944fae..6c5defd6569a3 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c @@ -32,9 +32,15 @@ const char *stack_type_name(enum stack_type type) { BUILD_BUG_ON(N_EXCEPTION_STACKS != 6);
+ if (type == STACK_TYPE_TASK) + return "TASK"; + if (type == STACK_TYPE_IRQ) return "IRQ";
+ if (type == STACK_TYPE_SOFTIRQ) + return "SOFTIRQ"; + if (type == STACK_TYPE_ENTRY) { /* * On 64-bit, we have a generic entry stack that we diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index f3f3034b06f34..cc6de3a01293c 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -313,17 +313,19 @@ out: }
#ifdef CONFIG_VMAP_STACK -__visible void __noreturn handle_stack_overflow(const char *message, - struct pt_regs *regs, - unsigned long fault_address) +__visible void __noreturn handle_stack_overflow(struct pt_regs *regs, + unsigned long fault_address, + struct stack_info *info) { - printk(KERN_EMERG "BUG: stack guard page was hit at %p (stack is %p..%p)\n", - (void *)fault_address, current->stack, - (char *)current->stack + THREAD_SIZE - 1); - die(message, regs, 0); + const char *name = stack_type_name(info->type); + + printk(KERN_EMERG "BUG: %s stack guard page was hit at %p (stack is %p..%p)\n", + name, (void *)fault_address, info->begin, info->end); + + die("stack guard page", regs, 0);
/* Be absolutely certain we don't return. */ - panic("%s", message); + panic("%s stack guard hit", name); } #endif
@@ -353,6 +355,7 @@ DEFINE_IDTENTRY_DF(exc_double_fault)
#ifdef CONFIG_VMAP_STACK unsigned long address = read_cr2(); + struct stack_info info; #endif
#ifdef CONFIG_X86_ESPFIX64 @@ -455,10 +458,8 @@ DEFINE_IDTENTRY_DF(exc_double_fault) * stack even if the actual trigger for the double fault was * something else. */ - if ((unsigned long)task_stack_page(tsk) - 1 - address < PAGE_SIZE) { - handle_stack_overflow("kernel stack overflow (double-fault)", - regs, address); - } + if (get_stack_guard_info((void *)address, &info)) + handle_stack_overflow(regs, address, &info); #endif
pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 84a2c8c4af735..4bfed53e210ec 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -32,6 +32,7 @@ #include <asm/pgtable_areas.h> /* VMALLOC_START, ... */ #include <asm/kvm_para.h> /* kvm_handle_async_pf */ #include <asm/vdso.h> /* fixup_vdso_exception() */ +#include <asm/irq_stack.h>
#define CREATE_TRACE_POINTS #include <asm/trace/exceptions.h> @@ -631,6 +632,9 @@ static noinline void page_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long address) { +#ifdef CONFIG_VMAP_STACK + struct stack_info info; +#endif unsigned long flags; int sig;
@@ -649,9 +653,7 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code, * that we're in vmalloc space to avoid this. */ if (is_vmalloc_addr((void *)address) && - (((unsigned long)current->stack - 1 - address < PAGE_SIZE) || - address - ((unsigned long)current->stack + THREAD_SIZE) < PAGE_SIZE)) { - unsigned long stack = __this_cpu_ist_top_va(DF) - sizeof(void *); + get_stack_guard_info((void *)address, &info)) { /* * We're likely to be running with very little stack space * left. It's plausible that we'd hit this condition but @@ -662,13 +664,11 @@ page_fault_oops(struct pt_regs *regs, unsigned long error_code, * and then double-fault, though, because we're likely to * break the console driver and lose most of the stack dump. */ - asm volatile ("movq %[stack], %%rsp\n\t" - "call handle_stack_overflow\n\t" - "1: jmp 1b" - : ASM_CALL_CONSTRAINT - : "D" ("kernel stack overflow (page fault)"), - "S" (regs), "d" (address), - [stack] "rm" (stack)); + call_on_stack(__this_cpu_ist_top_va(DF) - sizeof(void*), + handle_stack_overflow, + ASM_CALL_ARG3, + , [arg1] "r" (regs), [arg2] "r" (address), [arg3] "r" (&info)); + unreachable(); } #endif
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 7fae4c24a2b84a66c7be399727aca11e7a888462 ]
It turns out that a single page of stack is trivial to overflow with all the tracing gunk enabled. Raise the exception stacks to 2 pages, which is still half the interrupt stacks, which are at 4 pages.
Reported-by: Michael Wang yun.wang@linux.alibaba.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/YUIO9Ye98S5Eb68w@hirez.programming.kicks-ass.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/page_64_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index a8d4ad8565681..e9e2c3ba59239 100644 --- a/arch/x86/include/asm/page_64_types.h +++ b/arch/x86/include/asm/page_64_types.h @@ -15,7 +15,7 @@ #define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
-#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER) +#define EXCEPTION_STACK_ORDER (1 + KASAN_STACK_ORDER) #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
#define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER)
From: Jonas Dreßler verdre@v0yd.nl
[ Upstream commit c2e9666cdffd347460a2b17988db4cfaf2a68fb9 ]
We currently handle changing from the P2P to the STATION virtual interface type slightly different than changing from P2P to ADHOC: When changing to STATION, we don't send the SET_BSS_MODE command. We do send that command on all other type-changes though, and it probably makes sense to send the command since after all we just changed our BSS_MODE. Looking at prior changes to this part of the code, it seems that this is simply a leftover from old refactorings.
Since sending the SET_BSS_MODE command is the only difference between mwifiex_change_vif_to_sta_adhoc() and the current code, we can now use mwifiex_change_vif_to_sta_adhoc() for both switching to ADHOC and STATION interface type.
This does not fix any particular bug and just "looked right", so there's a small chance it might be a regression.
Signed-off-by: Jonas Dreßler verdre@v0yd.nl Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210914195909.36035-4-verdre@v0yd.nl Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/marvell/mwifiex/cfg80211.c | 22 ++++--------------- 1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 0961f4a5e415c..93eb5f109949f 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -1229,29 +1229,15 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: + if (mwifiex_cfg80211_deinit_p2p(priv)) + return -EFAULT; + switch (type) { - case NL80211_IFTYPE_STATION: - if (mwifiex_cfg80211_deinit_p2p(priv)) - return -EFAULT; - priv->adapter->curr_iface_comb.p2p_intf--; - priv->adapter->curr_iface_comb.sta_intf++; - dev->ieee80211_ptr->iftype = type; - if (mwifiex_deinit_priv_params(priv)) - return -1; - if (mwifiex_init_new_priv_params(priv, dev, type)) - return -1; - if (mwifiex_sta_init_cmd(priv, false, false)) - return -1; - break; case NL80211_IFTYPE_ADHOC: - if (mwifiex_cfg80211_deinit_p2p(priv)) - return -EFAULT; + case NL80211_IFTYPE_STATION: return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype, type, params); - break; case NL80211_IFTYPE_AP: - if (mwifiex_cfg80211_deinit_p2p(priv)) - return -EFAULT; return mwifiex_change_vif_to_ap(dev, curr_iftype, type, params); case NL80211_IFTYPE_UNSPECIFIED:
From: Jonas Dreßler verdre@v0yd.nl
[ Upstream commit c606008b70627a2fc485732a53cc22f0f66d0981 ]
When creating a new virtual interface in mwifiex_add_virtual_intf(), we update our internal driver states like bss_type, bss_priority, bss_role and bss_mode to reflect the mode the firmware will be set to.
When switching virtual interface mode using mwifiex_init_new_priv_params() though, we currently only update bss_mode and bss_role. In order for the interface mode switch to actually work, we also need to update bss_type to its proper value, so do that.
This fixes a crash of the firmware (because the driver tries to execute commands that are invalid in AP mode) when switching from station mode to AP mode.
Signed-off-by: Jonas Dreßler verdre@v0yd.nl Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210914195909.36035-9-verdre@v0yd.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index 93eb5f109949f..97f0f39364d67 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -908,16 +908,20 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv, switch (type) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: - priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_type = MWIFIEX_BSS_TYPE_STA; break; case NL80211_IFTYPE_P2P_CLIENT: - priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_type = MWIFIEX_BSS_TYPE_P2P; break; case NL80211_IFTYPE_P2P_GO: - priv->bss_role = MWIFIEX_BSS_ROLE_UAP; + priv->bss_role = MWIFIEX_BSS_ROLE_UAP; + priv->bss_type = MWIFIEX_BSS_TYPE_P2P; break; case NL80211_IFTYPE_AP: priv->bss_role = MWIFIEX_BSS_ROLE_UAP; + priv->bss_type = MWIFIEX_BSS_TYPE_UAP; break; default: mwifiex_dbg(adapter, ERROR,
From: Mark Brown broonie@kernel.org
[ Upstream commit 5fa6863ba69265cb7e45567d12614790ff26bd56 ]
Currently for SPI devices we use the spi_device_id for module autoloading even on systems using device tree, meaning that listing a compatible string in the of_match_table isn't enough to have the module for a SPI driver autoloaded.
We attempted to fix this by generating OF based modaliases for devices instantiated from DT in 3ce6c9e2617e ("spi: add of_device_uevent_modalias support") but this meant we no longer reported spi_device_id based aliases which broke drivers such as spi-nor which don't list all the compatible strings they support directly for DT, and in at least that case it's not super practical to do so given the very large number of compatibles needed, much larger than the number spi_device_ids due to vendor strings. As a result fell back to using spi_device_id based modalises.
Try to close the gap by printing a warning when a SPI driver has a DT compatible that won't be matched as a SPI device ID with the goal of having drivers provide both. Given fallback compatibles this check is going to be excessive but it should be robust which is probably more important here.
Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20210921192149.50740-1-broonie@kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 926b68aa45d3e..2a2f41b6df685 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -451,6 +451,47 @@ int __spi_register_driver(struct module *owner, struct spi_driver *sdrv) { sdrv->driver.owner = owner; sdrv->driver.bus = &spi_bus_type; + + /* + * For Really Good Reasons we use spi: modaliases not of: + * modaliases for DT so module autoloading won't work if we + * don't have a spi_device_id as well as a compatible string. + */ + if (sdrv->driver.of_match_table) { + const struct of_device_id *of_id; + + for (of_id = sdrv->driver.of_match_table; of_id->compatible[0]; + of_id++) { + const char *of_name; + + /* Strip off any vendor prefix */ + of_name = strnchr(of_id->compatible, + sizeof(of_id->compatible), ','); + if (of_name) + of_name++; + else + of_name = of_id->compatible; + + if (sdrv->id_table) { + const struct spi_device_id *spi_id; + + for (spi_id = sdrv->id_table; spi_id->name[0]; + spi_id++) + if (strcmp(spi_id->name, of_name) == 0) + break; + + if (spi_id->name[0]) + continue; + } else { + if (strcmp(sdrv->driver.name, of_name) == 0) + continue; + } + + pr_warn("SPI driver %s has no spi_device_id for %s\n", + sdrv->driver.name, of_id->compatible); + } + } + return driver_register(&sdrv->driver); } EXPORT_SYMBOL_GPL(__spi_register_driver);
From: Eric Biggers ebiggers@google.com
[ Upstream commit 7f595d6a6cdc336834552069a2e0a4f6d4756ddf ]
fscrypt currently requires a 512-bit master key when AES-256-XTS is used, since AES-256-XTS keys are 512-bit and fscrypt requires that the master key be at least as long any key that will be derived from it.
However, this is overly strict because AES-256-XTS doesn't actually have a 512-bit security strength, but rather 256-bit. The fact that XTS takes twice the expected key size is a quirk of the XTS mode. It is sufficient to use 256 bits of entropy for AES-256-XTS, provided that it is first properly expanded into a 512-bit key, which HKDF-SHA512 does.
Therefore, relax the check of the master key size to use the security strength of the derived key rather than the size of the derived key (except for v1 encryption policies, which don't use HKDF).
Besides making things more flexible for userspace, this is needed in order for the use of a KDF which only takes a 256-bit key to be introduced into the fscrypt key hierarchy. This will happen with hardware-wrapped keys support, as all known hardware which supports that feature uses an SP800-108 KDF using AES-256-CMAC, so the wrapped keys are wrapped 256-bit AES keys. Moreover, there is interest in fscrypt supporting the same type of AES-256-CMAC based KDF in software as an alternative to HKDF-SHA512. There is no security problem with such features, so fix the key length check to work properly with them.
Reviewed-by: Paul Crowley paulcrowley@google.com Link: https://lore.kernel.org/r/20210921030303.5598-1-ebiggers@kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/filesystems/fscrypt.rst | 10 ++--- fs/crypto/fscrypt_private.h | 5 ++- fs/crypto/hkdf.c | 11 ++++-- fs/crypto/keysetup.c | 57 +++++++++++++++++++++------ 4 files changed, 61 insertions(+), 22 deletions(-)
diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst index 0eb799d9d05a2..7940a45d39522 100644 --- a/Documentation/filesystems/fscrypt.rst +++ b/Documentation/filesystems/fscrypt.rst @@ -176,11 +176,11 @@ Master Keys
Each encrypted directory tree is protected by a *master key*. Master keys can be up to 64 bytes long, and must be at least as long as the -greater of the key length needed by the contents and filenames -encryption modes being used. For example, if AES-256-XTS is used for -contents encryption, the master key must be 64 bytes (512 bits). Note -that the XTS mode is defined to require a key twice as long as that -required by the underlying block cipher. +greater of the security strength of the contents and filenames +encryption modes being used. For example, if any AES-256 mode is +used, the master key must be at least 256 bits, i.e. 32 bytes. A +stricter requirement applies if the key is used by a v1 encryption +policy and AES-256-XTS is used; such keys must be 64 bytes.
To "unlock" an encrypted directory tree, userspace must provide the appropriate master key. There can be any number of master keys, each diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 3fa965eb3336d..cb25ef0cdf1f3 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -549,8 +549,9 @@ int __init fscrypt_init_keyring(void); struct fscrypt_mode { const char *friendly_name; const char *cipher_str; - int keysize; - int ivsize; + int keysize; /* key size in bytes */ + int security_strength; /* security strength in bytes */ + int ivsize; /* IV size in bytes */ int logged_impl_name; enum blk_crypto_mode_num blk_crypto_mode; }; diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c index e0ec210555053..7607d18b35fc0 100644 --- a/fs/crypto/hkdf.c +++ b/fs/crypto/hkdf.c @@ -16,9 +16,14 @@
/* * HKDF supports any unkeyed cryptographic hash algorithm, but fscrypt uses - * SHA-512 because it is reasonably secure and efficient; and since it produces - * a 64-byte digest, deriving an AES-256-XTS key preserves all 64 bytes of - * entropy from the master key and requires only one iteration of HKDF-Expand. + * SHA-512 because it is well-established, secure, and reasonably efficient. + * + * HKDF-SHA256 was also considered, as its 256-bit security strength would be + * sufficient here. A 512-bit security strength is "nice to have", though. + * Also, on 64-bit CPUs, SHA-512 is usually just as fast as SHA-256. In the + * common case of deriving an AES-256-XTS key (512 bits), that can result in + * HKDF-SHA512 being much faster than HKDF-SHA256, as the longer digest size of + * SHA-512 causes HKDF-Expand to only need to do one iteration rather than two. */ #define HKDF_HMAC_ALG "hmac(sha512)" #define HKDF_HASHLEN SHA512_DIGEST_SIZE diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index bca9c6658a7c5..89cd533a88bff 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -19,6 +19,7 @@ struct fscrypt_mode fscrypt_modes[] = { .friendly_name = "AES-256-XTS", .cipher_str = "xts(aes)", .keysize = 64, + .security_strength = 32, .ivsize = 16, .blk_crypto_mode = BLK_ENCRYPTION_MODE_AES_256_XTS, }, @@ -26,12 +27,14 @@ struct fscrypt_mode fscrypt_modes[] = { .friendly_name = "AES-256-CTS-CBC", .cipher_str = "cts(cbc(aes))", .keysize = 32, + .security_strength = 32, .ivsize = 16, }, [FSCRYPT_MODE_AES_128_CBC] = { .friendly_name = "AES-128-CBC-ESSIV", .cipher_str = "essiv(cbc(aes),sha256)", .keysize = 16, + .security_strength = 16, .ivsize = 16, .blk_crypto_mode = BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV, }, @@ -39,12 +42,14 @@ struct fscrypt_mode fscrypt_modes[] = { .friendly_name = "AES-128-CTS-CBC", .cipher_str = "cts(cbc(aes))", .keysize = 16, + .security_strength = 16, .ivsize = 16, }, [FSCRYPT_MODE_ADIANTUM] = { .friendly_name = "Adiantum", .cipher_str = "adiantum(xchacha12,aes)", .keysize = 32, + .security_strength = 32, .ivsize = 32, .blk_crypto_mode = BLK_ENCRYPTION_MODE_ADIANTUM, }, @@ -357,6 +362,45 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, return 0; }
+/* + * Check whether the size of the given master key (@mk) is appropriate for the + * encryption settings which a particular file will use (@ci). + * + * If the file uses a v1 encryption policy, then the master key must be at least + * as long as the derived key, as this is a requirement of the v1 KDF. + * + * Otherwise, the KDF can accept any size key, so we enforce a slightly looser + * requirement: we require that the size of the master key be at least the + * maximum security strength of any algorithm whose key will be derived from it + * (but in practice we only need to consider @ci->ci_mode, since any other + * possible subkeys such as DIRHASH and INODE_HASH will never increase the + * required key size over @ci->ci_mode). This allows AES-256-XTS keys to be + * derived from a 256-bit master key, which is cryptographically sufficient, + * rather than requiring a 512-bit master key which is unnecessarily long. (We + * still allow 512-bit master keys if the user chooses to use them, though.) + */ +static bool fscrypt_valid_master_key_size(const struct fscrypt_master_key *mk, + const struct fscrypt_info *ci) +{ + unsigned int min_keysize; + + if (ci->ci_policy.version == FSCRYPT_POLICY_V1) + min_keysize = ci->ci_mode->keysize; + else + min_keysize = ci->ci_mode->security_strength; + + if (mk->mk_secret.size < min_keysize) { + fscrypt_warn(NULL, + "key with %s %*phN is too short (got %u bytes, need %u+ bytes)", + master_key_spec_type(&mk->mk_spec), + master_key_spec_len(&mk->mk_spec), + (u8 *)&mk->mk_spec.u, + mk->mk_secret.size, min_keysize); + return false; + } + return true; +} + /* * Find the master key, then set up the inode's actual encryption key. * @@ -422,18 +466,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, goto out_release_key; }
- /* - * Require that the master key be at least as long as the derived key. - * Otherwise, the derived key cannot possibly contain as much entropy as - * that required by the encryption mode it will be used for. For v1 - * policies it's also required for the KDF to work at all. - */ - if (mk->mk_secret.size < ci->ci_mode->keysize) { - fscrypt_warn(NULL, - "key with %s %*phN is too short (got %u bytes, need %u+ bytes)", - master_key_spec_type(&mk_spec), - master_key_spec_len(&mk_spec), (u8 *)&mk_spec.u, - mk->mk_secret.size, ci->ci_mode->keysize); + if (!fscrypt_valid_master_key_size(mk, ci)) { err = -ENOKEY; goto out_release_key; }
From: Andrey Grodzovsky andrey.grodzovsky@amd.com
[ Upstream commit c03509cbc01559549700e14c4a6239f2572ab4ba ]
Add more guards to MMIO access post device unbind/unplug
Bug: https://bugs.archlinux.org/task/72092?project=1&order=dateopened&sor... Signed-off-by: Andrey Grodzovsky andrey.grodzovsky@amd.com Reviewed-by: James Zhu James.Zhu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c | 8 ++++++-- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 17 +++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c index f4686e918e0d1..c405075a572c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c @@ -22,6 +22,7 @@ */
#include <linux/firmware.h> +#include <drm/drm_drv.h>
#include "amdgpu.h" #include "amdgpu_vcn.h" @@ -192,11 +193,14 @@ static int vcn_v2_0_sw_init(void *handle) */ static int vcn_v2_0_sw_fini(void *handle) { - int r; + int r, idx; struct amdgpu_device *adev = (struct amdgpu_device *)handle; volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared_cpu_addr;
- fw_shared->present_flag_0 = 0; + if (drm_dev_enter(&adev->ddev, &idx)) { + fw_shared->present_flag_0 = 0; + drm_dev_exit(idx); + }
amdgpu_virt_free_mm_table(adev);
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index e0c0c3734432e..a0956d8623770 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -22,6 +22,7 @@ */
#include <linux/firmware.h> +#include <drm/drm_drv.h>
#include "amdgpu.h" #include "amdgpu_vcn.h" @@ -233,17 +234,21 @@ static int vcn_v2_5_sw_init(void *handle) */ static int vcn_v2_5_sw_fini(void *handle) { - int i, r; + int i, r, idx; struct amdgpu_device *adev = (struct amdgpu_device *)handle; volatile struct amdgpu_fw_shared *fw_shared;
- for (i = 0; i < adev->vcn.num_vcn_inst; i++) { - if (adev->vcn.harvest_config & (1 << i)) - continue; - fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; - fw_shared->present_flag_0 = 0; + if (drm_dev_enter(&adev->ddev, &idx)) { + for (i = 0; i < adev->vcn.num_vcn_inst; i++) { + if (adev->vcn.harvest_config & (1 << i)) + continue; + fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; + fw_shared->present_flag_0 = 0; + } + drm_dev_exit(idx); }
+ if (amdgpu_sriov_vf(adev)) amdgpu_virt_free_mm_table(adev);
From: Jimmy Kizito Jimmy.Kizito@amd.com
[ Upstream commit 60f39edd897ea134a4ddb789a6795681691c3183 ]
[Why] Links which are dynamically assigned link encoders have their link encoder set to NULL.
[How] Check that a pointer to a link_encoder object is non-NULL before using it.
Reviewed-by: Aric Cyr aric.cyr@amd.com Reviewed-by: Meenakshikumar Somasundaram meenakshikumar.somasundaram@amd.com Acked-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Signed-off-by: Jimmy Kizito Jimmy.Kizito@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 6d655e158267a..61c18637f84dc 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -4690,7 +4690,7 @@ enum dc_status dp_set_fec_ready(struct dc_link *link, bool ready) link_enc->funcs->fec_set_ready(link_enc, true); link->fec_state = dc_link_fec_ready; } else { - link_enc->funcs->fec_set_ready(link->link_enc, false); + link_enc->funcs->fec_set_ready(link_enc, false); link->fec_state = dc_link_fec_not_ready; dm_error("dpcd write failed to set fec_ready"); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index df8a7718a85fc..3af49cdf89ebd 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1522,7 +1522,7 @@ void dcn10_power_down_on_boot(struct dc *dc) for (i = 0; i < dc->link_count; i++) { struct dc_link *link = dc->links[i];
- if (link->link_enc->funcs->is_dig_enabled && + if (link->link_enc && link->link_enc->funcs->is_dig_enabled && link->link_enc->funcs->is_dig_enabled(link->link_enc) && dc->hwss.power_down) { dc->hwss.power_down(dc);
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit adad556efcdd42a1d9e060cbe5f6161cccf1fa28 ]
When complex algorithms that depend on other algorithms are built into the kernel, the order of registration must be done such that the underlying algorithms are ready before the ones on top are registered. As otherwise they would fail during the self-test which is required during registration.
In the past we have used subsystem initialisation ordering to guarantee this. The number of such precedence levels are limited and they may cause ripple effects in other subsystems.
This patch solves this problem by delaying all self-tests during boot-up for built-in algorithms. They will be tested either when something else in the kernel requests for them, or when we have finished registering all built-in algorithms, whichever comes earlier.
Reported-by: Vladis Dronov vdronov@redhat.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/algapi.c | 73 +++++++++++++++++++++++++++++++++-------------- crypto/api.c | 52 +++++++++++++++++++++++++++++---- crypto/internal.h | 10 +++++++ 3 files changed, 108 insertions(+), 27 deletions(-)
diff --git a/crypto/algapi.c b/crypto/algapi.c index 43f999dba4dc0..422bdca214e1c 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -389,29 +389,10 @@ void crypto_remove_final(struct list_head *list) } EXPORT_SYMBOL_GPL(crypto_remove_final);
-static void crypto_wait_for_test(struct crypto_larval *larval) -{ - int err; - - err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult); - if (err != NOTIFY_STOP) { - if (WARN_ON(err != NOTIFY_DONE)) - goto out; - crypto_alg_tested(larval->alg.cra_driver_name, 0); - } - - err = wait_for_completion_killable(&larval->completion); - WARN_ON(err); - if (!err) - crypto_notify(CRYPTO_MSG_ALG_LOADED, larval); - -out: - crypto_larval_kill(&larval->alg); -} - int crypto_register_alg(struct crypto_alg *alg) { struct crypto_larval *larval; + bool test_started; int err;
alg->cra_flags &= ~CRYPTO_ALG_DEAD; @@ -421,12 +402,15 @@ int crypto_register_alg(struct crypto_alg *alg)
down_write(&crypto_alg_sem); larval = __crypto_register_alg(alg); + test_started = static_key_enabled(&crypto_boot_test_finished); + larval->test_started = test_started; up_write(&crypto_alg_sem);
if (IS_ERR(larval)) return PTR_ERR(larval);
- crypto_wait_for_test(larval); + if (test_started) + crypto_wait_for_test(larval); return 0; } EXPORT_SYMBOL_GPL(crypto_register_alg); @@ -633,6 +617,8 @@ int crypto_register_instance(struct crypto_template *tmpl, if (IS_ERR(larval)) goto unlock;
+ larval->test_started = true; + hlist_add_head(&inst->list, &tmpl->instances); inst->tmpl = tmpl;
@@ -1261,9 +1247,48 @@ void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret, EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt); #endif
+static void __init crypto_start_tests(void) +{ + for (;;) { + struct crypto_larval *larval = NULL; + struct crypto_alg *q; + + down_write(&crypto_alg_sem); + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + struct crypto_larval *l; + + if (!crypto_is_larval(q)) + continue; + + l = (void *)q; + + if (!crypto_is_test_larval(l)) + continue; + + if (l->test_started) + continue; + + l->test_started = true; + larval = l; + break; + } + + up_write(&crypto_alg_sem); + + if (!larval) + break; + + crypto_wait_for_test(larval); + } + + static_branch_enable(&crypto_boot_test_finished); +} + static int __init crypto_algapi_init(void) { crypto_init_proc(); + crypto_start_tests(); return 0; }
@@ -1272,7 +1297,11 @@ static void __exit crypto_algapi_exit(void) crypto_exit_proc(); }
-module_init(crypto_algapi_init); +/* + * We run this at late_initcall so that all the built-in algorithms + * have had a chance to register themselves first. + */ +late_initcall(crypto_algapi_init); module_exit(crypto_algapi_exit);
MODULE_LICENSE("GPL"); diff --git a/crypto/api.c b/crypto/api.c index c4eda56cff891..1cf1f03347cc3 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -12,6 +12,7 @@
#include <linux/err.h> #include <linux/errno.h> +#include <linux/jump_label.h> #include <linux/kernel.h> #include <linux/kmod.h> #include <linux/module.h> @@ -30,6 +31,8 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem); BLOCKING_NOTIFIER_HEAD(crypto_chain); EXPORT_SYMBOL_GPL(crypto_chain);
+DEFINE_STATIC_KEY_FALSE(crypto_boot_test_finished); + static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg) @@ -47,11 +50,6 @@ void crypto_mod_put(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_mod_put);
-static inline int crypto_is_test_larval(struct crypto_larval *larval) -{ - return larval->alg.cra_driver_name[0]; -} - static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask) { @@ -163,11 +161,55 @@ void crypto_larval_kill(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_larval_kill);
+void crypto_wait_for_test(struct crypto_larval *larval) +{ + int err; + + err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult); + if (err != NOTIFY_STOP) { + if (WARN_ON(err != NOTIFY_DONE)) + goto out; + crypto_alg_tested(larval->alg.cra_driver_name, 0); + } + + err = wait_for_completion_killable(&larval->completion); + WARN_ON(err); + if (!err) + crypto_notify(CRYPTO_MSG_ALG_LOADED, larval); + +out: + crypto_larval_kill(&larval->alg); +} +EXPORT_SYMBOL_GPL(crypto_wait_for_test); + +static void crypto_start_test(struct crypto_larval *larval) +{ + if (!crypto_is_test_larval(larval)) + return; + + if (larval->test_started) + return; + + down_write(&crypto_alg_sem); + if (larval->test_started) { + up_write(&crypto_alg_sem); + return; + } + + larval->test_started = true; + up_write(&crypto_alg_sem); + + crypto_wait_for_test(larval); +} + static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) { struct crypto_larval *larval = (void *)alg; long timeout;
+ if (!static_branch_likely(&crypto_boot_test_finished)) + crypto_start_test(larval); + timeout = wait_for_completion_killable_timeout( &larval->completion, 60 * HZ);
diff --git a/crypto/internal.h b/crypto/internal.h index f00869af689f5..c08385571853e 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -10,6 +10,7 @@
#include <crypto/algapi.h> #include <linux/completion.h> +#include <linux/jump_label.h> #include <linux/list.h> #include <linux/module.h> #include <linux/notifier.h> @@ -27,6 +28,7 @@ struct crypto_larval { struct crypto_alg *adult; struct completion completion; u32 mask; + bool test_started; };
enum { @@ -45,6 +47,8 @@ extern struct list_head crypto_alg_list; extern struct rw_semaphore crypto_alg_sem; extern struct blocking_notifier_head crypto_chain;
+DECLARE_STATIC_KEY_FALSE(crypto_boot_test_finished); + #ifdef CONFIG_PROC_FS void __init crypto_init_proc(void); void __exit crypto_exit_proc(void); @@ -70,6 +74,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask); void crypto_larval_kill(struct crypto_alg *alg); +void crypto_wait_for_test(struct crypto_larval *larval); void crypto_alg_tested(const char *name, int err);
void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, @@ -156,5 +161,10 @@ static inline void crypto_yield(u32 flags) cond_resched(); }
+static inline int crypto_is_test_larval(struct crypto_larval *larval) +{ + return larval->alg.cra_driver_name[0]; +} + #endif /* _CRYPTO_INTERNAL_H */
From: Petr Machata petrm@nvidia.com
[ Upstream commit b69c99463d414cc263411462d52f25205657e9af ]
The purpose of this test is to verify that after a short activity passes, the reported time is reasonable: not zero (which could be reported by mistake), and not something outrageous (which would be indicative of an issue in used units).
However, the idle time is reported in units of clock_t, or hundredths of second. If the initial sequence of commands is very quick, it is possible that the idle time is reported as just flat-out zero. When this test was recently enabled in our nightly regression, we started seeing spurious failures for exactly this reason.
Therefore buffer the delay leading up to the test with a sleep, to make sure there is no legitimate way of reporting 0.
Signed-off-by: Petr Machata petrm@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/fib_nexthops.sh | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index 0d293391e9a44..b5a69ad191b07 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -2078,6 +2078,7 @@ basic_res() "id 101 index 0 nhid 2 id 101 index 1 nhid 2 id 101 index 2 nhid 1 id 101 index 3 nhid 1" log_test $? 0 "Dump all nexthop buckets in a group"
+ sleep 0.1 (( $($IP -j nexthop bucket list id 101 | jq '[.[] | select(.bucket.idle_time > 0 and .bucket.idle_time < 2)] | length') == 4 ))
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 2a5a8fa8b23144d14567d6f8293dd6fbeecee393 ]
Even with the previous commit 27af8e2c90fb ("leds: trigger: fix potential deadlock with libata") to this file, we still get lockdep unhappy, and Boqun explained the report here: https://lore.kernel.org/r/YNA+d1X4UkoQ7g8a@boqun-archlinux
Effectively, this means that the read_lock_irqsave() isn't enough here because another CPU might be trying to do a write lock, and thus block the readers.
This is all pretty messy, but it doesn't seem right that the LEDs framework imposes some locking requirements on users, in particular we'd have to make the spinlock in the iwlwifi driver always disable IRQs, even if we don't need that for any other reason, just to avoid this deadlock.
Since writes to the led_cdevs list are rare (and are done by userspace), just switch the list to RCU. This costs a synchronize_rcu() at removal time so we can ensure things are correct, but that seems like a small price to pay for getting lock-free iterations and no deadlocks (nor any locking requirements imposed on users.)
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Pavel Machek pavel@ucw.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/led-triggers.c | 41 +++++++++++++++++++------------------ include/linux/leds.h | 2 +- 2 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 4e7b78a84149b..072491d3e17b0 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -157,7 +157,6 @@ EXPORT_SYMBOL_GPL(led_trigger_read); /* Caller must ensure led_cdev->trigger_lock held */ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) { - unsigned long flags; char *event = NULL; char *envp[2]; const char *name; @@ -171,10 +170,13 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
/* Remove any existing trigger */ if (led_cdev->trigger) { - write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); - list_del(&led_cdev->trig_list); - write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, - flags); + spin_lock(&led_cdev->trigger->leddev_list_lock); + list_del_rcu(&led_cdev->trig_list); + spin_unlock(&led_cdev->trigger->leddev_list_lock); + + /* ensure it's no longer visible on the led_cdevs list */ + synchronize_rcu(); + cancel_work_sync(&led_cdev->set_brightness_work); led_stop_software_blink(led_cdev); if (led_cdev->trigger->deactivate) @@ -186,9 +188,9 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) led_set_brightness(led_cdev, LED_OFF); } if (trig) { - write_lock_irqsave(&trig->leddev_list_lock, flags); - list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); - write_unlock_irqrestore(&trig->leddev_list_lock, flags); + spin_lock(&trig->leddev_list_lock); + list_add_tail_rcu(&led_cdev->trig_list, &trig->led_cdevs); + spin_unlock(&trig->leddev_list_lock); led_cdev->trigger = trig;
if (trig->activate) @@ -223,9 +225,10 @@ err_add_groups: trig->deactivate(led_cdev); err_activate:
- write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); - list_del(&led_cdev->trig_list); - write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); + spin_lock(&led_cdev->trigger->leddev_list_lock); + list_del_rcu(&led_cdev->trig_list); + spin_unlock(&led_cdev->trigger->leddev_list_lock); + synchronize_rcu(); led_cdev->trigger = NULL; led_cdev->trigger_data = NULL; led_set_brightness(led_cdev, LED_OFF); @@ -285,7 +288,7 @@ int led_trigger_register(struct led_trigger *trig) struct led_classdev *led_cdev; struct led_trigger *_trig;
- rwlock_init(&trig->leddev_list_lock); + spin_lock_init(&trig->leddev_list_lock); INIT_LIST_HEAD(&trig->led_cdevs);
down_write(&triggers_list_lock); @@ -378,15 +381,14 @@ void led_trigger_event(struct led_trigger *trig, enum led_brightness brightness) { struct led_classdev *led_cdev; - unsigned long flags;
if (!trig) return;
- read_lock_irqsave(&trig->leddev_list_lock, flags); - list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) + rcu_read_lock(); + list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) led_set_brightness(led_cdev, brightness); - read_unlock_irqrestore(&trig->leddev_list_lock, flags); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(led_trigger_event);
@@ -397,20 +399,19 @@ static void led_trigger_blink_setup(struct led_trigger *trig, int invert) { struct led_classdev *led_cdev; - unsigned long flags;
if (!trig) return;
- read_lock_irqsave(&trig->leddev_list_lock, flags); - list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) { + rcu_read_lock(); + list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) { if (oneshot) led_blink_set_oneshot(led_cdev, delay_on, delay_off, invert); else led_blink_set(led_cdev, delay_on, delay_off); } - read_unlock_irqrestore(&trig->leddev_list_lock, flags); + rcu_read_unlock(); }
void led_trigger_blink(struct led_trigger *trig, diff --git a/include/linux/leds.h b/include/linux/leds.h index a0b730be40ad2..ba4861ec73d30 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -360,7 +360,7 @@ struct led_trigger { struct led_hw_trigger_type *trigger_type;
/* LEDs under control by this trigger (for simple triggers) */ - rwlock_t leddev_list_lock; + spinlock_t leddev_list_lock; struct list_head led_cdevs;
/* Link to next registered trigger */
From: Sriram R srirrama@codeaurora.org
[ Upstream commit 69a0fcf8a9f2273040d03e5ee77c9689c09e9d3a ]
During firmware recovery, the default reg rules which are received via WMI_REG_CHAN_LIST_CC_EVENT can overwrite the currently configured user regd.
See below snap for example,
root@OpenWrt:/# iw reg get | grep country country FR: DFS-ETSI country FR: DFS-ETSI country FR: DFS-ETSI country FR: DFS-ETSI
root@OpenWrt:/# echo assert > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/simulate_f w_crash <snip> [ 5290.471696] ath11k c000000.wifi1: pdev 1 successfully recovered
root@OpenWrt:/# iw reg get | grep country country FR: DFS-ETSI country US: DFS-FCC country US: DFS-FCC country US: DFS-FCC
In the above, the user configured country 'FR' is overwritten when the rules of default country 'US' are received and updated during recovery. Hence avoid processing of these rules in general during firmware recovery as they have been already applied during driver registration or after last set user country is configured.
This scenario applies for both AP and STA devices basically because cfg80211 is not aware of the recovery and only the driver recovers, but changing or resetting of the reg domain during recovery is not needed so as to continue with the configured regdomain currently in use.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01460-QCAHKSWPL_SILICONZ-1
Signed-off-by: Sriram R srirrama@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210721212029.142388-3-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/wmi.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 27c060dd3fb47..fa27115483c6c 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5793,6 +5793,17 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk
pdev_idx = reg_info->phy_id;
+ /* Avoid default reg rule updates sent during FW recovery if + * it is already available + */ + spin_lock(&ab->base_lock); + if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) && + ab->default_regd[pdev_idx]) { + spin_unlock(&ab->base_lock); + goto mem_free; + } + spin_unlock(&ab->base_lock); + if (pdev_idx >= ab->num_radios) { /* Process the event for phy0 only if single_pdev_only * is true. If pdev_idx is valid but not 0, discard the
From: Wen Gong wgong@codeaurora.org
[ Upstream commit 441b3b5911f8ead7f2fe2336587b340a33044d58 ]
When wlan interface is up, 11d scan is sent to the firmware, and the firmware needs to spend couple of seconds to complete the 11d scan. If immediately a normal scan from user space arrives to ath11k, then the normal scan request is also sent to the firmware, but the scan started event will be reported to ath11k until the 11d scan complete. When timed out for the scan started in ath11k, ath11k stops the normal scan and the firmware reports WMI_SCAN_EVENT_DEQUEUED to ath11k for the normal scan. ath11k has no handler for the event and then timed out for the scan completed in ath11k_scan_stop(), and ath11k prints the following error message.
[ 1491.604750] ath11k_pci 0000:02:00.0: failed to receive scan abort comple: timed out [ 1491.604756] ath11k_pci 0000:02:00.0: failed to stop scan: -110 [ 1491.604758] ath11k_pci 0000:02:00.0: failed to start hw scan: -110
Add a handler for WMI_SCAN_EVENT_DEQUEUED and then complete the scan to get rid of the above error message.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Signed-off-by: Wen Gong wgong@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210914164226.38843-1-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/wmi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index fa27115483c6c..72da1283f2ccb 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -6313,6 +6313,8 @@ static void ath11k_scan_event(struct ath11k_base *ab, struct sk_buff *skb) ath11k_wmi_event_scan_start_failed(ar); break; case WMI_SCAN_EVENT_DEQUEUED: + __ath11k_mac_scan_finish(ar); + break; case WMI_SCAN_EVENT_PREEMPTED: case WMI_SCAN_EVENT_RESTARTED: case WMI_SCAN_EVENT_FOREIGN_CHAN_EXIT:
From: Baochen Qiang bqiang@codeaurora.org
[ Upstream commit 86a03dad0f5ad8182ed5fcf7bf3eec71cd96577c ]
For fragmented packets, ath11k reassembles each fragment as a normal packet and then reinjects it into HW ring. In this case, the DMA direction should be DMA_TO_DEVICE, not DMA_FROM_DEVICE, otherwise invalid payload will be reinjected to HW and then delivered to host. What is more, since arbitrary memory could be allocated to the frame, we don't know what kind of data is contained in the buffer reinjected. Thus, as a bad result, private info may be leaked.
Note that this issue is only found on Intel platform.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Baochen Qiang bqiang@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210916064617.20006-1-bqiang@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/dp_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 9a224817630ae..af0a600ea067c 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -3310,7 +3310,7 @@ static int ath11k_dp_rx_h_defrag_reo_reinject(struct ath11k *ar, struct dp_rx_ti
paddr = dma_map_single(ab->dev, defrag_skb->data, defrag_skb->len + skb_tailroom(defrag_skb), - DMA_FROM_DEVICE); + DMA_TO_DEVICE); if (dma_mapping_error(ab->dev, paddr)) return -ENOMEM;
@@ -3375,7 +3375,7 @@ err_free_idr: spin_unlock_bh(&rx_refill_ring->idr_lock); err_unmap_dma: dma_unmap_single(ab->dev, paddr, defrag_skb->len + skb_tailroom(defrag_skb), - DMA_FROM_DEVICE); + DMA_TO_DEVICE); return ret; }
From: Alagu Sankar alagusankar@silex-india.com
[ Upstream commit e263bdab9c0e8025fb7f41f153709a9cda51f6b6 ]
Beacon buffer for high latency devices does not use DMA. other similar buffer allocation methods in the driver have already been modified for high latency path. Fix the beacon buffer allocation left out in the earlier high latency changes.
Signed-off-by: Alagu Sankar alagusankar@silex-india.com Signed-off-by: Erik Stromdahl erik.stromdahl@gmail.com [fabio: adapt it to use ar->bus_param.dev_type ] Signed-off-by: Fabio Estevam festevam@denx.de Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210818232627.2040121-1-festevam@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/mac.c | 31 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index c272b290fa73d..7ca68c81d9b61 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -993,8 +993,12 @@ static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif) ath10k_mac_vif_beacon_free(arvif);
if (arvif->beacon_buf) { - dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, - arvif->beacon_buf, arvif->beacon_paddr); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) + kfree(arvif->beacon_buf); + else + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, + arvif->beacon_paddr); arvif->beacon_buf = NULL; } } @@ -5576,10 +5580,17 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_ADHOC || vif->type == NL80211_IFTYPE_MESH_POINT || vif->type == NL80211_IFTYPE_AP) { - arvif->beacon_buf = dma_alloc_coherent(ar->dev, - IEEE80211_MAX_FRAME_LEN, - &arvif->beacon_paddr, - GFP_ATOMIC); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) { + arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN, + GFP_KERNEL); + arvif->beacon_paddr = (dma_addr_t)arvif->beacon_buf; + } else { + arvif->beacon_buf = + dma_alloc_coherent(ar->dev, + IEEE80211_MAX_FRAME_LEN, + &arvif->beacon_paddr, + GFP_ATOMIC); + } if (!arvif->beacon_buf) { ret = -ENOMEM; ath10k_warn(ar, "failed to allocate beacon buffer: %d\n", @@ -5794,8 +5805,12 @@ err_vdev_delete:
err: if (arvif->beacon_buf) { - dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, - arvif->beacon_buf, arvif->beacon_paddr); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) + kfree(arvif->beacon_buf); + else + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, + arvif->beacon_paddr); arvif->beacon_buf = NULL; }
From: Rakesh Babu rsaladi2@marvell.com
[ Upstream commit ffd2f89ad05cd620d822112a07b0c5669fa9e333 ]
Whenever the interface is brought up/down then set_rx_mode function is called by the stack which enables promisc/allmulti MCAM entries. But there are cases when driver brings interface down and then up such as while changing number of channels. In these cases promisc/allmulti MCAM entries are left disabled as set_rx_mode callback is not called. This patch enables these MCAM entries in all such cases.
Signed-off-by: Rakesh Babu rsaladi2@marvell.com Signed-off-by: Subbaraya Sundeep sbhatta@marvell.com Signed-off-by: Sunil Goutham sgoutham@marvell.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../ethernet/marvell/octeontx2/nic/otx2_pf.c | 78 ++++++++++--------- 1 file changed, 43 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 53df7fff92c40..53a3e8de1a51e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1493,6 +1493,44 @@ static void otx2_free_hw_resources(struct otx2_nic *pf) mutex_unlock(&mbox->lock); }
+static void otx2_do_set_rx_mode(struct otx2_nic *pf) +{ + struct net_device *netdev = pf->netdev; + struct nix_rx_mode *req; + bool promisc = false; + + if (!(netdev->flags & IFF_UP)) + return; + + if ((netdev->flags & IFF_PROMISC) || + (netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) { + promisc = true; + } + + /* Write unicast address to mcam entries or del from mcam */ + if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT) + __dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter); + + mutex_lock(&pf->mbox.lock); + req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox); + if (!req) { + mutex_unlock(&pf->mbox.lock); + return; + } + + req->mode = NIX_RX_MODE_UCAST; + + if (promisc) + req->mode |= NIX_RX_MODE_PROMISC; + if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) + req->mode |= NIX_RX_MODE_ALLMULTI; + + req->mode |= NIX_RX_MODE_USE_MCE; + + otx2_sync_mbox_msg(&pf->mbox); + mutex_unlock(&pf->mbox.lock); +} + int otx2_open(struct net_device *netdev) { struct otx2_nic *pf = netdev_priv(netdev); @@ -1646,6 +1684,8 @@ int otx2_open(struct net_device *netdev) if (err) goto err_tx_stop_queues;
+ otx2_do_set_rx_mode(pf); + return 0;
err_tx_stop_queues: @@ -1791,43 +1831,11 @@ static void otx2_set_rx_mode(struct net_device *netdev) queue_work(pf->otx2_wq, &pf->rx_mode_work); }
-static void otx2_do_set_rx_mode(struct work_struct *work) +static void otx2_rx_mode_wrk_handler(struct work_struct *work) { struct otx2_nic *pf = container_of(work, struct otx2_nic, rx_mode_work); - struct net_device *netdev = pf->netdev; - struct nix_rx_mode *req; - bool promisc = false; - - if (!(netdev->flags & IFF_UP)) - return; - - if ((netdev->flags & IFF_PROMISC) || - (netdev_uc_count(netdev) > OTX2_MAX_UNICAST_FLOWS)) { - promisc = true; - }
- /* Write unicast address to mcam entries or del from mcam */ - if (!promisc && netdev->priv_flags & IFF_UNICAST_FLT) - __dev_uc_sync(netdev, otx2_add_macfilter, otx2_del_macfilter); - - mutex_lock(&pf->mbox.lock); - req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox); - if (!req) { - mutex_unlock(&pf->mbox.lock); - return; - } - - req->mode = NIX_RX_MODE_UCAST; - - if (promisc) - req->mode |= NIX_RX_MODE_PROMISC; - if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST)) - req->mode |= NIX_RX_MODE_ALLMULTI; - - req->mode |= NIX_RX_MODE_USE_MCE; - - otx2_sync_mbox_msg(&pf->mbox); - mutex_unlock(&pf->mbox.lock); + otx2_do_set_rx_mode(pf); }
static int otx2_set_features(struct net_device *netdev, @@ -2358,7 +2366,7 @@ static int otx2_wq_init(struct otx2_nic *pf) if (!pf->otx2_wq) return -ENOMEM;
- INIT_WORK(&pf->rx_mode_work, otx2_do_set_rx_mode); + INIT_WORK(&pf->rx_mode_work, otx2_rx_mode_wrk_handler); INIT_WORK(&pf->reset_task, otx2_reset_task); return 0; }
From: Dirk Bender d.bender@phytec.de
[ Upstream commit 0961ba6dd211a4a52d1dd4c2d59be60ac2dc08c7 ]
To prevent corrupted frames after starting and stopping the sensor its datasheet specifies a specific pause sequence to follow:
Stopping: Set Pause_Restart Bit -> Set Restart Bit -> Set Chip_Enable Off
Restarting: Set Chip_Enable On -> Clear Pause_Restart Bit
The Restart Bit is cleared automatically and must not be cleared manually as this would cause undefined behavior.
Signed-off-by: Dirk Bender d.bender@phytec.de Signed-off-by: Stefan Riedmueller s.riedmueller@phytec.de Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/mt9p031.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 6eb88ef997836..3ae1b28c8351b 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -78,7 +78,9 @@ #define MT9P031_PIXEL_CLOCK_INVERT (1 << 15) #define MT9P031_PIXEL_CLOCK_SHIFT(n) ((n) << 8) #define MT9P031_PIXEL_CLOCK_DIVIDE(n) ((n) << 0) -#define MT9P031_FRAME_RESTART 0x0b +#define MT9P031_RESTART 0x0b +#define MT9P031_FRAME_PAUSE_RESTART (1 << 1) +#define MT9P031_FRAME_RESTART (1 << 0) #define MT9P031_SHUTTER_DELAY 0x0c #define MT9P031_RST 0x0d #define MT9P031_RST_ENABLE 1 @@ -444,9 +446,23 @@ static int mt9p031_set_params(struct mt9p031 *mt9p031) static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); + struct i2c_client *client = v4l2_get_subdevdata(subdev); + int val; int ret;
if (!enable) { + /* enable pause restart */ + val = MT9P031_FRAME_PAUSE_RESTART; + ret = mt9p031_write(client, MT9P031_RESTART, val); + if (ret < 0) + return ret; + + /* enable restart + keep pause restart set */ + val |= MT9P031_FRAME_RESTART; + ret = mt9p031_write(client, MT9P031_RESTART, val); + if (ret < 0) + return ret; + /* Stop sensor readout */ ret = mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN, 0); @@ -466,6 +482,16 @@ static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable) if (ret < 0) return ret;
+ /* + * - clear pause restart + * - don't clear restart as clearing restart manually can cause + * undefined behavior + */ + val = MT9P031_FRAME_RESTART; + ret = mt9p031_write(client, MT9P031_RESTART, val); + if (ret < 0) + return ret; + return mt9p031_pll_enable(mt9p031); }
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit dbb4cfea6efe979ed153bd59a6a527a90d3d0ab3 ]
The interrupt handling should be related to the firmware version. If the driver matches an old firmware, then the driver should not handle interrupt such as i2c or dma, otherwise it will cause some errors.
This log reveals it:
[ 27.708641] INFO: trying to register non-static key. [ 27.710851] The code is fine but needs lockdep annotation, or maybe [ 27.712010] you didn't initialize this object before use? [ 27.712396] turning off the locking correctness validator. [ 27.712787] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.12.4-g70e7f0549188-dirty #169 [ 27.713349] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 [ 27.714149] Call Trace: [ 27.714329] <IRQ> [ 27.714480] dump_stack+0xba/0xf5 [ 27.714737] register_lock_class+0x873/0x8f0 [ 27.715052] ? __lock_acquire+0x323/0x1930 [ 27.715353] __lock_acquire+0x75/0x1930 [ 27.715636] lock_acquire+0x1dd/0x3e0 [ 27.715905] ? netup_i2c_interrupt+0x19/0x310 [ 27.716226] _raw_spin_lock_irqsave+0x4b/0x60 [ 27.716544] ? netup_i2c_interrupt+0x19/0x310 [ 27.716863] netup_i2c_interrupt+0x19/0x310 [ 27.717178] netup_unidvb_isr+0xd3/0x160 [ 27.717467] __handle_irq_event_percpu+0x53/0x3e0 [ 27.717808] handle_irq_event_percpu+0x35/0x90 [ 27.718129] handle_irq_event+0x39/0x60 [ 27.718409] handle_fasteoi_irq+0xc2/0x1d0 [ 27.718707] __common_interrupt+0x7f/0x150 [ 27.719008] common_interrupt+0xb4/0xd0 [ 27.719289] </IRQ> [ 27.719446] asm_common_interrupt+0x1e/0x40 [ 27.719747] RIP: 0010:native_safe_halt+0x17/0x20 [ 27.720084] Code: 07 0f 00 2d 8b ee 4c 00 f4 5d c3 0f 1f 84 00 00 00 00 00 8b 05 72 95 17 02 55 48 89 e5 85 c0 7e 07 0f 00 2d 6b ee 4c 00 fb f4 <5d> c3 cc cc cc cc cc cc cc 55 48 89 e5 e8 67 53 ff ff 8b 0d 29 f6 [ 27.721386] RSP: 0018:ffffc9000008fe90 EFLAGS: 00000246 [ 27.721758] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 0000000000000000 [ 27.722262] RDX: 0000000000000000 RSI: ffffffff85f7c054 RDI: ffffffff85ded4e6 [ 27.722770] RBP: ffffc9000008fe90 R08: 0000000000000001 R09: 0000000000000001 [ 27.723277] R10: 0000000000000000 R11: 0000000000000001 R12: ffffffff86a75408 [ 27.723781] R13: 0000000000000000 R14: 0000000000000000 R15: ffff888100260000 [ 27.724289] default_idle+0x9/0x10 [ 27.724537] arch_cpu_idle+0xa/0x10 [ 27.724791] default_idle_call+0x6e/0x250 [ 27.725082] do_idle+0x1f0/0x2d0 [ 27.725326] cpu_startup_entry+0x18/0x20 [ 27.725613] start_secondary+0x11f/0x160 [ 27.725902] secondary_startup_64_no_verify+0xb0/0xbb [ 27.726272] BUG: kernel NULL pointer dereference, address: 0000000000000002 [ 27.726768] #PF: supervisor read access in kernel mode [ 27.727138] #PF: error_code(0x0000) - not-present page [ 27.727507] PGD 8000000118688067 P4D 8000000118688067 PUD 10feab067 PMD 0 [ 27.727999] Oops: 0000 [#1] PREEMPT SMP PTI [ 27.728302] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 5.12.4-g70e7f0549188-dirty #169 [ 27.728861] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 [ 27.729660] RIP: 0010:netup_i2c_interrupt+0x23/0x310 [ 27.730019] Code: 0f 1f 80 00 00 00 00 55 48 89 e5 41 55 41 54 53 48 89 fb e8 af 6e 95 fd 48 89 df e8 e7 9f 1c 01 49 89 c5 48 8b 83 48 08 00 00 <66> 44 8b 60 02 44 89 e0 48 8b 93 48 08 00 00 83 e0 f8 66 89 42 02 [ 27.731339] RSP: 0018:ffffc90000118e90 EFLAGS: 00010046 [ 27.731716] RAX: 0000000000000000 RBX: ffff88810803c4d8 RCX: 0000000000000000 [ 27.732223] RDX: 0000000000000001 RSI: ffffffff85d37b94 RDI: ffff88810803c4d8 [ 27.732727] RBP: ffffc90000118ea8 R08: 0000000000000000 R09: 0000000000000001 [ 27.733239] R10: ffff88810803c4f0 R11: 61646e6f63657320 R12: 0000000000000000 [ 27.733745] R13: 0000000000000046 R14: ffff888101041000 R15: ffff8881081b2400 [ 27.734251] FS: 0000000000000000(0000) GS:ffff88817bc80000(0000) knlGS:0000000000000000 [ 27.734821] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 27.735228] CR2: 0000000000000002 CR3: 0000000108194000 CR4: 00000000000006e0 [ 27.735735] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 27.736241] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 27.736744] Call Trace: [ 27.736924] <IRQ> [ 27.737074] netup_unidvb_isr+0xd3/0x160 [ 27.737363] __handle_irq_event_percpu+0x53/0x3e0 [ 27.737706] handle_irq_event_percpu+0x35/0x90 [ 27.738028] handle_irq_event+0x39/0x60 [ 27.738306] handle_fasteoi_irq+0xc2/0x1d0 [ 27.738602] __common_interrupt+0x7f/0x150 [ 27.738899] common_interrupt+0xb4/0xd0 [ 27.739176] </IRQ> [ 27.739331] asm_common_interrupt+0x1e/0x40 [ 27.739633] RIP: 0010:native_safe_halt+0x17/0x20 [ 27.739967] Code: 07 0f 00 2d 8b ee 4c 00 f4 5d c3 0f 1f 84 00 00 00 00 00 8b 05 72 95 17 02 55 48 89 e5 85 c0 7e 07 0f 00 2d 6b ee 4c 00 fb f4 <5d> c3 cc cc cc cc cc cc cc 55 48 89 e5 e8 67 53 ff ff 8b 0d 29 f6 [ 27.741275] RSP: 0018:ffffc9000008fe90 EFLAGS: 00000246 [ 27.741647] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 0000000000000000 [ 27.742148] RDX: 0000000000000000 RSI: ffffffff85f7c054 RDI: ffffffff85ded4e6 [ 27.742652] RBP: ffffc9000008fe90 R08: 0000000000000001 R09: 0000000000000001 [ 27.743154] R10: 0000000000000000 R11: 0000000000000001 R12: ffffffff86a75408 [ 27.743652] R13: 0000000000000000 R14: 0000000000000000 R15: ffff888100260000 [ 27.744157] default_idle+0x9/0x10 [ 27.744405] arch_cpu_idle+0xa/0x10 [ 27.744658] default_idle_call+0x6e/0x250 [ 27.744948] do_idle+0x1f0/0x2d0 [ 27.745190] cpu_startup_entry+0x18/0x20 [ 27.745475] start_secondary+0x11f/0x160 [ 27.745761] secondary_startup_64_no_verify+0xb0/0xbb [ 27.746123] Modules linked in: [ 27.746348] Dumping ftrace buffer: [ 27.746596] (ftrace buffer empty) [ 27.746852] CR2: 0000000000000002 [ 27.747094] ---[ end trace ebafd46f83ab946d ]--- [ 27.747424] RIP: 0010:netup_i2c_interrupt+0x23/0x310 [ 27.747778] Code: 0f 1f 80 00 00 00 00 55 48 89 e5 41 55 41 54 53 48 89 fb e8 af 6e 95 fd 48 89 df e8 e7 9f 1c 01 49 89 c5 48 8b 83 48 08 00 00 <66> 44 8b 60 02 44 89 e0 48 8b 93 48 08 00 00 83 e0 f8 66 89 42 02 [ 27.749082] RSP: 0018:ffffc90000118e90 EFLAGS: 00010046 [ 27.749461] RAX: 0000000000000000 RBX: ffff88810803c4d8 RCX: 0000000000000000 [ 27.749966] RDX: 0000000000000001 RSI: ffffffff85d37b94 RDI: ffff88810803c4d8 [ 27.750471] RBP: ffffc90000118ea8 R08: 0000000000000000 R09: 0000000000000001 [ 27.750976] R10: ffff88810803c4f0 R11: 61646e6f63657320 R12: 0000000000000000 [ 27.751480] R13: 0000000000000046 R14: ffff888101041000 R15: ffff8881081b2400 [ 27.751986] FS: 0000000000000000(0000) GS:ffff88817bc80000(0000) knlGS:0000000000000000 [ 27.752560] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 27.752970] CR2: 0000000000000002 CR3: 0000000108194000 CR4: 00000000000006e0 [ 27.753481] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 27.753984] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 27.754487] Kernel panic - not syncing: Fatal exception in interrupt [ 27.755033] Dumping ftrace buffer: [ 27.755279] (ftrace buffer empty) [ 27.755534] Kernel Offset: disabled [ 27.755785] Rebooting in 1 seconds..
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../pci/netup_unidvb/netup_unidvb_core.c | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c index 6f3125c2d0976..77bae14685513 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -258,19 +258,24 @@ static irqreturn_t netup_unidvb_isr(int irq, void *dev_id) if ((reg40 & AVL_IRQ_ASSERTED) != 0) { /* IRQ is being signaled */ reg_isr = readw(ndev->bmmio0 + REG_ISR); - if (reg_isr & NETUP_UNIDVB_IRQ_I2C0) { - iret = netup_i2c_interrupt(&ndev->i2c[0]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_I2C1) { - iret = netup_i2c_interrupt(&ndev->i2c[1]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_SPI) { + if (reg_isr & NETUP_UNIDVB_IRQ_SPI) iret = netup_spi_interrupt(ndev->spi); - } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA1) { - iret = netup_dma_interrupt(&ndev->dma[0]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA2) { - iret = netup_dma_interrupt(&ndev->dma[1]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_CI) { - iret = netup_ci_interrupt(ndev); + else if (!ndev->old_fw) { + if (reg_isr & NETUP_UNIDVB_IRQ_I2C0) { + iret = netup_i2c_interrupt(&ndev->i2c[0]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_I2C1) { + iret = netup_i2c_interrupt(&ndev->i2c[1]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA1) { + iret = netup_dma_interrupt(&ndev->dma[0]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA2) { + iret = netup_dma_interrupt(&ndev->dma[1]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_CI) { + iret = netup_ci_interrupt(ndev); + } else { + goto err; + } } else { +err: dev_err(&pci_dev->dev, "%s(): unknown interrupt 0x%x\n", __func__, reg_isr);
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit e16f5e39acd6d10cc63ae39bc0a77188ed828f22 ]
There were several issues with handling errors in lm3554_probe(): - Probe did not set the error code when v4l2_ctrl_handler_init() failed. - It intermixed gotos for handling errors of v4l2_ctrl_handler_init() and media_entity_pads_init(). - It did not set the error code for failures of v4l2_ctrl_new_custom(). - Probe did not free resources in case of failures of atomisp_register_i2c_module().
The patch fixes all these issues.
Found by Linux Driver Verification project (linuxtesting.org).
Link: https://lore.kernel.org/linux-media/20210810162943.19852-1-novikov@ispras.ru Signed-off-by: Evgeny Novikov novikov@ispras.ru Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/atomisp/i2c/atomisp-lm3554.c | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c index 362ed44b4effa..e046489cd253b 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c @@ -835,7 +835,6 @@ static int lm3554_probe(struct i2c_client *client) int err = 0; struct lm3554 *flash; unsigned int i; - int ret;
flash = kzalloc(sizeof(*flash), GFP_KERNEL); if (!flash) @@ -844,7 +843,7 @@ static int lm3554_probe(struct i2c_client *client) flash->pdata = lm3554_platform_data_func(client); if (IS_ERR(flash->pdata)) { err = PTR_ERR(flash->pdata); - goto fail1; + goto free_flash; }
v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); @@ -852,12 +851,12 @@ static int lm3554_probe(struct i2c_client *client) flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; flash->mode = ATOMISP_FLASH_MODE_OFF; flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1; - ret = + err = v4l2_ctrl_handler_init(&flash->ctrl_handler, ARRAY_SIZE(lm3554_controls)); - if (ret) { + if (err) { dev_err(&client->dev, "error initialize a ctrl_handler.\n"); - goto fail3; + goto unregister_subdev; }
for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++) @@ -866,14 +865,15 @@ static int lm3554_probe(struct i2c_client *client)
if (flash->ctrl_handler.error) { dev_err(&client->dev, "ctrl_handler error.\n"); - goto fail3; + err = flash->ctrl_handler.error; + goto free_handler; }
flash->sd.ctrl_handler = &flash->ctrl_handler; err = media_entity_pads_init(&flash->sd.entity, 0, NULL); if (err) { dev_err(&client->dev, "error initialize a media entity.\n"); - goto fail2; + goto free_handler; }
flash->sd.entity.function = MEDIA_ENT_F_FLASH; @@ -884,16 +884,27 @@ static int lm3554_probe(struct i2c_client *client)
err = lm3554_gpio_init(client); if (err) { - dev_err(&client->dev, "gpio request/direction_output fail"); - goto fail3; + dev_err(&client->dev, "gpio request/direction_output fail.\n"); + goto cleanup_media; + } + + err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH); + if (err) { + dev_err(&client->dev, "fail to register atomisp i2c module.\n"); + goto uninit_gpio; } - return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH); -fail3: + + return 0; + +uninit_gpio: + lm3554_gpio_uninit(client); +cleanup_media: media_entity_cleanup(&flash->sd.entity); +free_handler: v4l2_ctrl_handler_free(&flash->ctrl_handler); -fail2: +unregister_subdev: v4l2_device_unregister_subdev(&flash->sd); -fail1: +free_flash: kfree(flash);
return err;
From: Dmitriy Ulitin ulitin@ispras.ru
[ Upstream commit 548fa43a58696450c15b8f5564e99589c5144664 ]
At the moment of enabling irq handling:
1922 ret = devm_request_threaded_irq(&pdev->dev, irq, dcmi_irq_callback, 1923 dcmi_irq_thread, IRQF_ONESHOT, 1924 dev_name(&pdev->dev), dcmi);
there is still uninitialized field sd_format of struct stm32_dcmi *dcmi. If an interrupt occurs in the interval between the installation of the interrupt handler and the initialization of this field, NULL pointer dereference happens.
This field is dereferenced in the handler function without any check:
457 if (dcmi->sd_format->fourcc == V4L2_PIX_FMT_JPEG && 458 dcmi->misr & IT_FRAME) {
The patch moves interrupt handler installation after initialization of the sd_format field that happens in dcmi_graph_notify_complete() via dcmi_set_default_fmt().
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Dmitriy Ulitin ulitin@ispras.ru Signed-off-by: Alexey Khoroshilov khoroshilov@ispras.ru Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/stm32/stm32-dcmi.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index d914ccef98317..6110718645a4f 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -128,6 +128,7 @@ struct stm32_dcmi { int sequence; struct list_head buffers; struct dcmi_buf *active; + int irq;
struct v4l2_device v4l2_dev; struct video_device *vdev; @@ -1759,6 +1760,14 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) return ret; }
+ ret = devm_request_threaded_irq(dcmi->dev, dcmi->irq, dcmi_irq_callback, + dcmi_irq_thread, IRQF_ONESHOT, + dev_name(dcmi->dev), dcmi); + if (ret) { + dev_err(dcmi->dev, "Unable to request irq %d\n", dcmi->irq); + return ret; + } + return 0; }
@@ -1914,6 +1923,8 @@ static int dcmi_probe(struct platform_device *pdev) if (irq <= 0) return irq ? irq : -ENXIO;
+ dcmi->irq = irq; + dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dcmi->res) { dev_err(&pdev->dev, "Could not get resource\n"); @@ -1926,14 +1937,6 @@ static int dcmi_probe(struct platform_device *pdev) return PTR_ERR(dcmi->regs); }
- ret = devm_request_threaded_irq(&pdev->dev, irq, dcmi_irq_callback, - dcmi_irq_thread, IRQF_ONESHOT, - dev_name(&pdev->dev), dcmi); - if (ret) { - dev_err(&pdev->dev, "Unable to request irq %d\n", irq); - return ret; - } - mclk = devm_clk_get(&pdev->dev, "mclk"); if (IS_ERR(mclk)) { if (PTR_ERR(mclk) != -EPROBE_DEFER)
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit 97a2777a96070afb7da5d587834086c0b586c8cc ]
Fixes v4l2-compliance:
Format ioctls (Input 0): warn: v4l2-test-formats.cpp(1339): S_PARM is supported but doesn't report V4L2_CAP_TIMEPERFRAME fail: v4l2-test-formats.cpp(1241): node->has_frmintervals && !cap->capability
Reviewed-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_v4l2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 6acb8013de08b..c9d208677bcd8 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -472,10 +472,13 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, uvc_simplify_fraction(&timeperframe.numerator, &timeperframe.denominator, 8, 333);
- if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { parm->parm.capture.timeperframe = timeperframe; - else + parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + } else { parm->parm.output.timeperframe = timeperframe; + parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; + }
return 0; }
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit ffccdde5f0e17d2f0d788a9d831a027187890eaa ]
The device is doing something unexpected with the control. Either because the protocol is not properly implemented or there has been a HW error.
Fixes v4l2-compliance:
Control ioctls (Input 0): fail: v4l2-test-controls.cpp(448): s_ctrl returned an error (22) test VIDIOC_G/S_CTRL: FAIL fail: v4l2-test-controls.cpp(698): s_ext_ctrls returned an error (22) test VIDIOC_G/S/TRY_EXT_CTRLS: FAIL
Reviewed-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_video.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index e16464606b140..9f37eaf28ce7e 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -115,6 +115,11 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, case 5: /* Invalid unit */ case 6: /* Invalid control */ case 7: /* Invalid Request */ + /* + * The firmware has not properly implemented + * the control or there has been a HW error. + */ + return -EIO; case 8: /* Invalid value within range */ return -EINVAL; default: /* reserved or unknown */
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit e3f60e7e1a2b451f538f9926763432249bcf39c4 ]
All the entities must have a unique name. We can have a descriptive and unique name by appending the function and the entity->id.
This is even resilent to multi chain devices.
Fixes v4l2-compliance: Media Controller ioctls: fail: v4l2-test-media.cpp(205): v2_entity_names_set.find(key) != v2_entity_names_set.end() test MEDIA_IOC_G_TOPOLOGY: FAIL fail: v4l2-test-media.cpp(394): num_data_links != num_links test MEDIA_IOC_ENUM_ENTITIES/LINKS: FAIL
Signed-off-by: Ricardo Ribalda ribalda@chromium.org Reviewed-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_driver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 9a791d8ef200d..c4bc67024534a 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2194,6 +2194,7 @@ int uvc_register_video_device(struct uvc_device *dev, const struct v4l2_file_operations *fops, const struct v4l2_ioctl_ops *ioctl_ops) { + const char *name; int ret;
/* Initialize the video buffers queue. */ @@ -2222,16 +2223,20 @@ int uvc_register_video_device(struct uvc_device *dev, case V4L2_BUF_TYPE_VIDEO_CAPTURE: default: vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + name = "Video Capture"; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; + name = "Video Output"; break; case V4L2_BUF_TYPE_META_CAPTURE: vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; + name = "Metadata"; break; }
- strscpy(vdev->name, dev->name, sizeof(vdev->name)); + snprintf(vdev->name, sizeof(vdev->name), "%s %u", name, + stream->header.bTerminalLink);
/* * Set the driver data before calling video_register_device, otherwise
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 76e21bb8be4f5f987f3006d197196fe6af63f656 ]
vidtv_bridge_remove() releases and cleans up everything except for dvb itself. The patch adds this missed release.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/test-drivers/vidtv/vidtv_bridge.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index 75617709c8ce2..0f6d998d18dc0 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -557,6 +557,7 @@ static int vidtv_bridge_remove(struct platform_device *pdev) dvb_dmxdev_release(&dvb->dmx_dev); dvb_dmx_release(&dvb->demux); dvb_unregister_adapter(&dvb->adapter); + kfree(dvb); dev_info(&pdev->dev, "Successfully removed vidtv\n");
return 0;
From: Tuo Li islituo@gmail.com
[ Upstream commit 8515965e5e33f4feb56134348c95953f3eadfb26 ]
The variable pdev is assigned to dev->plat_dev, and dev->plat_dev is checked in: if (!dev->plat_dev)
This indicates both dev->plat_dev and pdev can be NULL. If so, the function dev_err() is called to print error information. dev_err(&pdev->dev, "No platform data specified\n");
However, &pdev->dev is an illegal address, and it is dereferenced in dev_err().
To fix this possible null-pointer dereference, replace dev_err() with mfc_err().
Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Tuo Li islituo@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index eba2b9f040df0..c763c0a03140c 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1283,7 +1283,7 @@ static int s5p_mfc_probe(struct platform_device *pdev) spin_lock_init(&dev->condlock); dev->plat_dev = pdev; if (!dev->plat_dev) { - dev_err(&pdev->dev, "No platform data specified\n"); + mfc_err("No platform data specified\n"); return -ENODEV; }
From: Nadezda Lutovinova lutovinova@ispras.ru
[ Upstream commit cdfaf4752e6915a4b455ad4400133e540e4dc965 ]
If of_device_get_match_data() return NULL, then null pointer dereference occurs in s5p_mfc_init_pm(). The patch adds checking if dev->variant is NULL.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Nadezda Lutovinova lutovinova@ispras.ru Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/s5p-mfc/s5p_mfc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c index c763c0a03140c..f336a95432732 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1288,6 +1288,10 @@ static int s5p_mfc_probe(struct platform_device *pdev) }
dev->variant = of_device_get_match_data(&pdev->dev); + if (!dev->variant) { + dev_err(&pdev->dev, "Failed to get device MFC hardware variant information\n"); + return -ENOENT; + }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->regs_base = devm_ioremap_resource(&pdev->dev, res);
From: Sergey Senozhatsky senozhatsky@chromium.org
[ Upstream commit a4b83deb3e76fb9385ca58e2c072a145b3a320d6 ]
With the new DMA API we need an extension of the videobuf2 API. Previously, videobuf2 core would set the non-coherent DMA bit in the vb2_queue dma_attr field (if user-space would pass a corresponding memory hint); the vb2 core then would pass the vb2_queue dma_attrs to the vb2 allocators. The vb2 allocator would use the queue's dma_attr and the DMA API would allocate either coherent or non-coherent memory.
But we cannot do this anymore, since there is no corresponding DMA attr flag and, hence, there is no way for the allocator to become aware of what type of allocation user-space has requested. So we need to pass more context from videobuf2 core to the allocators.
Fix this by changing the call_ptr_memop() macro to pass the vb2 pointer to the corresponding op callbacks.
Signed-off-by: Sergey Senozhatsky senozhatsky@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../media/common/videobuf2/videobuf2-core.c | 42 +++++++++++-------- .../common/videobuf2/videobuf2-dma-contig.c | 36 +++++++++------- .../media/common/videobuf2/videobuf2-dma-sg.c | 33 ++++++++------- .../common/videobuf2/videobuf2-vmalloc.c | 30 ++++++------- include/media/videobuf2-core.h | 37 ++++++++-------- 5 files changed, 98 insertions(+), 80 deletions(-)
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 508ac295eb06e..033b0c83272fe 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -68,13 +68,13 @@ module_param(debug, int, 0644); err; \ })
-#define call_ptr_memop(vb, op, args...) \ +#define call_ptr_memop(op, vb, args...) \ ({ \ struct vb2_queue *_q = (vb)->vb2_queue; \ void *ptr; \ \ log_memop(vb, op); \ - ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL; \ + ptr = _q->mem_ops->op ? _q->mem_ops->op(vb, args) : NULL; \ if (!IS_ERR_OR_NULL(ptr)) \ (vb)->cnt_mem_ ## op++; \ ptr; \ @@ -144,9 +144,9 @@ module_param(debug, int, 0644); ((vb)->vb2_queue->mem_ops->op ? \ (vb)->vb2_queue->mem_ops->op(args) : 0)
-#define call_ptr_memop(vb, op, args...) \ +#define call_ptr_memop(op, vb, args...) \ ((vb)->vb2_queue->mem_ops->op ? \ - (vb)->vb2_queue->mem_ops->op(args) : NULL) + (vb)->vb2_queue->mem_ops->op(vb, args) : NULL)
#define call_void_memop(vb, op, args...) \ do { \ @@ -230,9 +230,10 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) if (size < vb->planes[plane].length) goto free;
- mem_priv = call_ptr_memop(vb, alloc, - q->alloc_devs[plane] ? : q->dev, - q->dma_attrs, size, q->dma_dir, q->gfp_flags); + mem_priv = call_ptr_memop(alloc, + vb, + q->alloc_devs[plane] ? : q->dev, + size); if (IS_ERR_OR_NULL(mem_priv)) { if (mem_priv) ret = PTR_ERR(mem_priv); @@ -975,7 +976,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no) if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv) return NULL;
- return call_ptr_memop(vb, vaddr, vb->planes[plane_no].mem_priv); + return call_ptr_memop(vaddr, vb, vb->planes[plane_no].mem_priv);
} EXPORT_SYMBOL_GPL(vb2_plane_vaddr); @@ -985,7 +986,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no) if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv) return NULL;
- return call_ptr_memop(vb, cookie, vb->planes[plane_no].mem_priv); + return call_ptr_memop(cookie, vb, vb->planes[plane_no].mem_priv); } EXPORT_SYMBOL_GPL(vb2_plane_cookie);
@@ -1125,10 +1126,11 @@ static int __prepare_userptr(struct vb2_buffer *vb) vb->planes[plane].data_offset = 0;
/* Acquire each plane's memory */ - mem_priv = call_ptr_memop(vb, get_userptr, - q->alloc_devs[plane] ? : q->dev, - planes[plane].m.userptr, - planes[plane].length, q->dma_dir); + mem_priv = call_ptr_memop(get_userptr, + vb, + q->alloc_devs[plane] ? : q->dev, + planes[plane].m.userptr, + planes[plane].length); if (IS_ERR(mem_priv)) { dprintk(q, 1, "failed acquiring userspace memory for plane %d\n", plane); @@ -1249,9 +1251,11 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) vb->planes[plane].data_offset = 0;
/* Acquire each plane's memory */ - mem_priv = call_ptr_memop(vb, attach_dmabuf, - q->alloc_devs[plane] ? : q->dev, - dbuf, planes[plane].length, q->dma_dir); + mem_priv = call_ptr_memop(attach_dmabuf, + vb, + q->alloc_devs[plane] ? : q->dev, + dbuf, + planes[plane].length); if (IS_ERR(mem_priv)) { dprintk(q, 1, "failed to attach dmabuf\n"); ret = PTR_ERR(mem_priv); @@ -2187,8 +2191,10 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
vb_plane = &vb->planes[plane];
- dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv, - flags & O_ACCMODE); + dbuf = call_ptr_memop(get_dmabuf, + vb, + vb_plane->mem_priv, + flags & O_ACCMODE); if (IS_ERR_OR_NULL(dbuf)) { dprintk(q, 1, "failed to export buffer %d, plane %d\n", index, plane); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index a7f61ba854405..019c3843dc6d5 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -40,6 +40,8 @@ struct vb2_dc_buf {
/* DMABUF related */ struct dma_buf_attachment *db_attach; + + struct vb2_buffer *vb; };
/*********************************************/ @@ -66,14 +68,14 @@ static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) /* callbacks for all buffers */ /*********************************************/
-static void *vb2_dc_cookie(void *buf_priv) +static void *vb2_dc_cookie(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dc_buf *buf = buf_priv;
return &buf->dma_addr; }
-static void *vb2_dc_vaddr(void *buf_priv) +static void *vb2_dc_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; struct dma_buf_map map; @@ -137,9 +139,9 @@ static void vb2_dc_put(void *buf_priv) kfree(buf); }
-static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, - unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) +static void *vb2_dc_alloc(struct vb2_buffer *vb, + struct device *dev, + unsigned long size) { struct vb2_dc_buf *buf;
@@ -150,9 +152,10 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, if (!buf) return ERR_PTR(-ENOMEM);
- buf->attrs = attrs; + buf->attrs = vb->vb2_queue->dma_attrs; buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr, - GFP_KERNEL | gfp_flags, buf->attrs); + GFP_KERNEL | vb->vb2_queue->gfp_flags, + buf->attrs); if (!buf->cookie) { dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); kfree(buf); @@ -165,11 +168,12 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, /* Prevent the device from being released while the buffer is used */ buf->dev = get_device(dev); buf->size = size; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir;
buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dc_put; buf->handler.arg = buf; + buf->vb = vb;
refcount_set(&buf->refcount, 1);
@@ -397,7 +401,9 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf) return sgt; }
-static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags) +static struct dma_buf *vb2_dc_get_dmabuf(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags) { struct vb2_dc_buf *buf = buf_priv; struct dma_buf *dbuf; @@ -459,8 +465,8 @@ static void vb2_dc_put_userptr(void *buf_priv) kfree(buf); }
-static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_dc_get_userptr(struct vb2_buffer *vb, struct device *dev, + unsigned long vaddr, unsigned long size) { struct vb2_dc_buf *buf; struct frame_vector *vec; @@ -490,7 +496,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, return ERR_PTR(-ENOMEM);
buf->dev = dev; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir;
offset = lower_32_bits(offset_in_page(vaddr)); vec = vb2_create_framevec(vaddr, size); @@ -660,8 +666,8 @@ static void vb2_dc_detach_dmabuf(void *mem_priv) kfree(buf); }
-static void *vb2_dc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_dc_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, + struct dma_buf *dbuf, unsigned long size) { struct vb2_dc_buf *buf; struct dma_buf_attachment *dba; @@ -685,7 +691,7 @@ static void *vb2_dc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, return dba; }
- buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->size = size; buf->db_attach = dba;
diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index c5b06a5095661..50265080cfc80 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -51,6 +51,8 @@ struct vb2_dma_sg_buf { struct vb2_vmarea_handler handler;
struct dma_buf_attachment *db_attach; + + struct vb2_buffer *vb; };
static void vb2_dma_sg_put(void *buf_priv); @@ -96,9 +98,8 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, return 0; }
-static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, - unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) +static void *vb2_dma_sg_alloc(struct vb2_buffer *vb, struct device *dev, + unsigned long size) { struct vb2_dma_sg_buf *buf; struct sg_table *sgt; @@ -113,7 +114,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, return ERR_PTR(-ENOMEM);
buf->vaddr = NULL; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->offset = 0; buf->size = size; /* size is already page aligned */ @@ -130,7 +131,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, if (!buf->pages) goto fail_pages_array_alloc;
- ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags); + ret = vb2_dma_sg_alloc_compacted(buf, vb->vb2_queue->gfp_flags); if (ret) goto fail_pages_alloc;
@@ -154,6 +155,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; buf->handler.arg = buf; + buf->vb = vb;
refcount_set(&buf->refcount, 1);
@@ -213,9 +215,8 @@ static void vb2_dma_sg_finish(void *buf_priv) dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); }
-static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, - unsigned long size, - enum dma_data_direction dma_dir) +static void *vb2_dma_sg_get_userptr(struct vb2_buffer *vb, struct device *dev, + unsigned long vaddr, unsigned long size) { struct vb2_dma_sg_buf *buf; struct sg_table *sgt; @@ -230,7 +231,7 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
buf->vaddr = NULL; buf->dev = dev; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; buf->dma_sgt = &buf->sg_table; @@ -292,7 +293,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) kfree(buf); }
-static void *vb2_dma_sg_vaddr(void *buf_priv) +static void *vb2_dma_sg_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; struct dma_buf_map map; @@ -511,7 +512,9 @@ static const struct dma_buf_ops vb2_dma_sg_dmabuf_ops = { .release = vb2_dma_sg_dmabuf_ops_release, };
-static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags) +static struct dma_buf *vb2_dma_sg_get_dmabuf(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags) { struct vb2_dma_sg_buf *buf = buf_priv; struct dma_buf *dbuf; @@ -605,8 +608,8 @@ static void vb2_dma_sg_detach_dmabuf(void *mem_priv) kfree(buf); }
-static void *vb2_dma_sg_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, + struct dma_buf *dbuf, unsigned long size) { struct vb2_dma_sg_buf *buf; struct dma_buf_attachment *dba; @@ -630,14 +633,14 @@ static void *vb2_dma_sg_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, return dba; }
- buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->size = size; buf->db_attach = dba;
return buf; }
-static void *vb2_dma_sg_cookie(void *buf_priv) +static void *vb2_dma_sg_cookie(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv;
diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 83f95258ec8c6..ef36abd912dcc 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c @@ -34,13 +34,12 @@ struct vb2_vmalloc_buf {
static void vb2_vmalloc_put(void *buf_priv);
-static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, - unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) +static void *vb2_vmalloc_alloc(struct vb2_buffer *vb, struct device *dev, + unsigned long size) { struct vb2_vmalloc_buf *buf;
- buf = kzalloc(sizeof(*buf), GFP_KERNEL | gfp_flags); + buf = kzalloc(sizeof(*buf), GFP_KERNEL | vb->vb2_queue->gfp_flags); if (!buf) return ERR_PTR(-ENOMEM);
@@ -52,7 +51,7 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, return ERR_PTR(-ENOMEM); }
- buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_vmalloc_put; buf->handler.arg = buf; @@ -71,9 +70,8 @@ static void vb2_vmalloc_put(void *buf_priv) } }
-static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, - unsigned long size, - enum dma_data_direction dma_dir) +static void *vb2_vmalloc_get_userptr(struct vb2_buffer *vb, struct device *dev, + unsigned long vaddr, unsigned long size) { struct vb2_vmalloc_buf *buf; struct frame_vector *vec; @@ -84,7 +82,7 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, if (!buf) return ERR_PTR(-ENOMEM);
- buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; offset = vaddr & ~PAGE_MASK; buf->size = size; vec = vb2_create_framevec(vaddr, size); @@ -147,7 +145,7 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) kfree(buf); }
-static void *vb2_vmalloc_vaddr(void *buf_priv) +static void *vb2_vmalloc_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_vmalloc_buf *buf = buf_priv;
@@ -339,7 +337,9 @@ static const struct dma_buf_ops vb2_vmalloc_dmabuf_ops = { .release = vb2_vmalloc_dmabuf_ops_release, };
-static struct dma_buf *vb2_vmalloc_get_dmabuf(void *buf_priv, unsigned long flags) +static struct dma_buf *vb2_vmalloc_get_dmabuf(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags) { struct vb2_vmalloc_buf *buf = buf_priv; struct dma_buf *dbuf; @@ -403,8 +403,10 @@ static void vb2_vmalloc_detach_dmabuf(void *mem_priv) kfree(buf); }
-static void *vb2_vmalloc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_vmalloc_attach_dmabuf(struct vb2_buffer *vb, + struct device *dev, + struct dma_buf *dbuf, + unsigned long size) { struct vb2_vmalloc_buf *buf;
@@ -416,7 +418,7 @@ static void *vb2_vmalloc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, return ERR_PTR(-ENOMEM);
buf->dbuf = dbuf; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->size = size;
return buf; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 12955cb460d23..3b5986cee0739 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -46,6 +46,7 @@ enum vb2_memory {
struct vb2_fileio_data; struct vb2_threadio_data; +struct vb2_buffer;
/** * struct vb2_mem_ops - memory handling/memory allocator operations. @@ -53,10 +54,8 @@ struct vb2_threadio_data; * return ERR_PTR() on failure or a pointer to allocator private, * per-buffer data on success; the returned private structure * will then be passed as @buf_priv argument to other ops in this - * structure. Additional gfp_flags to use when allocating the - * are also passed to this operation. These flags are from the - * gfp_flags field of vb2_queue. The size argument to this function - * shall be *page aligned*. + * structure. The size argument to this function shall be + * *page aligned*. * @put: inform the allocator that the buffer will no longer be used; * usually will result in the allocator freeing the buffer (if * no other users of this buffer are present); the @buf_priv @@ -117,31 +116,33 @@ struct vb2_threadio_data; * map_dmabuf, unmap_dmabuf. */ struct vb2_mem_ops { - void *(*alloc)(struct device *dev, unsigned long attrs, - unsigned long size, - enum dma_data_direction dma_dir, - gfp_t gfp_flags); + void *(*alloc)(struct vb2_buffer *vb, + struct device *dev, + unsigned long size); void (*put)(void *buf_priv); - struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); - - void *(*get_userptr)(struct device *dev, unsigned long vaddr, - unsigned long size, - enum dma_data_direction dma_dir); + struct dma_buf *(*get_dmabuf)(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags); + + void *(*get_userptr)(struct vb2_buffer *vb, + struct device *dev, + unsigned long vaddr, + unsigned long size); void (*put_userptr)(void *buf_priv);
void (*prepare)(void *buf_priv); void (*finish)(void *buf_priv);
- void *(*attach_dmabuf)(struct device *dev, + void *(*attach_dmabuf)(struct vb2_buffer *vb, + struct device *dev, struct dma_buf *dbuf, - unsigned long size, - enum dma_data_direction dma_dir); + unsigned long size); void (*detach_dmabuf)(void *buf_priv); int (*map_dmabuf)(void *buf_priv); void (*unmap_dmabuf)(void *buf_priv);
- void *(*vaddr)(void *buf_priv); - void *(*cookie)(void *buf_priv); + void *(*vaddr)(struct vb2_buffer *vb, void *buf_priv); + void *(*cookie)(struct vb2_buffer *vb, void *buf_priv);
unsigned int (*num_users)(void *buf_priv);
On (21/11/15 17:55), Greg Kroah-Hartman wrote:
From: Sergey Senozhatsky senozhatsky@chromium.org
[ Upstream commit a4b83deb3e76fb9385ca58e2c072a145b3a320d6 ]
With the new DMA API we need an extension of the videobuf2 API. Previously, videobuf2 core would set the non-coherent DMA bit in the vb2_queue dma_attr field (if user-space would pass a corresponding memory hint); the vb2 core then would pass the vb2_queue dma_attrs to the vb2 allocators. The vb2 allocator would use the queue's dma_attr and the DMA API would allocate either coherent or non-coherent memory.
But we cannot do this anymore, since there is no corresponding DMA attr flag and, hence, there is no way for the allocator to become aware of what type of allocation user-space has requested. So we need to pass more context from videobuf2 core to the allocators.
Fix this by changing the call_ptr_memop() macro to pass the vb2 pointer to the corresponding op callbacks.
Signed-off-by: Sergey Senozhatsky senozhatsky@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
Hello Greg, Sasha,
This patch needs two fix up patches to be applied.
The first one is in Linus's tree (media: videobuf2: always set buffer vb2 pointer) 67f85135c57c8ea20b5417b28ae65e53dc2ec2c3
The second one isn't yet (media: videobuf2-dma-sg: Fix buf->vb NULL pointer dereference) https://lore.kernel.org/all/20211101145355.533704-1-hdegoede@redhat.com/raw
On Tue, Nov 16, 2021 at 10:22:36AM +0900, Sergey Senozhatsky wrote:
On (21/11/15 17:55), Greg Kroah-Hartman wrote:
From: Sergey Senozhatsky senozhatsky@chromium.org
[ Upstream commit a4b83deb3e76fb9385ca58e2c072a145b3a320d6 ]
With the new DMA API we need an extension of the videobuf2 API. Previously, videobuf2 core would set the non-coherent DMA bit in the vb2_queue dma_attr field (if user-space would pass a corresponding memory hint); the vb2 core then would pass the vb2_queue dma_attrs to the vb2 allocators. The vb2 allocator would use the queue's dma_attr and the DMA API would allocate either coherent or non-coherent memory.
But we cannot do this anymore, since there is no corresponding DMA attr flag and, hence, there is no way for the allocator to become aware of what type of allocation user-space has requested. So we need to pass more context from videobuf2 core to the allocators.
Fix this by changing the call_ptr_memop() macro to pass the vb2 pointer to the corresponding op callbacks.
Signed-off-by: Sergey Senozhatsky senozhatsky@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org
Hello Greg, Sasha,
This patch needs two fix up patches to be applied.
The first one is in Linus's tree (media: videobuf2: always set buffer vb2 pointer) 67f85135c57c8ea20b5417b28ae65e53dc2ec2c3
Now applied, thanks.
The second one isn't yet (media: videobuf2-dma-sg: Fix buf->vb NULL pointer dereference) https://lore.kernel.org/all/20211101145355.533704-1-hdegoede@redhat.com/raw
I've grabbed this from linux-next now.
thanks,
greg k-h
From: Martin Kepplinger martin.kepplinger@puri.sm
[ Upstream commit 6d0d779b212c27293d9ccb4da092ff0ccb6efa39 ]
Some tools like v4l2-compliance let users select a media device based on the bus_info string which can be quite convenient. Use a unique string for that.
This also fixes the following v4l2-compliance warning: warn: v4l2-test-media.cpp(52): empty bus_info
Signed-off-by: Martin Kepplinger martin.kepplinger@puri.sm Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/imx/imx-media-dev-common.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c index d186179388d03..4d873726a461b 100644 --- a/drivers/staging/media/imx/imx-media-dev-common.c +++ b/drivers/staging/media/imx/imx-media-dev-common.c @@ -367,6 +367,8 @@ struct imx_media_dev *imx_media_dev_init(struct device *dev, imxmd->v4l2_dev.notify = imx_media_notify; strscpy(imxmd->v4l2_dev.name, "imx-media", sizeof(imxmd->v4l2_dev.name)); + snprintf(imxmd->md.bus_info, sizeof(imxmd->md.bus_info), + "platform:%s", dev_name(imxmd->md.dev));
media_device_init(&imxmd->md);
From: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se
[ Upstream commit a5991c4e947153418f71f4689614b87ca0551b81 ]
When adding an internal scratch buffer to improve buffer handling when stopping it was also erroneously used when syncing at capture start. This led to that the first three buffers captured were always dropped as they were captured in the scratch buffer instead of in a buffer provided by the user.
Allow the hardware to be given user provided buffers when preparing for capture in the stopped state. This still allows the driver to sync with the hardware and always completes the buffers to user-space in the correct order as no buffers are completed before the sync is complete. This change improves the driver as buffers are completed and given to the user three frames earlier than before.
The change also fixes a warning produced by v4l2-compliance,
warn: v4l2-test-buffers.cpp(448): got sequence number 3, expected 0
[hverkuil: fixed some typos in the Subject and the log message]
Signed-off-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar-vin/rcar-dma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index f5f722ab1d4e8..520d044bfb8d5 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -904,7 +904,8 @@ static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot) vin->format.sizeimage / 2; break; } - } else if (vin->state != RUNNING || list_empty(&vin->buf_list)) { + } else if ((vin->state != STOPPED && vin->state != RUNNING) || + list_empty(&vin->buf_list)) { vin->buf_hw[slot].buffer = NULL; vin->buf_hw[slot].type = FULL; phys_addr = vin->scratch_phys;
From: Rajat Asthana rajatasthana4@gmail.com
[ Upstream commit 476db72e521983ecb847e4013b263072bb1110fc ]
Syzkaller reported a warning called "rcu detected stall in dummy_timer".
The error seems to be an error in mceusb_dev_recv(). In the case of -EPROTO error, the routine immediately resubmits the URB. Instead it should return without resubmitting URB.
Reported-by: syzbot+4d3749e9612c2cfab956@syzkaller.appspotmail.com Signed-off-by: Rajat Asthana rajatasthana4@gmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/mceusb.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index e03dd1f0144f0..137a71954aabf 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1386,6 +1386,7 @@ static void mceusb_dev_recv(struct urb *urb) case -ECONNRESET: case -ENOENT: case -EILSEQ: + case -EPROTO: case -ESHUTDOWN: usb_unlink_urb(urb); return;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit c15b5fc054c3d6c97e953617605235c5cb8ce979 ]
When CONFIG_PRINTK is not set, the CMPXCHG_BUGCHECK() macro calls _printk(), but _printk() is a static inline function, not available as an extern. Since the purpose of the macro is to print the BUGCHECK info, make this config option depend on PRINTK.
Fixes multiple occurrences of this build error:
../include/linux/printk.h:208:5: error: static declaration of '_printk' follows non-static declaration 208 | int _printk(const char *s, ...) | ^~~~~~~ In file included from ../arch/ia64/include/asm/cmpxchg.h:5, ../arch/ia64/include/uapi/asm/cmpxchg.h:146:28: note: previous declaration of '_printk' with type 'int(const char *, ...)' 146 | extern int _printk(const char *fmt, ...);
Cc: linux-ia64@vger.kernel.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Tony Luck tony.luck@intel.com Cc: Chris Down chris@chrisdown.name Cc: Paul Gortmaker paul.gortmaker@windriver.com Cc: John Paul Adrian Glaubitz glaubitz@physik.fu-berlin.de Signed-off-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Petr Mladek pmladek@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/ia64/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug index 40ca23bd228d6..2ce008e2d1644 100644 --- a/arch/ia64/Kconfig.debug +++ b/arch/ia64/Kconfig.debug @@ -39,7 +39,7 @@ config DISABLE_VHPT
config IA64_DEBUG_CMPXCHG bool "Turn on compare-and-exchange bug checking (slow!)" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PRINTK help Selecting this option turns on bug checking for the IA-64 compare-and-exchange instructions. This is slow! Itaniums
From: Zong-Zhe Yang kevin_yang@realtek.com
[ Upstream commit c5a8e90730a322f236731fc347dd3afa5db5550e ]
When fw fifo dumps, RX clock gating should be disabled to avoid something unexpected. However, the register operation ran into a mistake. So, we fix it.
Signed-off-by: Zong-Zhe Yang kevin_yang@realtek.com Signed-off-by: Ping-Ke Shih pkshih@realtek.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210927111830.5354-1-pkshih@realtek.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/realtek/rtw88/fw.c | 7 +++---- drivers/net/wireless/realtek/rtw88/reg.h | 1 + 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index e6399519584bd..a384fc3a4f2b0 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -1556,12 +1556,10 @@ static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size, u32 i; u16 idx = 0; u16 ctl; - u8 rcr;
- rcr = rtw_read8(rtwdev, REG_RCR + 2); ctl = rtw_read16(rtwdev, REG_PKTBUF_DBG_CTRL) & 0xf000; /* disable rx clock gate */ - rtw_write8(rtwdev, REG_RCR, rcr | BIT(3)); + rtw_write32_set(rtwdev, REG_RCR, BIT_DISGCLK);
do { rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, start_pg | ctl); @@ -1580,7 +1578,8 @@ static void rtw_fw_read_fifo_page(struct rtw_dev *rtwdev, u32 offset, u32 size,
out: rtw_write16(rtwdev, REG_PKTBUF_DBG_CTRL, ctl); - rtw_write8(rtwdev, REG_RCR + 2, rcr); + /* restore rx clock gate */ + rtw_write32_clr(rtwdev, REG_RCR, BIT_DISGCLK); }
static void rtw_fw_read_fifo(struct rtw_dev *rtwdev, enum rtw_fw_fifo_sel sel, diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h index f5ce75095e904..c0fb1e446245f 100644 --- a/drivers/net/wireless/realtek/rtw88/reg.h +++ b/drivers/net/wireless/realtek/rtw88/reg.h @@ -406,6 +406,7 @@ #define BIT_MFBEN BIT(22) #define BIT_DISCHKPPDLLEN BIT(21) #define BIT_PKTCTL_DLEN BIT(20) +#define BIT_DISGCLK BIT(19) #define BIT_TIM_PARSER_EN BIT(18) #define BIT_BC_MD_EN BIT(17) #define BIT_UC_MD_EN BIT(16)
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 49c3eb3036e6359c5c20fe76c611a2c0e0d4710e ]
The Cyberbook T116 tablet contains quite generic names in the sys_vendor and product_name DMI strings, without this patch brcmfmac will try to load: "brcmfmac43455-sdio.Default string-Default string.txt" as nvram file which is way too generic.
The nvram file shipped on the factory Android image contains the exact same settings as those used on the AcePC T8 mini PC, so point the new DMI nvram filename quirk to the acepc-t8 nvram file.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210928160633.96928-1-hdegoede@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c index 6d5188b78f2de..0af452dca7664 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c @@ -75,6 +75,16 @@ static const struct dmi_system_id dmi_platform_data[] = { }, .driver_data = (void *)&acepc_t8_data, }, + { + /* 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"), + }, + /* The factory image nvram file is identical to the ACEPC T8 one */ + .driver_data = (void *)&acepc_t8_data, + }, { /* Match for the GPDwin which unfortunately uses somewhat * generic dmi strings, which is why we test for 4 strings.
From: Nadezda Lutovinova lutovinova@ispras.ru
[ Upstream commit fc41665498332ad394b7db37f23e9394096ddc71 ]
If rcsi2_code_to_fmt() return NULL, then null pointer dereference occurs in the next cycle. That should not be possible now but adding checking protects from future bugs. The patch adds checking if format is NULL.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Nadezda Lutovinova lutovinova@ispras.ru Reviewed-by: Jacopo Mondi jacopo@jmondi.org Reviewed-by: Niklas Söderlund niklas.soderlund+renesas@ragnatech.se Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/rcar-vin/rcar-csi2.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index e28eff0396888..ba4a380016cc4 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -553,6 +553,8 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
/* Code is validated in set_fmt. */ format = rcsi2_code_to_fmt(priv->mf.code); + if (!format) + return -EINVAL;
/* * Enable all supported CSI-2 channels with virtual channel and
From: Corey Minyard cminyard@mvista.com
[ Upstream commit b36eb5e7b75a756baa64909a176dd4269ee05a8b ]
Don't do kfree or other risky things when oops_in_progress is set. It's easy enough to avoid doing them
Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/ipmi_msghandler.c | 10 +++++++--- drivers/char/ipmi/ipmi_watchdog.c | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index e96cb5c4f97a3..a08f53f208bfe 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -4789,7 +4789,9 @@ static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0); static void free_smi_msg(struct ipmi_smi_msg *msg) { atomic_dec(&smi_msg_inuse_count); - kfree(msg); + /* Try to keep as much stuff out of the panic path as possible. */ + if (!oops_in_progress) + kfree(msg); }
struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) @@ -4808,7 +4810,9 @@ EXPORT_SYMBOL(ipmi_alloc_smi_msg); static void free_recv_msg(struct ipmi_recv_msg *msg) { atomic_dec(&recv_msg_inuse_count); - kfree(msg); + /* Try to keep as much stuff out of the panic path as possible. */ + if (!oops_in_progress) + kfree(msg); }
static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) @@ -4826,7 +4830,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) { - if (msg->user) + if (msg->user && !oops_in_progress) kref_put(&msg->user->refcount, free_user); msg->done(msg); } diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index f855a9665c284..883b4a3410122 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -342,13 +342,17 @@ static atomic_t msg_tofree = ATOMIC_INIT(0); static DECLARE_COMPLETION(msg_wait); static void msg_free_smi(struct ipmi_smi_msg *msg) { - if (atomic_dec_and_test(&msg_tofree)) - complete(&msg_wait); + if (atomic_dec_and_test(&msg_tofree)) { + if (!oops_in_progress) + complete(&msg_wait); + } } static void msg_free_recv(struct ipmi_recv_msg *msg) { - if (atomic_dec_and_test(&msg_tofree)) - complete(&msg_wait); + if (atomic_dec_and_test(&msg_tofree)) { + if (!oops_in_progress) + complete(&msg_wait); + } } static struct ipmi_smi_msg smi_msg = { .done = msg_free_smi @@ -434,8 +438,10 @@ static int _ipmi_set_timeout(int do_heartbeat) rv = __ipmi_set_timeout(&smi_msg, &recv_msg, &send_heartbeat_now); - if (rv) + if (rv) { + atomic_set(&msg_tofree, 0); return rv; + }
wait_for_completion(&msg_wait);
@@ -580,6 +586,7 @@ restart: &recv_msg, 1); if (rv) { + atomic_set(&msg_tofree, 0); pr_warn("heartbeat send failure: %d\n", rv); return rv; }
From: Josh Don joshdon@google.com
[ Upstream commit a130e8fbc7de796eb6e680724d87f4737a26d0ac ]
/proc/uptime reports idle time by reading the CPUTIME_IDLE field from the per-cpu kcpustats. However, on NO_HZ systems, idle time is not continually updated on idle cpus, leading this value to appear incorrectly small.
/proc/stat performs an accounting update when reading idle time; we can use the same approach for uptime.
With this patch, /proc/stat and /proc/uptime now agree on idle time. Additionally, the following shows idle time tick up consistently on an idle machine:
(while true; do cat /proc/uptime; sleep 1; done) | awk '{print $2-prev; prev=$2}'
Reported-by: Luigi Rizzo lrizzo@google.com Signed-off-by: Josh Don joshdon@google.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Eric Dumazet edumazet@google.com Link: https://lkml.kernel.org/r/20210827165438.3280779-1-joshdon@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/proc/stat.c | 4 ++-- fs/proc/uptime.c | 14 +++++++++----- include/linux/kernel_stat.h | 1 + 3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 6561a06ef9059..4fb8729a68d4e 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c @@ -24,7 +24,7 @@
#ifdef arch_idle_time
-static u64 get_idle_time(struct kernel_cpustat *kcs, int cpu) +u64 get_idle_time(struct kernel_cpustat *kcs, int cpu) { u64 idle;
@@ -46,7 +46,7 @@ static u64 get_iowait_time(struct kernel_cpustat *kcs, int cpu)
#else
-static u64 get_idle_time(struct kernel_cpustat *kcs, int cpu) +u64 get_idle_time(struct kernel_cpustat *kcs, int cpu) { u64 idle, idle_usecs = -1ULL;
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c index 5a1b228964fb7..deb99bc9b7e6b 100644 --- a/fs/proc/uptime.c +++ b/fs/proc/uptime.c @@ -12,18 +12,22 @@ static int uptime_proc_show(struct seq_file *m, void *v) { struct timespec64 uptime; struct timespec64 idle; - u64 nsec; + u64 idle_nsec; u32 rem; int i;
- nsec = 0; - for_each_possible_cpu(i) - nsec += (__force u64) kcpustat_cpu(i).cpustat[CPUTIME_IDLE]; + idle_nsec = 0; + for_each_possible_cpu(i) { + struct kernel_cpustat kcs; + + kcpustat_cpu_fetch(&kcs, i); + idle_nsec += get_idle_time(&kcs, i); + }
ktime_get_boottime_ts64(&uptime); timens_add_boottime(&uptime);
- idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem); + idle.tv_sec = div_u64_rem(idle_nsec, NSEC_PER_SEC, &rem); idle.tv_nsec = rem; seq_printf(m, "%lu.%02lu %lu.%02lu\n", (unsigned long) uptime.tv_sec, diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 44ae1a7eb9e39..69ae6b2784645 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -102,6 +102,7 @@ extern void account_system_index_time(struct task_struct *, u64, enum cpu_usage_stat); extern void account_steal_time(u64); extern void account_idle_time(u64); +extern u64 get_idle_time(struct kernel_cpustat *kcs, int cpu);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE static inline void account_process_tick(struct task_struct *tsk, int user)
From: Li Zhijian lizhijian@cn.fujitsu.com
[ Upstream commit 1c36432b278cecf1499f21fae19836e614954309 ]
Previously, 'make -C sched run_tests' will block forever when it occurs something wrong where the *selftests framework* is waiting for its child processes to exit.
[root@iaas-rpma sched]# ./cs_prctl_test
## Create a thread/process/process group hiearchy Not a core sched system tid=74985, / tgid=74985 / pgid=74985: ffffffffffffffff Not a core sched system tid=74986, / tgid=74986 / pgid=74985: ffffffffffffffff Not a core sched system tid=74988, / tgid=74986 / pgid=74985: ffffffffffffffff Not a core sched system tid=74989, / tgid=74986 / pgid=74985: ffffffffffffffff Not a core sched system tid=74990, / tgid=74986 / pgid=74985: ffffffffffffffff Not a core sched system tid=74987, / tgid=74987 / pgid=74985: ffffffffffffffff Not a core sched system tid=74991, / tgid=74987 / pgid=74985: ffffffffffffffff Not a core sched system tid=74992, / tgid=74987 / pgid=74985: ffffffffffffffff Not a core sched system tid=74993, / tgid=74987 / pgid=74985: ffffffffffffffff
Not a core sched system (268) FAILED: get_cs_cookie(0) == 0
## Set a cookie on entire process group -1 = prctl(62, 1, 0, 2, 0) core_sched create failed -- PGID: Invalid argument (cs_prctl_test.c:272) - [root@iaas-rpma sched]# ps PID TTY TIME CMD 4605 pts/2 00:00:00 bash 74986 pts/2 00:00:00 cs_prctl_test 74987 pts/2 00:00:00 cs_prctl_test 74999 pts/2 00:00:00 ps
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Li Zhijian lizhijian@cn.fujitsu.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Chris Hyser chris.hyser@oracle.com Link: https://lore.kernel.org/r/20210902024333.75983-1-lizhijian@cn.fujitsu.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/sched/cs_prctl_test.c | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/sched/cs_prctl_test.c b/tools/testing/selftests/sched/cs_prctl_test.c index 7db9cf822dc75..8109b17dc764c 100644 --- a/tools/testing/selftests/sched/cs_prctl_test.c +++ b/tools/testing/selftests/sched/cs_prctl_test.c @@ -62,6 +62,17 @@ enum pid_type {PIDTYPE_PID = 0, PIDTYPE_TGID, PIDTYPE_PGID};
const int THREAD_CLONE_FLAGS = CLONE_THREAD | CLONE_SIGHAND | CLONE_FS | CLONE_VM | CLONE_FILES;
+struct child_args { + int num_threads; + int pfd[2]; + int cpid; + int thr_tids[MAX_THREADS]; +}; + +static struct child_args procs[MAX_PROCESSES]; +static int num_processes = 2; +static int need_cleanup = 0; + static int _prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) { @@ -78,8 +89,14 @@ static int _prctl(int option, unsigned long arg2, unsigned long arg3, unsigned l #define handle_error(msg) __handle_error(__FILE__, __LINE__, msg) static void __handle_error(char *fn, int ln, char *msg) { + int pidx; printf("(%s:%d) - ", fn, ln); perror(msg); + if (need_cleanup) { + for (pidx = 0; pidx < num_processes; ++pidx) + kill(procs[pidx].cpid, 15); + need_cleanup = 0; + } exit(EXIT_FAILURE); }
@@ -106,13 +123,6 @@ static unsigned long get_cs_cookie(int pid) return cookie; }
-struct child_args { - int num_threads; - int pfd[2]; - int cpid; - int thr_tids[MAX_THREADS]; -}; - static int child_func_thread(void __attribute__((unused))*arg) { while (1) @@ -212,10 +222,7 @@ void _validate(int line, int val, char *msg)
int main(int argc, char *argv[]) { - struct child_args procs[MAX_PROCESSES]; - int keypress = 0; - int num_processes = 2; int num_threads = 3; int delay = 0; int res = 0; @@ -262,6 +269,7 @@ int main(int argc, char *argv[])
printf("\n## Create a thread/process/process group hiearchy\n"); create_processes(num_processes, num_threads, procs); + need_cleanup = 1; disp_processes(num_processes, procs); validate(get_cs_cookie(0) == 0);
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit d3c4b6f64ad356c0d9ddbcf73fa471e6a841cc5c ]
ACPICA commit 0762982923f95eb652cf7ded27356b247c9774de
During wakeup from system-wide sleep states, acpi_get_sleep_type_data() is called and it tries to get memory from the slab allocator in order to evaluate a control method, but if KFENCE is enabled in the kernel, the memory allocation attempt causes an IRQ work to be queued and a self-IPI to be sent to the CPU running the code which requires the memory controller to be ready, so if that happens too early in the wakeup path, it doesn't work.
Prevent that from taking place by calling acpi_get_sleep_type_data() for S0 upfront, when preparing to enter a given sleep state, and saving the data obtained by it for later use during system wakeup.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214271 Reported-by: Reik Keutterling spielkind@gmail.com Tested-by: Reik Keutterling spielkind@gmail.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/acpica/acglobal.h | 2 ++ drivers/acpi/acpica/hwesleep.c | 8 ++------ drivers/acpi/acpica/hwsleep.c | 11 ++++------- drivers/acpi/acpica/hwxfsleep.c | 7 +++++++ 4 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index d41b810e367c4..4366d36ef1198 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -226,6 +226,8 @@ extern struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b); +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0); +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b_s0);
/***************************************************************************** * diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 803402aefaeb6..808fdf54aeebf 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c @@ -147,17 +147,13 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state)
acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) { - acpi_status status; u8 sleep_type_value;
ACPI_FUNCTION_TRACE(hw_extended_wake_prep);
- status = acpi_get_sleep_type_data(ACPI_STATE_S0, - &acpi_gbl_sleep_type_a, - &acpi_gbl_sleep_type_b); - if (ACPI_SUCCESS(status)) { + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) { sleep_type_value = - ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & + ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) & ACPI_X_SLEEP_TYPE_MASK);
(void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE), diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 14baa13bf8482..34a3825f25d37 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -179,7 +179,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state)
acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) { - acpi_status status; + acpi_status status = AE_OK; struct acpi_bit_register_info *sleep_type_reg_info; struct acpi_bit_register_info *sleep_enable_reg_info; u32 pm1a_control; @@ -192,10 +192,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) * This is unclear from the ACPI Spec, but it is required * by some machines. */ - status = acpi_get_sleep_type_data(ACPI_STATE_S0, - &acpi_gbl_sleep_type_a, - &acpi_gbl_sleep_type_b); - if (ACPI_SUCCESS(status)) { + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) { sleep_type_reg_info = acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); sleep_enable_reg_info = @@ -216,9 +213,9 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state)
/* Insert the SLP_TYP bits */
- pm1a_control |= (acpi_gbl_sleep_type_a << + pm1a_control |= (acpi_gbl_sleep_type_a_s0 << sleep_type_reg_info->bit_position); - pm1b_control |= (acpi_gbl_sleep_type_b << + pm1b_control |= (acpi_gbl_sleep_type_b_s0 << sleep_type_reg_info->bit_position);
/* Write the control registers and ignore any errors */ diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index 89b12afed564e..e4cde23a29061 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c @@ -217,6 +217,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) return_ACPI_STATUS(status); }
+ status = acpi_get_sleep_type_data(ACPI_STATE_S0, + &acpi_gbl_sleep_type_a_s0, + &acpi_gbl_sleep_type_b_s0); + if (ACPI_FAILURE(status)) { + acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID; + } + /* Execute the _PTS method (Prepare To Sleep) */
arg_list.count = 1;
From: Vincent Donnefort vincent.donnefort@arm.com
[ Upstream commit 15171769069408789a72f9aa9a52cc931b839b56 ]
When applying the policy min/max limits, the requested frequency is simply clamped to not be out of range. It means, however, if one of the boundaries isn't an available frequency, the frequency resolution can return a value out of those limits, depending on the relation used.
e.g. freq{0,1,2} being available frequencies.
freq0 policy->min freq1 policy->max freq2 | | | | | 17kHz 18kHz 19kHz 20kHz 21kHz
__resolve_freq(21kHz, CPUFREQ_RELATION_L) -> 21kHz (out of bounds) __resolve_freq(17kHz, CPUFREQ_RELATION_H) -> 17kHz (out of bounds)
If, during the policy init, we resolve the requested min/max to existing frequencies, we ensure that any CPUFREQ_RELATION_* would resolve to a frequency which is inside the policy min/max range.
Making the policy limits rigid helps to introduce the inefficient frequencies support. Resolving an inefficient frequency to an efficient one should not transgress policy->max (which can be set for thermal reason) and having a value we can trust simplify this comparison.
Signed-off-by: Vincent Donnefort vincent.donnefort@arm.com Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/cpufreq.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 5782b15a8caad..284e940084c61 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2523,8 +2523,15 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, if (ret) return ret;
+ /* + * Resolve policy min/max to available frequencies. It ensures + * no frequency resolution will neither overshoot the requested maximum + * nor undershoot the requested minimum. + */ policy->min = new_data.min; policy->max = new_data.max; + policy->min = __resolve_freq(policy, policy->min, CPUFREQ_RELATION_L); + policy->max = __resolve_freq(policy, policy->max, CPUFREQ_RELATION_H); trace_cpu_frequency_limits(policy);
policy->cached_target_freq = UINT_MAX;
From: Wojciech Drewek wojciech.drewek@intel.com
[ Upstream commit 2ae0aa4758b0f4a247d45cb3bf01548a7f396751 ]
Keeping devlink port inside VSI data structure causes some issues. Since VF VSI is released during reset that means that we have to unregister devlink port and register it again every time reset is triggered. With the new changes in devlink API it might cause deadlock issues. After calling devlink_port_register/devlink_port_unregister devlink API is going to lock rtnl_mutex. It's an issue when VF reset is triggered in netlink operation context (like setting VF MAC address or VLAN), because rtnl_lock is already taken by netlink. Another call of rtnl_lock from devlink API results in dead-lock.
By moving devlink port to PF/VF we avoid creating/destroying it during reset. Since this patch, devlink ports are created during ice_probe, destroyed during ice_remove for PF and created during ice_repr_add, destroyed during ice_repr_rem for VF.
Signed-off-by: Wojciech Drewek wojciech.drewek@intel.com Tested-by: Sandeep Penigalapati sandeep.penigalapati@intel.com Signed-off-by: Tony Nguyen anthony.l.nguyen@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/ice/ice.h | 7 +- drivers/net/ethernet/intel/ice/ice_devlink.c | 109 +++++++++++++----- drivers/net/ethernet/intel/ice/ice_devlink.h | 6 +- drivers/net/ethernet/intel/ice/ice_lib.c | 3 +- drivers/net/ethernet/intel/ice/ice_main.c | 4 +- .../net/ethernet/intel/ice/ice_virtchnl_pf.c | 2 +- .../net/ethernet/intel/ice/ice_virtchnl_pf.h | 9 ++ 7 files changed, 103 insertions(+), 37 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index 3c4f08d20414e..8b23fbf3cdf4c 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -306,10 +306,6 @@ struct ice_vsi { spinlock_t arfs_lock; /* protects aRFS hash table and filter state */ atomic_t *arfs_last_fltr_id;
- /* devlink port data */ - struct devlink_port devlink_port; - bool devlink_port_registered; - u16 max_frame; u16 rx_buf_len;
@@ -421,6 +417,9 @@ struct ice_pf { struct devlink_region *nvm_region; struct devlink_region *devcaps_region;
+ /* devlink port data */ + struct devlink_port devlink_port; + /* OS reserved IRQ details */ struct msix_entry *msix_entries; struct ice_res_tracker *irq_tracker; diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index da7288bdc9a3f..2ec5d5cb72803 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -526,60 +526,115 @@ void ice_devlink_unregister(struct ice_pf *pf) }
/** - * ice_devlink_create_port - Create a devlink port for this VSI - * @vsi: the VSI to create a port for + * ice_devlink_create_pf_port - Create a devlink port for this PF + * @pf: the PF to create a devlink port for * - * Create and register a devlink_port for this VSI. + * Create and register a devlink_port for this PF. * * Return: zero on success or an error code on failure. */ -int ice_devlink_create_port(struct ice_vsi *vsi) +int ice_devlink_create_pf_port(struct ice_pf *pf) { struct devlink_port_attrs attrs = {}; - struct ice_port_info *pi; + struct devlink_port *devlink_port; struct devlink *devlink; + struct ice_vsi *vsi; struct device *dev; - struct ice_pf *pf; int err;
- /* Currently we only create devlink_port instances for PF VSIs */ - if (vsi->type != ICE_VSI_PF) - return -EINVAL; - - pf = vsi->back; - devlink = priv_to_devlink(pf); dev = ice_pf_to_dev(pf); - pi = pf->hw.port_info; + + devlink_port = &pf->devlink_port; + + vsi = ice_get_main_vsi(pf); + if (!vsi) + return -EIO;
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; - attrs.phys.port_number = pi->lport; - devlink_port_attrs_set(&vsi->devlink_port, &attrs); - err = devlink_port_register(devlink, &vsi->devlink_port, vsi->idx); + attrs.phys.port_number = pf->hw.bus.func; + devlink_port_attrs_set(devlink_port, &attrs); + devlink = priv_to_devlink(pf); + + err = devlink_port_register(devlink, devlink_port, vsi->idx); if (err) { - dev_err(dev, "devlink_port_register failed: %d\n", err); + dev_err(dev, "Failed to create devlink port for PF %d, error %d\n", + pf->hw.pf_id, err); return err; }
- vsi->devlink_port_registered = true; + return 0; +} + +/** + * ice_devlink_destroy_pf_port - Destroy the devlink_port for this PF + * @pf: the PF to cleanup + * + * Unregisters the devlink_port structure associated with this PF. + */ +void ice_devlink_destroy_pf_port(struct ice_pf *pf) +{ + struct devlink_port *devlink_port; + + devlink_port = &pf->devlink_port; + + devlink_port_type_clear(devlink_port); + devlink_port_unregister(devlink_port); +} + +/** + * ice_devlink_create_vf_port - Create a devlink port for this VF + * @vf: the VF to create a port for + * + * Create and register a devlink_port for this VF. + * + * Return: zero on success or an error code on failure. + */ +int ice_devlink_create_vf_port(struct ice_vf *vf) +{ + struct devlink_port_attrs attrs = {}; + struct devlink_port *devlink_port; + struct devlink *devlink; + struct ice_vsi *vsi; + struct device *dev; + struct ice_pf *pf; + int err; + + pf = vf->pf; + dev = ice_pf_to_dev(pf); + vsi = ice_get_vf_vsi(vf); + devlink_port = &vf->devlink_port; + + attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF; + attrs.pci_vf.pf = pf->hw.bus.func; + attrs.pci_vf.vf = vf->vf_id; + + devlink_port_attrs_set(devlink_port, &attrs); + devlink = priv_to_devlink(pf); + + err = devlink_port_register(devlink, devlink_port, vsi->idx); + if (err) { + dev_err(dev, "Failed to create devlink port for VF %d, error %d\n", + vf->vf_id, err); + return err; + }
return 0; }
/** - * ice_devlink_destroy_port - Destroy the devlink_port for this VSI - * @vsi: the VSI to cleanup + * ice_devlink_destroy_vf_port - Destroy the devlink_port for this VF + * @vf: the VF to cleanup * - * Unregisters the devlink_port structure associated with this VSI. + * Unregisters the devlink_port structure associated with this VF. */ -void ice_devlink_destroy_port(struct ice_vsi *vsi) +void ice_devlink_destroy_vf_port(struct ice_vf *vf) { - if (!vsi->devlink_port_registered) - return; + struct devlink_port *devlink_port;
- devlink_port_type_clear(&vsi->devlink_port); - devlink_port_unregister(&vsi->devlink_port); + devlink_port = &vf->devlink_port;
- vsi->devlink_port_registered = false; + devlink_port_type_clear(devlink_port); + devlink_port_unregister(devlink_port); }
/** diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.h b/drivers/net/ethernet/intel/ice/ice_devlink.h index e07e74426bde8..e30284ccbed4c 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.h +++ b/drivers/net/ethernet/intel/ice/ice_devlink.h @@ -8,8 +8,10 @@ struct ice_pf *ice_allocate_pf(struct device *dev);
int ice_devlink_register(struct ice_pf *pf); void ice_devlink_unregister(struct ice_pf *pf); -int ice_devlink_create_port(struct ice_vsi *vsi); -void ice_devlink_destroy_port(struct ice_vsi *vsi); +int ice_devlink_create_pf_port(struct ice_pf *pf); +void ice_devlink_destroy_pf_port(struct ice_pf *pf); +int ice_devlink_create_vf_port(struct ice_vf *vf); +void ice_devlink_destroy_vf_port(struct ice_vf *vf);
void ice_devlink_init_regions(struct ice_pf *pf); void ice_devlink_destroy_regions(struct ice_pf *pf); diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index b718e196af2a4..e47920fe73b88 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -2860,7 +2860,8 @@ int ice_vsi_release(struct ice_vsi *vsi) clear_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); }
- ice_devlink_destroy_port(vsi); + if (vsi->type == ICE_VSI_PF) + ice_devlink_destroy_pf_port(pf);
if (test_bit(ICE_FLAG_RSS_ENA, pf->flags)) ice_rss_clean(vsi); diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 06fa93e597fbc..30077104d1439 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -4170,11 +4170,11 @@ static int ice_register_netdev(struct ice_pf *pf) set_bit(ICE_VSI_NETDEV_REGISTERED, vsi->state); netif_carrier_off(vsi->netdev); netif_tx_stop_all_queues(vsi->netdev); - err = ice_devlink_create_port(vsi); + err = ice_devlink_create_pf_port(pf); if (err) goto err_devlink_create;
- devlink_port_type_eth_set(&vsi->devlink_port, vsi->netdev); + devlink_port_type_eth_set(&pf->devlink_port, vsi->netdev);
return 0; err_devlink_create: diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index e93430ab37f1e..a827c6b653a38 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -251,7 +251,7 @@ ice_vc_hash_field_match_type ice_vc_hash_field_list_comms[] = { * ice_get_vf_vsi - get VF's VSI based on the stored index * @vf: VF used to get VSI */ -static struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf) +struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf) { return vf->pf->vsi[vf->lan_vsi_idx]; } diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h index 842cb077df861..38b4dc82c5c18 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h @@ -111,9 +111,13 @@ struct ice_vf { struct ice_mdd_vf_events mdd_rx_events; struct ice_mdd_vf_events mdd_tx_events; DECLARE_BITMAP(opcodes_allowlist, VIRTCHNL_OP_MAX); + + /* devlink port data */ + struct devlink_port devlink_port; };
#ifdef CONFIG_PCI_IOV +struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf); void ice_process_vflr_event(struct ice_pf *pf); int ice_sriov_configure(struct pci_dev *pdev, int num_vfs); int ice_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac); @@ -171,6 +175,11 @@ static inline void ice_print_vfs_mdd_events(struct ice_pf *pf) { } static inline void ice_print_vf_rx_mdd_event(struct ice_vf *vf) { } static inline void ice_restore_all_vfs_msi_state(struct pci_dev *pdev) { }
+static inline struct ice_vsi *ice_get_vf_vsi(struct ice_vf *vf) +{ + return NULL; +} + static inline bool ice_is_malicious_vf(struct ice_pf __always_unused *pf, struct ice_rq_event_info __always_unused *event,
From: Mirela Rabulea mirela.rabulea@nxp.com
[ Upstream commit 83f5f0633b156c636f5249d3c10f2a9423dd4c96 ]
Found by Coverity scan.
Signed-off-by: Mirela Rabulea mirela.rabulea@nxp.com Reviewed-by: Laurentiu Palcu laurentiu.palcu@nxp.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c index 755138063ee61..33e7604271cdf 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c @@ -575,6 +575,10 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv)
dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + if (!dst_buf || !src_buf) { + dev_err(dev, "No source or destination buffer.\n"); + goto job_unlock; + } jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
if (dec_ret & SLOT_STATUS_ENC_CONFIG_ERR) {
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit 553481e38045f349bb9aa596d03bebd020020c9c ]
For a try_fmt call, the node noes not need to be enabled.
Fixes v4l2-compliance
fail: v4l2-test-formats.cpp(717): Video Output Multiplanar is valid, but no TRY_FMT was implemented test VIDIOC_TRY_FMT: FAIL
Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/ipu3/ipu3-v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 38a2407645096..ea746e8054eb7 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -696,7 +696,7 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node,
/* CSS expects some format on OUT queue */ if (i != IPU3_CSS_QUEUE_OUT && - !imgu_pipe->nodes[inode].enabled) { + !imgu_pipe->nodes[inode].enabled && !try) { fmts[i] = NULL; continue; }
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit ea2b9a33711604e91f8c826f4dcb3c12baa1990a ]
bus_info field had a different value for the media entity and the video device.
Fixes v4l2-compliance:
v4l2-compliance.cpp(637): media bus_info 'PCI:0000:00:05.0' differs from V4L2 bus_info 'PCI:viewfinder'
Reviewed-by: Bingbu Cao bingbu.cao@intel.com Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/media/ipu3/ipu3-v4l2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index ea746e8054eb7..90c86ba5040e3 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -592,11 +592,12 @@ static const struct imgu_fmt *find_format(struct v4l2_format *f, u32 type) static int imgu_vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { - struct imgu_video_device *node = file_to_intel_imgu_node(file); + struct imgu_device *imgu = video_drvdata(file);
strscpy(cap->driver, IMGU_NAME, sizeof(cap->driver)); strscpy(cap->card, IMGU_NAME, sizeof(cap->card)); - snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", node->name); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + pci_name(imgu->pci_dev));
return 0; }
From: Anant Thazhemadam anant.thazhemadam@gmail.com
[ Upstream commit 899a61a3305d49e8a712e9ab20d0db94bde5929f ]
In dibusb_read_eeprom_byte(), if dibusb_i2c_msg() fails, val gets assigned an value that's not properly initialized. Using kzalloc() in place of kmalloc() for the buffer fixes this issue, as the val can now be set to 0 in the event dibusb_i2c_msg() fails.
Reported-by: syzbot+e27b4fd589762b0b9329@syzkaller.appspotmail.com Tested-by: syzbot+e27b4fd589762b0b9329@syzkaller.appspotmail.com Signed-off-by: Anant Thazhemadam anant.thazhemadam@gmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/dvb-usb/dibusb-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c index 02b51d1a1b67c..aff60c10cb0b2 100644 --- a/drivers/media/usb/dvb-usb/dibusb-common.c +++ b/drivers/media/usb/dvb-usb/dibusb-common.c @@ -223,7 +223,7 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) u8 *buf; int rc;
- buf = kmalloc(2, GFP_KERNEL); + buf = kzalloc(2, GFP_KERNEL); if (!buf) return -ENOMEM;
From: Antoine Tenart atenart@kernel.org
[ Upstream commit 146e5e733310379f51924111068f08a3af0db830 ]
Due to deadlocks in the networking subsystem spotted 12 years ago[1], a workaround was put in place[2] to avoid taking the rtnl lock when it was not available and restarting the syscall (back to VFS, letting userspace spin). The following construction is found a lot in the net sysfs and sysctl code:
if (!rtnl_trylock()) return restart_syscall();
This can be problematic when multiple userspace threads use such interfaces in a short period, making them to spin a lot. This happens for example when adding and moving virtual interfaces: userspace programs listening on events, such as systemd-udevd and NetworkManager, do trigger actions reading files in sysfs. It gets worse when a lot of virtual interfaces are created concurrently, say when creating containers at boot time.
Returning early without hitting the above pattern when the syscall will fail eventually does make things better. While it is not a fix for the issue, it does ease things.
[1] https://lore.kernel.org/netdev/49A4D5D5.5090602@trash.net/ https://lore.kernel.org/netdev/m14oyhis31.fsf@fess.ebiederm.org/ and https://lore.kernel.org/netdev/20090226084924.16cb3e08@nehalam/ [2] Rightfully, those deadlocks are *hard* to solve.
Signed-off-by: Antoine Tenart atenart@kernel.org Reviewed-by: Paolo Abeni pabeni@redhat.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/net-sysfs.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index b2e49eb7001d6..dfa5ecff7f738 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -175,6 +175,14 @@ static int change_carrier(struct net_device *dev, unsigned long new_carrier) static ssize_t carrier_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { + struct net_device *netdev = to_net_dev(dev); + + /* The check is also done in change_carrier; this helps returning early + * without hitting the trylock/restart in netdev_store. + */ + if (!netdev->netdev_ops->ndo_change_carrier) + return -EOPNOTSUPP; + return netdev_store(dev, attr, buf, len, change_carrier); }
@@ -196,6 +204,12 @@ static ssize_t speed_show(struct device *dev, struct net_device *netdev = to_net_dev(dev); int ret = -EINVAL;
+ /* The check is also done in __ethtool_get_link_ksettings; this helps + * returning early without hitting the trylock/restart below. + */ + if (!netdev->ethtool_ops->get_link_ksettings) + return ret; + if (!rtnl_trylock()) return restart_syscall();
@@ -216,6 +230,12 @@ static ssize_t duplex_show(struct device *dev, struct net_device *netdev = to_net_dev(dev); int ret = -EINVAL;
+ /* The check is also done in __ethtool_get_link_ksettings; this helps + * returning early without hitting the trylock/restart below. + */ + if (!netdev->ethtool_ops->get_link_ksettings) + return ret; + if (!rtnl_trylock()) return restart_syscall();
@@ -468,6 +488,14 @@ static ssize_t proto_down_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { + struct net_device *netdev = to_net_dev(dev); + + /* The check is also done in change_proto_down; this helps returning + * early without hitting the trylock/restart in netdev_store. + */ + if (!netdev->netdev_ops->ndo_change_proto_down) + return -EOPNOTSUPP; + return netdev_store(dev, attr, buf, len, change_proto_down); } NETDEVICE_SHOW_RW(proto_down, fmt_dec); @@ -478,6 +506,12 @@ static ssize_t phys_port_id_show(struct device *dev, struct net_device *netdev = to_net_dev(dev); ssize_t ret = -EINVAL;
+ /* The check is also done in dev_get_phys_port_id; this helps returning + * early without hitting the trylock/restart below. + */ + if (!netdev->netdev_ops->ndo_get_phys_port_id) + return -EOPNOTSUPP; + if (!rtnl_trylock()) return restart_syscall();
@@ -500,6 +534,13 @@ static ssize_t phys_port_name_show(struct device *dev, struct net_device *netdev = to_net_dev(dev); ssize_t ret = -EINVAL;
+ /* The checks are also done in dev_get_phys_port_name; this helps + * returning early without hitting the trylock/restart below. + */ + if (!netdev->netdev_ops->ndo_get_phys_port_name && + !netdev->netdev_ops->ndo_get_devlink_port) + return -EOPNOTSUPP; + if (!rtnl_trylock()) return restart_syscall();
@@ -522,6 +563,14 @@ static ssize_t phys_switch_id_show(struct device *dev, struct net_device *netdev = to_net_dev(dev); ssize_t ret = -EINVAL;
+ /* The checks are also done in dev_get_phys_port_name; this helps + * returning early without hitting the trylock/restart below. This works + * because recurse is false when calling dev_get_port_parent_id. + */ + if (!netdev->netdev_ops->ndo_get_port_parent_id && + !netdev->netdev_ops->ndo_get_devlink_port) + return -EOPNOTSUPP; + if (!rtnl_trylock()) return restart_syscall();
@@ -1226,6 +1275,12 @@ static ssize_t tx_maxrate_store(struct netdev_queue *queue, if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ /* The check is also done later; this helps returning early without + * hitting the trylock/restart below. + */ + if (!dev->netdev_ops->ndo_set_tx_maxrate) + return -EOPNOTSUPP; + err = kstrtou32(buf, 10, &rate); if (err < 0) return err;
From: Alex Sierra alex.sierra@amd.com
[ Upstream commit ec6abe831a843208e99a59adf108adba22166b3f ]
This fix the deadlock with the BO reservations during SVM_BO evictions while allocations in VRAM are concurrently performed. More specific, while the ttm waits for the fence to be signaled (ttm_bo_wait), it already has the BO reserved. In parallel, the restore worker might be running, prefetching memory to VRAM. This also requires to reserve the BO, but blocks the mmap semaphore first. The deadlock happens when the SVM_BO eviction worker kicks in and waits for the mmap semaphore held in restore worker. Preventing signal the fence back, causing the deadlock until the ttm times out.
We don't need to hold the BO reservation anymore during validation and mapping. Now the physical addresses are taken from hmm_range_fault. We also take migrate_mutex to prevent range migration while validate_and_map update GPU page table.
Signed-off-by: Alex Sierra alex.sierra@amd.com Signed-off-by: Felix Kuehling Felix.Kuehling@amd.com Reviewed-by: Philip Yang philip.yang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 9d0f65a90002d..179080329af89 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -1307,7 +1307,7 @@ struct svm_validate_context { struct svm_range *prange; bool intr; unsigned long bitmap[MAX_GPU_INSTANCE]; - struct ttm_validate_buffer tv[MAX_GPU_INSTANCE+1]; + struct ttm_validate_buffer tv[MAX_GPU_INSTANCE]; struct list_head validate_list; struct ww_acquire_ctx ticket; }; @@ -1334,11 +1334,6 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx) ctx->tv[gpuidx].num_shared = 4; list_add(&ctx->tv[gpuidx].head, &ctx->validate_list); } - if (ctx->prange->svm_bo && ctx->prange->ttm_res) { - ctx->tv[MAX_GPU_INSTANCE].bo = &ctx->prange->svm_bo->bo->tbo; - ctx->tv[MAX_GPU_INSTANCE].num_shared = 1; - list_add(&ctx->tv[MAX_GPU_INSTANCE].head, &ctx->validate_list); - }
r = ttm_eu_reserve_buffers(&ctx->ticket, &ctx->validate_list, ctx->intr, NULL);
From: Steven Rostedt (VMware) rostedt@goodmis.org
[ Upstream commit 49d67e445742bbcb03106b735b2ab39f6e5c56bc ]
The tracefs file system is by default mounted such that only root user can access it. But there are legitimate reasons to create a group and allow those added to the group to have access to tracing. By changing the permissions of the tracefs mount point to allow access, it will allow group access to the tracefs directory.
There should not be any real reason to allow all access to the tracefs directory as it contains sensitive information. Have the default permission of directories being created not have any OTH (other) bits set, such that an admin that wants to give permission to a group has to first disable all OTH bits in the file system.
Link: https://lkml.kernel.org/r/20210818153038.664127804@goodmis.org
Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/tracefs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 1261e8b41edb4..925a621b432e3 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -432,7 +432,8 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, if (unlikely(!inode)) return failed_creating(dentry);
- inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; + /* Do not set bits for OTH */ + inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; inode->i_op = ops; inode->i_fop = &simple_dir_operations;
From: Steven Rostedt (VMware) rostedt@goodmis.org
[ Upstream commit 21ccc9cd72116289469e5519b6159c675a2fa58f ]
When building the files in the tracefs file system, do not by default set any permissions for OTH (other). This will make it easier for admins who want to define a group for accessing tracefs and not having to first disable all the permission bits for "other" in the file system.
As tracing can leak sensitive information, it should never by default allowing all users access. An admin can still set the permission bits for others to have access, which may be useful for creating a honeypot and seeing who takes advantage of it and roots the machine.
Link: https://lkml.kernel.org/r/20210818153038.864149276@goodmis.org
Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/ftrace.c | 23 +++++---- kernel/trace/trace.c | 73 ++++++++++++++------------- kernel/trace/trace.h | 3 ++ kernel/trace/trace_dynevent.c | 2 +- kernel/trace/trace_events.c | 42 +++++++-------- kernel/trace/trace_events_synth.c | 4 +- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_hwlat.c | 6 +-- kernel/trace/trace_kprobe.c | 8 +-- kernel/trace/trace_osnoise.c | 14 ++--- kernel/trace/trace_printk.c | 2 +- kernel/trace/trace_recursion_record.c | 4 +- kernel/trace/trace_stack.c | 6 +-- kernel/trace/trace_stat.c | 6 +-- kernel/trace/trace_uprobe.c | 4 +- 15 files changed, 103 insertions(+), 96 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index feebf57c64588..c672040142e98 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -988,8 +988,9 @@ static __init void ftrace_profile_tracefs(struct dentry *d_tracer) } }
- entry = tracefs_create_file("function_profile_enabled", 0644, - d_tracer, NULL, &ftrace_profile_fops); + entry = tracefs_create_file("function_profile_enabled", + TRACE_MODE_WRITE, d_tracer, NULL, + &ftrace_profile_fops); if (!entry) pr_warn("Could not create tracefs 'function_profile_enabled' entry\n"); } @@ -6109,10 +6110,10 @@ void ftrace_create_filter_files(struct ftrace_ops *ops, struct dentry *parent) {
- trace_create_file("set_ftrace_filter", 0644, parent, + trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent, ops, &ftrace_filter_fops);
- trace_create_file("set_ftrace_notrace", 0644, parent, + trace_create_file("set_ftrace_notrace", TRACE_MODE_WRITE, parent, ops, &ftrace_notrace_fops); }
@@ -6139,19 +6140,19 @@ void ftrace_destroy_filter_files(struct ftrace_ops *ops) static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer) {
- trace_create_file("available_filter_functions", 0444, + trace_create_file("available_filter_functions", TRACE_MODE_READ, d_tracer, NULL, &ftrace_avail_fops);
- trace_create_file("enabled_functions", 0444, + trace_create_file("enabled_functions", TRACE_MODE_READ, d_tracer, NULL, &ftrace_enabled_fops);
ftrace_create_filter_files(&global_ops, d_tracer);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER - trace_create_file("set_graph_function", 0644, d_tracer, + trace_create_file("set_graph_function", TRACE_MODE_WRITE, d_tracer, NULL, &ftrace_graph_fops); - trace_create_file("set_graph_notrace", 0644, d_tracer, + trace_create_file("set_graph_notrace", TRACE_MODE_WRITE, d_tracer, NULL, &ftrace_graph_notrace_fops); #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ @@ -7494,10 +7495,10 @@ static const struct file_operations ftrace_no_pid_fops = {
void ftrace_init_tracefs(struct trace_array *tr, struct dentry *d_tracer) { - trace_create_file("set_ftrace_pid", 0644, d_tracer, + trace_create_file("set_ftrace_pid", TRACE_MODE_WRITE, d_tracer, tr, &ftrace_pid_fops); - trace_create_file("set_ftrace_notrace_pid", 0644, d_tracer, - tr, &ftrace_no_pid_fops); + trace_create_file("set_ftrace_notrace_pid", TRACE_MODE_WRITE, + d_tracer, tr, &ftrace_no_pid_fops); }
void __init ftrace_init_tracefs_toplevel(struct trace_array *tr, diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bc677cd642240..5e452dd57af01 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1714,7 +1714,8 @@ static void trace_create_maxlat_file(struct trace_array *tr, { INIT_WORK(&tr->fsnotify_work, latency_fsnotify_workfn); init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq); - tr->d_max_latency = trace_create_file("tracing_max_latency", 0644, + tr->d_max_latency = trace_create_file("tracing_max_latency", + TRACE_MODE_WRITE, d_tracer, &tr->max_latency, &tracing_max_lat_fops); } @@ -1748,8 +1749,8 @@ void latency_fsnotify(struct trace_array *tr) || defined(CONFIG_OSNOISE_TRACER)
#define trace_create_maxlat_file(tr, d_tracer) \ - trace_create_file("tracing_max_latency", 0644, d_tracer, \ - &tr->max_latency, &tracing_max_lat_fops) + trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \ + d_tracer, &tr->max_latency, &tracing_max_lat_fops)
#else #define trace_create_maxlat_file(tr, d_tracer) do { } while (0) @@ -6077,7 +6078,7 @@ trace_insert_eval_map_file(struct module *mod, struct trace_eval_map **start,
static void trace_create_eval_file(struct dentry *d_tracer) { - trace_create_file("eval_map", 0444, d_tracer, + trace_create_file("eval_map", TRACE_MODE_READ, d_tracer, NULL, &tracing_eval_map_fops); }
@@ -8590,27 +8591,27 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu) }
/* per cpu trace_pipe */ - trace_create_cpu_file("trace_pipe", 0444, d_cpu, + trace_create_cpu_file("trace_pipe", TRACE_MODE_READ, d_cpu, tr, cpu, &tracing_pipe_fops);
/* per cpu trace */ - trace_create_cpu_file("trace", 0644, d_cpu, + trace_create_cpu_file("trace", TRACE_MODE_WRITE, d_cpu, tr, cpu, &tracing_fops);
- trace_create_cpu_file("trace_pipe_raw", 0444, d_cpu, + trace_create_cpu_file("trace_pipe_raw", TRACE_MODE_READ, d_cpu, tr, cpu, &tracing_buffers_fops);
- trace_create_cpu_file("stats", 0444, d_cpu, + trace_create_cpu_file("stats", TRACE_MODE_READ, d_cpu, tr, cpu, &tracing_stats_fops);
- trace_create_cpu_file("buffer_size_kb", 0444, d_cpu, + trace_create_cpu_file("buffer_size_kb", TRACE_MODE_READ, d_cpu, tr, cpu, &tracing_entries_fops);
#ifdef CONFIG_TRACER_SNAPSHOT - trace_create_cpu_file("snapshot", 0644, d_cpu, + trace_create_cpu_file("snapshot", TRACE_MODE_WRITE, d_cpu, tr, cpu, &snapshot_fops);
- trace_create_cpu_file("snapshot_raw", 0444, d_cpu, + trace_create_cpu_file("snapshot_raw", TRACE_MODE_READ, d_cpu, tr, cpu, &snapshot_raw_fops); #endif } @@ -8816,8 +8817,8 @@ create_trace_option_file(struct trace_array *tr, topt->opt = opt; topt->tr = tr;
- topt->entry = trace_create_file(opt->name, 0644, t_options, topt, - &trace_options_fops); + topt->entry = trace_create_file(opt->name, TRACE_MODE_WRITE, + t_options, topt, &trace_options_fops);
}
@@ -8892,7 +8893,7 @@ create_trace_option_core_file(struct trace_array *tr, if (!t_options) return NULL;
- return trace_create_file(option, 0644, t_options, + return trace_create_file(option, TRACE_MODE_WRITE, t_options, (void *)&tr->trace_flags_index[index], &trace_options_core_fops); } @@ -9417,28 +9418,28 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) struct trace_event_file *file; int cpu;
- trace_create_file("available_tracers", 0444, d_tracer, + trace_create_file("available_tracers", TRACE_MODE_READ, d_tracer, tr, &show_traces_fops);
- trace_create_file("current_tracer", 0644, d_tracer, + trace_create_file("current_tracer", TRACE_MODE_WRITE, d_tracer, tr, &set_tracer_fops);
- trace_create_file("tracing_cpumask", 0644, d_tracer, + trace_create_file("tracing_cpumask", TRACE_MODE_WRITE, d_tracer, tr, &tracing_cpumask_fops);
- trace_create_file("trace_options", 0644, d_tracer, + trace_create_file("trace_options", TRACE_MODE_WRITE, d_tracer, tr, &tracing_iter_fops);
- trace_create_file("trace", 0644, d_tracer, + trace_create_file("trace", TRACE_MODE_WRITE, d_tracer, tr, &tracing_fops);
- trace_create_file("trace_pipe", 0444, d_tracer, + trace_create_file("trace_pipe", TRACE_MODE_READ, d_tracer, tr, &tracing_pipe_fops);
- trace_create_file("buffer_size_kb", 0644, d_tracer, + trace_create_file("buffer_size_kb", TRACE_MODE_WRITE, d_tracer, tr, &tracing_entries_fops);
- trace_create_file("buffer_total_size_kb", 0444, d_tracer, + trace_create_file("buffer_total_size_kb", TRACE_MODE_READ, d_tracer, tr, &tracing_total_entries_fops);
trace_create_file("free_buffer", 0200, d_tracer, @@ -9449,25 +9450,25 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
file = __find_event_file(tr, "ftrace", "print"); if (file && file->dir) - trace_create_file("trigger", 0644, file->dir, file, - &event_trigger_fops); + trace_create_file("trigger", TRACE_MODE_WRITE, file->dir, + file, &event_trigger_fops); tr->trace_marker_file = file;
trace_create_file("trace_marker_raw", 0220, d_tracer, tr, &tracing_mark_raw_fops);
- trace_create_file("trace_clock", 0644, d_tracer, tr, + trace_create_file("trace_clock", TRACE_MODE_WRITE, d_tracer, tr, &trace_clock_fops);
- trace_create_file("tracing_on", 0644, d_tracer, + trace_create_file("tracing_on", TRACE_MODE_WRITE, d_tracer, tr, &rb_simple_fops);
- trace_create_file("timestamp_mode", 0444, d_tracer, tr, + trace_create_file("timestamp_mode", TRACE_MODE_READ, d_tracer, tr, &trace_time_stamp_mode_fops);
tr->buffer_percent = 50;
- trace_create_file("buffer_percent", 0444, d_tracer, + trace_create_file("buffer_percent", TRACE_MODE_READ, d_tracer, tr, &buffer_percent_fops);
create_trace_options_dir(tr); @@ -9478,11 +9479,11 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) MEM_FAIL(1, "Could not allocate function filter files");
#ifdef CONFIG_TRACER_SNAPSHOT - trace_create_file("snapshot", 0644, d_tracer, + trace_create_file("snapshot", TRACE_MODE_WRITE, d_tracer, tr, &snapshot_fops); #endif
- trace_create_file("error_log", 0644, d_tracer, + trace_create_file("error_log", TRACE_MODE_WRITE, d_tracer, tr, &tracing_err_log_fops);
for_each_tracing_cpu(cpu) @@ -9675,19 +9676,19 @@ static __init int tracer_init_tracefs(void) init_tracer_tracefs(&global_trace, NULL); ftrace_init_tracefs_toplevel(&global_trace, NULL);
- trace_create_file("tracing_thresh", 0644, NULL, + trace_create_file("tracing_thresh", TRACE_MODE_WRITE, NULL, &global_trace, &tracing_thresh_fops);
- trace_create_file("README", 0444, NULL, + trace_create_file("README", TRACE_MODE_READ, NULL, NULL, &tracing_readme_fops);
- trace_create_file("saved_cmdlines", 0444, NULL, + trace_create_file("saved_cmdlines", TRACE_MODE_READ, NULL, NULL, &tracing_saved_cmdlines_fops);
- trace_create_file("saved_cmdlines_size", 0644, NULL, + trace_create_file("saved_cmdlines_size", TRACE_MODE_WRITE, NULL, NULL, &tracing_saved_cmdlines_size_fops);
- trace_create_file("saved_tgids", 0444, NULL, + trace_create_file("saved_tgids", TRACE_MODE_READ, NULL, NULL, &tracing_saved_tgids_fops);
trace_eval_init(); @@ -9699,7 +9700,7 @@ static __init int tracer_init_tracefs(void) #endif
#ifdef CONFIG_DYNAMIC_FTRACE - trace_create_file("dyn_ftrace_total_info", 0444, NULL, + trace_create_file("dyn_ftrace_total_info", TRACE_MODE_READ, NULL, NULL, &tracing_dyn_info_fops); #endif
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index b7c0f8e160fb4..5c71d32b2860a 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -27,6 +27,9 @@ #include <asm/syscall.h> /* some archs define it here */ #endif
+#define TRACE_MODE_WRITE 0640 +#define TRACE_MODE_READ 0440 + enum trace_type { __TRACE_FIRST_TYPE = 0,
diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c index 1110112e55bd7..e34e8182ee4b5 100644 --- a/kernel/trace/trace_dynevent.c +++ b/kernel/trace/trace_dynevent.c @@ -262,7 +262,7 @@ static __init int init_dynamic_event(void) if (ret) return 0;
- entry = tracefs_create_file("dynamic_events", 0644, NULL, + entry = tracefs_create_file("dynamic_events", TRACE_MODE_WRITE, NULL, NULL, &dynamic_events_ops);
/* Event list interface */ diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 830b3b9940f4c..bb1123ef2a021 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -2312,7 +2312,8 @@ event_subsystem_dir(struct trace_array *tr, const char *name, /* the ftrace system is special, do not create enable or filter files */ if (strcmp(name, "ftrace") != 0) {
- entry = tracefs_create_file("filter", 0644, dir->entry, dir, + entry = tracefs_create_file("filter", TRACE_MODE_WRITE, + dir->entry, dir, &ftrace_subsystem_filter_fops); if (!entry) { kfree(system->filter); @@ -2320,7 +2321,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, pr_warn("Could not create tracefs '%s/filter' entry\n", name); }
- trace_create_file("enable", 0644, dir->entry, dir, + trace_create_file("enable", TRACE_MODE_WRITE, dir->entry, dir, &ftrace_system_enable_fops); }
@@ -2402,12 +2403,12 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file) }
if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) - trace_create_file("enable", 0644, file->dir, file, + trace_create_file("enable", TRACE_MODE_WRITE, file->dir, file, &ftrace_enable_fops);
#ifdef CONFIG_PERF_EVENTS if (call->event.type && call->class->reg) - trace_create_file("id", 0444, file->dir, + trace_create_file("id", TRACE_MODE_READ, file->dir, (void *)(long)call->event.type, &ftrace_event_id_fops); #endif @@ -2423,22 +2424,22 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file) * triggers or filters. */ if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) { - trace_create_file("filter", 0644, file->dir, file, - &ftrace_event_filter_fops); + trace_create_file("filter", TRACE_MODE_WRITE, file->dir, + file, &ftrace_event_filter_fops);
- trace_create_file("trigger", 0644, file->dir, file, - &event_trigger_fops); + trace_create_file("trigger", TRACE_MODE_WRITE, file->dir, + file, &event_trigger_fops); }
#ifdef CONFIG_HIST_TRIGGERS - trace_create_file("hist", 0444, file->dir, file, + trace_create_file("hist", TRACE_MODE_READ, file->dir, file, &event_hist_fops); #endif #ifdef CONFIG_HIST_TRIGGERS_DEBUG - trace_create_file("hist_debug", 0444, file->dir, file, + trace_create_file("hist_debug", TRACE_MODE_READ, file->dir, file, &event_hist_debug_fops); #endif - trace_create_file("format", 0444, file->dir, call, + trace_create_file("format", TRACE_MODE_READ, file->dir, call, &ftrace_event_format_fops);
#ifdef CONFIG_TRACE_EVENT_INJECT @@ -3433,7 +3434,7 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) struct dentry *d_events; struct dentry *entry;
- entry = tracefs_create_file("set_event", 0644, parent, + entry = tracefs_create_file("set_event", TRACE_MODE_WRITE, parent, tr, &ftrace_set_event_fops); if (!entry) { pr_warn("Could not create tracefs 'set_event' entry\n"); @@ -3446,7 +3447,7 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) return -ENOMEM; }
- entry = trace_create_file("enable", 0644, d_events, + entry = trace_create_file("enable", TRACE_MODE_WRITE, d_events, tr, &ftrace_tr_enable_fops); if (!entry) { pr_warn("Could not create tracefs 'enable' entry\n"); @@ -3455,24 +3456,25 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
/* There are not as crucial, just warn if they are not created */
- entry = tracefs_create_file("set_event_pid", 0644, parent, + entry = tracefs_create_file("set_event_pid", TRACE_MODE_WRITE, parent, tr, &ftrace_set_event_pid_fops); if (!entry) pr_warn("Could not create tracefs 'set_event_pid' entry\n");
- entry = tracefs_create_file("set_event_notrace_pid", 0644, parent, - tr, &ftrace_set_event_notrace_pid_fops); + entry = tracefs_create_file("set_event_notrace_pid", + TRACE_MODE_WRITE, parent, tr, + &ftrace_set_event_notrace_pid_fops); if (!entry) pr_warn("Could not create tracefs 'set_event_notrace_pid' entry\n");
/* ring buffer internal formats */ - entry = trace_create_file("header_page", 0444, d_events, + entry = trace_create_file("header_page", TRACE_MODE_READ, d_events, ring_buffer_print_page_header, &ftrace_show_header_fops); if (!entry) pr_warn("Could not create tracefs 'header_page' entry\n");
- entry = trace_create_file("header_event", 0444, d_events, + entry = trace_create_file("header_event", TRACE_MODE_READ, d_events, ring_buffer_print_entry_header, &ftrace_show_header_fops); if (!entry) @@ -3689,8 +3691,8 @@ __init int event_trace_init(void) if (!tr) return -ENODEV;
- entry = tracefs_create_file("available_events", 0444, NULL, - tr, &ftrace_avail_fops); + entry = tracefs_create_file("available_events", TRACE_MODE_READ, + NULL, tr, &ftrace_avail_fops); if (!entry) pr_warn("Could not create tracefs 'available_events' entry\n");
diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index d54094b7a9d75..22db3ce95e74f 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -2227,8 +2227,8 @@ static __init int trace_events_synth_init(void) if (err) goto err;
- entry = tracefs_create_file("synthetic_events", 0644, NULL, - NULL, &synth_events_fops); + entry = tracefs_create_file("synthetic_events", TRACE_MODE_WRITE, + NULL, NULL, &synth_events_fops); if (!entry) { err = -ENODEV; goto err; diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 0de6837722da5..6b5ff3ba4251f 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1340,7 +1340,7 @@ static __init int init_graph_tracefs(void) if (ret) return 0;
- trace_create_file("max_graph_depth", 0644, NULL, + trace_create_file("max_graph_depth", TRACE_MODE_WRITE, NULL, NULL, &graph_depth_fops);
return 0; diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c index 1b83d75eb103b..d0a730d99a331 100644 --- a/kernel/trace/trace_hwlat.c +++ b/kernel/trace/trace_hwlat.c @@ -782,21 +782,21 @@ static int init_tracefs(void) if (!top_dir) return -ENOMEM;
- hwlat_sample_window = tracefs_create_file("window", 0640, + hwlat_sample_window = tracefs_create_file("window", TRACE_MODE_WRITE, top_dir, &hwlat_window, &trace_min_max_fops); if (!hwlat_sample_window) goto err;
- hwlat_sample_width = tracefs_create_file("width", 0644, + hwlat_sample_width = tracefs_create_file("width", TRACE_MODE_WRITE, top_dir, &hwlat_width, &trace_min_max_fops); if (!hwlat_sample_width) goto err;
- hwlat_thread_mode = trace_create_file("mode", 0644, + hwlat_thread_mode = trace_create_file("mode", TRACE_MODE_WRITE, top_dir, NULL, &thread_mode_fops); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 3a64ba4bbad6f..92caef33b68c2 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1925,16 +1925,16 @@ static __init int init_kprobe_trace(void) if (ret) return 0;
- entry = tracefs_create_file("kprobe_events", 0644, NULL, - NULL, &kprobe_events_ops); + entry = tracefs_create_file("kprobe_events", TRACE_MODE_WRITE, + NULL, NULL, &kprobe_events_ops);
/* Event list interface */ if (!entry) pr_warn("Could not create tracefs 'kprobe_events' entry\n");
/* Profile interface */ - entry = tracefs_create_file("kprobe_profile", 0444, NULL, - NULL, &kprobe_profile_ops); + entry = tracefs_create_file("kprobe_profile", TRACE_MODE_READ, + NULL, NULL, &kprobe_profile_ops);
if (!entry) pr_warn("Could not create tracefs 'kprobe_profile' entry\n"); diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index ce053619f289e..c4f14fb98aaac 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -1856,38 +1856,38 @@ static int init_tracefs(void) if (!top_dir) return 0;
- tmp = tracefs_create_file("period_us", 0640, top_dir, + tmp = tracefs_create_file("period_us", TRACE_MODE_WRITE, top_dir, &osnoise_period, &trace_min_max_fops); if (!tmp) goto err;
- tmp = tracefs_create_file("runtime_us", 0644, top_dir, + tmp = tracefs_create_file("runtime_us", TRACE_MODE_WRITE, top_dir, &osnoise_runtime, &trace_min_max_fops); if (!tmp) goto err;
- tmp = tracefs_create_file("stop_tracing_us", 0640, top_dir, + tmp = tracefs_create_file("stop_tracing_us", TRACE_MODE_WRITE, top_dir, &osnoise_stop_tracing_in, &trace_min_max_fops); if (!tmp) goto err;
- tmp = tracefs_create_file("stop_tracing_total_us", 0640, top_dir, + tmp = tracefs_create_file("stop_tracing_total_us", TRACE_MODE_WRITE, top_dir, &osnoise_stop_tracing_total, &trace_min_max_fops); if (!tmp) goto err;
- tmp = trace_create_file("cpus", 0644, top_dir, NULL, &cpus_fops); + tmp = trace_create_file("cpus", TRACE_MODE_WRITE, top_dir, NULL, &cpus_fops); if (!tmp) goto err; #ifdef CONFIG_TIMERLAT_TRACER #ifdef CONFIG_STACKTRACE - tmp = tracefs_create_file("print_stack", 0640, top_dir, + tmp = tracefs_create_file("print_stack", TRACE_MODE_WRITE, top_dir, &osnoise_print_stack, &trace_min_max_fops); if (!tmp) goto err; #endif
- tmp = tracefs_create_file("timerlat_period_us", 0640, top_dir, + tmp = tracefs_create_file("timerlat_period_us", TRACE_MODE_WRITE, top_dir, &timerlat_period, &trace_min_max_fops); if (!tmp) goto err; diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index 4b320fe7df704..29f6e95439b67 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c @@ -384,7 +384,7 @@ static __init int init_trace_printk_function_export(void) if (ret) return 0;
- trace_create_file("printk_formats", 0444, NULL, + trace_create_file("printk_formats", TRACE_MODE_READ, NULL, NULL, &ftrace_formats_fops);
return 0; diff --git a/kernel/trace/trace_recursion_record.c b/kernel/trace/trace_recursion_record.c index b2edac1fe156e..4d4b78c8ca257 100644 --- a/kernel/trace/trace_recursion_record.c +++ b/kernel/trace/trace_recursion_record.c @@ -226,8 +226,8 @@ __init static int create_recursed_functions(void) { struct dentry *dentry;
- dentry = trace_create_file("recursed_functions", 0644, NULL, NULL, - &recursed_functions_fops); + dentry = trace_create_file("recursed_functions", TRACE_MODE_WRITE, + NULL, NULL, &recursed_functions_fops); if (!dentry) pr_warn("WARNING: Failed to create recursed_functions\n"); return 0; diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 63c2850420516..5a48dba912eae 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -559,14 +559,14 @@ static __init int stack_trace_init(void) if (ret) return 0;
- trace_create_file("stack_max_size", 0644, NULL, + trace_create_file("stack_max_size", TRACE_MODE_WRITE, NULL, &stack_trace_max_size, &stack_max_size_fops);
- trace_create_file("stack_trace", 0444, NULL, + trace_create_file("stack_trace", TRACE_MODE_READ, NULL, NULL, &stack_trace_fops);
#ifdef CONFIG_DYNAMIC_FTRACE - trace_create_file("stack_trace_filter", 0644, NULL, + trace_create_file("stack_trace_filter", TRACE_MODE_WRITE, NULL, &trace_ops, &stack_trace_filter_fops); #endif
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index 8d141c3825a94..bb247beec4470 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c @@ -297,9 +297,9 @@ static int init_stat_file(struct stat_session *session) if (!stat_dir && (ret = tracing_stat_init())) return ret;
- session->file = tracefs_create_file(session->ts->name, 0644, - stat_dir, - session, &tracing_stat_fops); + session->file = tracefs_create_file(session->ts->name, TRACE_MODE_WRITE, + stat_dir, session, + &tracing_stat_fops); if (!session->file) return -ENOMEM; return 0; diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 225ce569bf8f8..0a5c0db3137ee 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -1655,10 +1655,10 @@ static __init int init_uprobe_trace(void) if (ret) return 0;
- trace_create_file("uprobe_events", 0644, NULL, + trace_create_file("uprobe_events", TRACE_MODE_WRITE, NULL, NULL, &uprobe_events_ops); /* Profile interface */ - trace_create_file("uprobe_profile", 0444, NULL, + trace_create_file("uprobe_profile", TRACE_MODE_READ, NULL, NULL, &uprobe_profile_ops); return 0; }
From: Tuo Li islituo@gmail.com
[ Upstream commit 4b6012a7830b813799a7faf40daa02a837e0fd5b ]
kzalloc() is used to allocate memory for cd->detectors, and if it fails, channel_detector_exit() behind the label fail will be called: channel_detector_exit(dpd, cd);
In channel_detector_exit(), cd->detectors is dereferenced through: struct pri_detector *de = cd->detectors[i];
To fix this possible null-pointer dereference, check cd->detectors before the for loop to dereference cd->detectors.
Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Tuo Li islituo@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210805153854.154066-1-islituo@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/dfs_pattern_detector.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c index 80390495ea250..75cb53a3ec15e 100644 --- a/drivers/net/wireless/ath/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/dfs_pattern_detector.c @@ -183,10 +183,12 @@ static void channel_detector_exit(struct dfs_pattern_detector *dpd, if (cd == NULL) return; list_del(&cd->head); - for (i = 0; i < dpd->num_radar_types; i++) { - struct pri_detector *de = cd->detectors[i]; - if (de != NULL) - de->exit(de); + if (cd->detectors) { + for (i = 0; i < dpd->num_radar_types; i++) { + struct pri_detector *de = cd->detectors[i]; + if (de != NULL) + de->exit(de); + } } kfree(cd->detectors); kfree(cd);
From: Will Deacon will@kernel.org
[ Upstream commit 2f2e1a5069679491d18cf9021da19b40c56a17f3 ]
If the __pkvm_prot_finalize hypercall returns an error, we WARN but fail to propagate the failure code back to kvm_arch_init().
Pass a pointer to a zero-initialised return variable so that failure to finalise the pKVM protections on a host CPU can be reported back to KVM.
Cc: Marc Zyngier maz@kernel.org Cc: Quentin Perret qperret@google.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211008135839.1193-5-will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kvm/arm.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index fe102cd2e5183..9b328bb05596a 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1971,9 +1971,25 @@ out_err: return err; }
-static void _kvm_host_prot_finalize(void *discard) +static void _kvm_host_prot_finalize(void *arg) { - WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)); + int *err = arg; + + if (WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize))) + WRITE_ONCE(*err, -EINVAL); +} + +static int pkvm_drop_host_privileges(void) +{ + int ret = 0; + + /* + * Flip the static key upfront as that may no longer be possible + * once the host stage 2 is installed. + */ + static_branch_enable(&kvm_protected_mode_initialized); + on_each_cpu(_kvm_host_prot_finalize, &ret, 1); + return ret; }
static int finalize_hyp_mode(void) @@ -1987,15 +2003,7 @@ static int finalize_hyp_mode(void) * None of other sections should ever be introspected. */ kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); - - /* - * Flip the static key upfront as that may no longer be possible - * once the host stage 2 is installed. - */ - static_branch_enable(&kvm_protected_mode_initialized); - on_each_cpu(_kvm_host_prot_finalize, NULL, 1); - - return 0; + return pkvm_drop_host_privileges(); }
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
From: Xin Xiong xiongx18@fudan.edu.cn
[ Upstream commit 8105c2abbf36296bf38ca44f55ee45d160db476a ]
The issue happens in several error handling paths on two refcounted object related to the object "host" (dma_chan_rx, dma_chan_tx). In these paths, the function forgets to decrement one or both objects' reference count increased earlier by dma_request_chan(), causing reference count leaks.
Fix it by balancing the refcounts of both objects in some error handling paths. In correspondence with the changes in moxart_probe(), IS_ERR() is replaced with IS_ERR_OR_NULL() in moxart_remove() as well.
Signed-off-by: Xin Xiong xiongx18@fudan.edu.cn Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Link: https://lore.kernel.org/r/20211009041918.28419-1-xiongx18@fudan.edu.cn Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/moxart-mmc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index 6c9d38132f74c..7b9fcef490de7 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c @@ -621,6 +621,14 @@ static int moxart_probe(struct platform_device *pdev) ret = -EPROBE_DEFER; goto out; } + if (!IS_ERR(host->dma_chan_tx)) { + dma_release_channel(host->dma_chan_tx); + host->dma_chan_tx = NULL; + } + if (!IS_ERR(host->dma_chan_rx)) { + dma_release_channel(host->dma_chan_rx); + host->dma_chan_rx = NULL; + } dev_dbg(dev, "PIO mode transfer enabled\n"); host->have_dma = false; } else { @@ -675,6 +683,10 @@ static int moxart_probe(struct platform_device *pdev) return 0;
out: + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) + dma_release_channel(host->dma_chan_tx); + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) + dma_release_channel(host->dma_chan_rx); if (mmc) mmc_free_host(mmc); return ret; @@ -687,9 +699,9 @@ static int moxart_remove(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, NULL);
- if (!IS_ERR(host->dma_chan_tx)) + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) dma_release_channel(host->dma_chan_tx); - if (!IS_ERR(host->dma_chan_rx)) + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) dma_release_channel(host->dma_chan_rx); mmc_remove_host(mmc); mmc_free_host(mmc);
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit 814a66741b9ffb5e1ba119e368b178edb0b7322d ]
Both iov_iter_get_pages and iov_iter_get_pages_alloc return the number of bytes of the iovec they could get the pages for. When they cannot get any pages, they're supposed to return 0, but when the start of the iovec isn't page aligned, the calculation goes wrong and they return a negative value. Fix both functions.
In addition, change iov_iter_get_pages_alloc to return NULL in that case to prevent resource leaks.
Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- lib/iov_iter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 755c10c5138cd..60b5e6edfbaa7 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -1488,7 +1488,7 @@ ssize_t iov_iter_get_pages(struct iov_iter *i, res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE ? FOLL_WRITE : 0, pages); - if (unlikely(res < 0)) + if (unlikely(res <= 0)) return res; return (res == n ? len : res * PAGE_SIZE) - *start; } @@ -1612,8 +1612,9 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, return -ENOMEM; res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE ? FOLL_WRITE : 0, p); - if (unlikely(res < 0)) { + if (unlikely(res <= 0)) { kvfree(p); + *pages = NULL; return res; } *pages = p;
From: André Almeida andrealmeid@collabora.com
[ Upstream commit 2835f327bd1240508db2c89fe94a056faa53c49a ]
Some buggy firmware and/or brand new batteries can support a charge that's slightly over the reported design capacity. In such cases, the kernel will report to userspace that the charging state of the battery is "Unknown", when in reality the battery charge is "Full", at least from the design capacity point of view. Make the fallback condition accepts capacities over the designed capacity so userspace knows that is full.
Signed-off-by: André Almeida andrealmeid@collabora.com Reviewed-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dae91f906cea9..8afa85d6eb6a7 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -169,7 +169,7 @@ static int acpi_battery_is_charged(struct acpi_battery *battery) return 1;
/* fallback to using design values for broken batteries */ - if (battery->design_capacity == battery->capacity_now) + if (battery->design_capacity <= battery->capacity_now) return 1;
/* we don't do any sort of metric based on percentages */
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit c10383e8ddf4810b9a5c1595404c2724d925a0a6 ]
On some systems the ACPI namespace contains device objects that are not used in certain configurations of the system. If they start off in the D0 power state configuration, they will stay in it until the system reboots, because of the lack of any mechanism possibly causing their configuration to change. If that happens, they may prevent some power resources from being turned off or generally they may prevent the platform from getting into the deepest low-power states thus causing some energy to be wasted.
Address this issue by changing the configuration of unused ACPI device objects to the D3cold power state one after carrying out the ACPI-based enumeration of devices.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214091 Link: https://lore.kernel.org/linux-acpi/20211007205126.11769-1-mario.limonciello@... Reported-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Tested-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/glue.c | 25 +++++++++++++++++++++++++ drivers/acpi/internal.h | 1 + drivers/acpi/scan.c | 6 ++++++ 3 files changed, 32 insertions(+)
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 7a33a6d985f89..1cfafa254e3d4 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -340,3 +340,28 @@ void acpi_device_notify_remove(struct device *dev)
acpi_unbind_one(dev); } + +int acpi_dev_turn_off_if_unused(struct device *dev, void *not_used) +{ + struct acpi_device *adev = to_acpi_device(dev); + + /* + * Skip device objects with device IDs, because they may be in use even + * if they are not companions of any physical device objects. + */ + if (adev->pnp.type.hardware_id) + return 0; + + mutex_lock(&adev->physical_node_lock); + + /* + * Device objects without device IDs are not in use if they have no + * corresponding physical device objects. + */ + if (list_empty(&adev->physical_node_list)) + acpi_device_set_power(adev, ACPI_STATE_D3_COLD); + + mutex_unlock(&adev->physical_node_lock); + + return 0; +} diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index d91b560e88674..8fbdc172864b0 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -117,6 +117,7 @@ bool acpi_device_is_battery(struct acpi_device *adev); bool acpi_device_is_first_physical_node(struct acpi_device *adev, const struct device *dev); int acpi_bus_register_early_device(int type); +int acpi_dev_turn_off_if_unused(struct device *dev, void *not_used);
/* -------------------------------------------------------------------------- Device Matching and Notification diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5b54c80b9d32a..770b82483d74d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2559,6 +2559,12 @@ int __init acpi_scan_init(void) } }
+ /* + * Make sure that power management resources are not blocked by ACPI + * device objects with no users. + */ + bus_for_each_dev(&acpi_bus_type, NULL, NULL, acpi_dev_turn_off_if_unused); + acpi_turn_off_unused_power_resources();
acpi_scan_initialized = true;
From: Aurabindo Pillai aurabindo.pillai@amd.com
[ Upstream commit 1f3b22e4eb162e0b1d423106a47484943a22a309 ]
[Why&How] When system boots in headless mode, connecting a 4k display creates a null pointer dereference due to hubp for a certain plane being null. Add a condition to check for null hubp before dereferencing it.
Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Reviewed-by: Harry Wentland harry.wentland@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index fafed1e4a998d..0950784bafa49 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -1002,7 +1002,8 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc, /* turning off DPG */ pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, false); for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) - mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false); + if (mpcc_pipe->plane_res.hubp) + mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false);
stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space, color_depth, solid_color, width, height, offset);
From: Yifan Zhang yifan1.zhang@amd.com
[ Upstream commit 6f4b590aae217da16cfa44039a2abcfb209137ab ]
When IOMMU disabled in sbios and kfd in iommuv2 path, IOMMU resume failure blocks system resume. Don't allow kfd to use iommu v2 when iommu is disabled.
Reported-by: youling youling257@gmail.com Tested-by: youling youling257@gmail.com Signed-off-by: Yifan Zhang yifan1.zhang@amd.com Reviewed-by: James Zhu James.Zhu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index a6afacc3b10cd..88c483f699894 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -916,6 +916,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, kfd_double_confirm_iommu_support(kfd);
if (kfd_iommu_device_init(kfd)) { + kfd->use_iommu_v2 = false; dev_err(kfd_device, "Error initializing iommuv2\n"); goto device_iommu_error; }
From: Matthias Schiffer matthias.schiffer@ew.tq-group.com
[ Upstream commit 67ca5159dbe2edb5dae7544447b8677d2596933a ]
It seems reasonable to fine-tune only some of the skew values when using one of the rgmii-*id PHY modes, and even when all skew values are specified, using the correct ID PHY mode makes sense for documentation purposes. Such a configuration also appears in the binding docs in Documentation/devicetree/bindings/net/micrel-ksz90x1.txt, so the driver should not warn about it.
Signed-off-by: Matthias Schiffer matthias.schiffer@ew.tq-group.com Link: https://lore.kernel.org/r/20211012103402.21438-1-matthias.schiffer@ew.tq-gro... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/micrel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 5c928f827173c..643b1c1827a92 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -863,9 +863,9 @@ static int ksz9031_config_init(struct phy_device *phydev) MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4, tx_data_skews, 4, &update);
- if (update && phydev->interface != PHY_INTERFACE_MODE_RGMII) + if (update && !phy_interface_is_rgmii(phydev)) phydev_warn(phydev, - "*-skew-ps values should be used only with phy-mode = "rgmii"\n"); + "*-skew-ps values should be used only with RGMII PHY modes\n");
/* Silicon Errata Sheet (DS80000691D or DS80000692D): * When the device links in the 1000BASE-T slave mode only,
From: Kees Cook keescook@chromium.org
[ Upstream commit cf2a85efdade117e2169d6e26641016cbbf03ef0 ]
For files that lack trailing newlines and match a leaking address (e.g. wchan[1]), the leaking_addresses.pl report would run together with the next line, making things look corrupted.
Unconditionally remove the newline on input, and write it back out on output.
[1] https://lore.kernel.org/all/20210103142726.GC30643@xsang-OptiPlex-9020/
Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20211008111626.151570317@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/leaking_addresses.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl index b2d8b8aa2d99e..8f636a23bc3f2 100755 --- a/scripts/leaking_addresses.pl +++ b/scripts/leaking_addresses.pl @@ -455,8 +455,9 @@ sub parse_file
open my $fh, "<", $file or return; while ( <$fh> ) { + chomp; if (may_leak_address($_)) { - print $file . ': ' . $_; + printf("$file: $_\n"); } } close $fh;
From: Yuanzheng Song songyuanzheng@huawei.com
[ Upstream commit 1dd7128b839f631b31a9e9dce3aaf639bef74e9d ]
If both dev_set_name() and device_register() failed, then null pointer dereference occurs in thermal_release() which will use strncmp() to compare the name.
So fix it by adding dev_set_name() return value check.
Signed-off-by: Yuanzheng Song songyuanzheng@huawei.com Link: https://lore.kernel.org/r/20211015083230.67658-1-songyuanzheng@huawei.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/thermal_core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 51374f4e1ccaf..d094ebbde0ed7 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -902,6 +902,10 @@ __thermal_cooling_device_register(struct device_node *np, goto out_kfree_cdev; cdev->id = ret;
+ ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id); + if (ret) + goto out_ida_remove; + cdev->type = kstrdup(type ? type : "", GFP_KERNEL); if (!cdev->type) { ret = -ENOMEM; @@ -916,7 +920,6 @@ __thermal_cooling_device_register(struct device_node *np, cdev->device.class = &thermal_class; cdev->devdata = devdata; thermal_cooling_device_setup_sysfs(cdev); - dev_set_name(&cdev->device, "cooling_device%d", cdev->id); ret = device_register(&cdev->device); if (ret) goto out_kfree_type; @@ -1227,6 +1230,10 @@ thermal_zone_device_register(const char *type, int trips, int mask, tz->id = id; strlcpy(tz->type, type, sizeof(tz->type));
+ result = dev_set_name(&tz->device, "thermal_zone%d", tz->id); + if (result) + goto remove_id; + if (!ops->critical) ops->critical = thermal_zone_device_critical;
@@ -1248,7 +1255,6 @@ thermal_zone_device_register(const char *type, int trips, int mask, /* A new thermal zone needs to be updated anyway. */ atomic_set(&tz->need_update, 1);
- dev_set_name(&tz->device, "thermal_zone%d", tz->id); result = device_register(&tz->device); if (result) goto release_device;
From: Tim Gardner tim.gardner@canonical.com
[ Upstream commit b220c154832c5cd0df34cbcbcc19d7135c16e823 ]
Coverity complains of a possible NULL dereference:
CID 120718 (#1 of 1): Dereference null return value (NULL_RETURNS) 23. dereference: Dereferencing a pointer that might be NULL state->bos when calling msm_gpu_crashstate_get_bo. [show details] 301 msm_gpu_crashstate_get_bo(state, submit->bos[i].obj, 302 submit->bos[i].iova, submit->bos[i].flags);
Fix this by employing the same state->bos NULL check as is used in the next for loop.
Cc: Rob Clark robdclark@gmail.com Cc: Sean Paul sean@poorly.run Cc: David Airlie airlied@linux.ie Cc: Daniel Vetter daniel@ffwll.ch Cc: linux-arm-msm@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: freedreno@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Tim Gardner tim.gardner@canonical.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://lore.kernel.org/r/20210929162554.14295-1-tim.gardner@canonical.com Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 8a3a592da3a4d..2c46cd968ac4c 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -296,7 +296,7 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, state->bos = kcalloc(nr, sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
- for (i = 0; i < submit->nr_bos; i++) { + for (i = 0; state->bos && i < submit->nr_bos; i++) { if (should_dump(submit, i)) { msm_gpu_crashstate_get_bo(state, submit->bos[i].obj, submit->bos[i].iova, submit->bos[i].flags);
From: Ansuel Smith ansuelsmth@gmail.com
[ Upstream commit d012f9189fda0f3a1b303780ba0bbc7298d0d349 ]
The function can loop and lock the system if for whatever reason the bit for the target sensor is NEVER valid. This is the case if a sensor is disabled by the factory and the valid bit is never reported as actually valid. Add a timeout check and exit if a timeout occurs. As this is a very rare condition, handle the timeout only if the first read fails. While at it also rework the function to improve readability and convert to poll_timeout generic macro.
Signed-off-by: Ansuel Smith ansuelsmth@gmail.com Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211007172859.583-1-ansuelsmth@gmail.com Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/qcom/tsens.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/drivers/thermal/qcom/tsens.c b/drivers/thermal/qcom/tsens.c index b1162e566a707..99a8d9f3e03ca 100644 --- a/drivers/thermal/qcom/tsens.c +++ b/drivers/thermal/qcom/tsens.c @@ -603,22 +603,21 @@ int get_temp_tsens_valid(const struct tsens_sensor *s, int *temp) int ret;
/* VER_0 doesn't have VALID bit */ - if (tsens_version(priv) >= VER_0_1) { - ret = regmap_field_read(priv->rf[valid_idx], &valid); - if (ret) - return ret; - while (!valid) { - /* Valid bit is 0 for 6 AHB clock cycles. - * At 19.2MHz, 1 AHB clock is ~60ns. - * We should enter this loop very, very rarely. - */ - ndelay(400); - ret = regmap_field_read(priv->rf[valid_idx], &valid); - if (ret) - return ret; - } - } + if (tsens_version(priv) == VER_0) + goto get_temp; + + /* Valid bit is 0 for 6 AHB clock cycles. + * At 19.2MHz, 1 AHB clock is ~60ns. + * We should enter this loop very, very rarely. + * Wait 1 us since it's the min of poll_timeout macro. + * Old value was 400 ns. + */ + ret = regmap_field_read_poll_timeout(priv->rf[valid_idx], valid, + valid, 1, 20 * USEC_PER_MSEC); + if (ret) + return ret;
+get_temp: /* Valid bit is set, OK to read the temperature */ *temp = tsens_hw_to_mC(s, temp_idx);
From: Jens Axboe axboe@kernel.dk
[ Upstream commit ba0ffdd8ce48ad7f7e85191cd29f9674caca3745 ]
Particularly for NVMe with efficient deferred submission for many requests, there are nice benefits to be seen by bumping the default max plug count from 16 to 32. This is especially true for virtualized setups, where the submit part is more expensive. But can be noticed even on native hardware.
Reduce the multiple queue factor from 4 to 2, since we're changing the default size.
While changing it, move the defines into the block layer private header. These aren't values that anyone outside of the block layer uses, or should use.
Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-mq.c | 4 ++-- block/blk.h | 6 ++++++ include/linux/blkdev.h | 2 -- 3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c index 652a31fc3bb38..49587c181e3fd 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2148,14 +2148,14 @@ static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq) }
/* - * Allow 4x BLK_MAX_REQUEST_COUNT requests on plug queue for multiple + * Allow 2x BLK_MAX_REQUEST_COUNT requests on plug queue for multiple * queues. This is important for md arrays to benefit from merging * requests. */ static inline unsigned short blk_plug_max_rq_count(struct blk_plug *plug) { if (plug->multiple_queues) - return BLK_MAX_REQUEST_COUNT * 4; + return BLK_MAX_REQUEST_COUNT * 2; return BLK_MAX_REQUEST_COUNT; }
diff --git a/block/blk.h b/block/blk.h index 6c3c00a8fe19d..aab72194d2266 100644 --- a/block/blk.h +++ b/block/blk.h @@ -184,6 +184,12 @@ bool blk_bio_list_merge(struct request_queue *q, struct list_head *list, void blk_account_io_start(struct request *req); void blk_account_io_done(struct request *req, u64 now);
+/* + * Plug flush limits + */ +#define BLK_MAX_REQUEST_COUNT 32 +#define BLK_PLUG_FLUSH_SIZE (128 * 1024) + /* * Internal elevator interface */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 12b9dbcc980ee..683aee3654200 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1198,8 +1198,6 @@ struct blk_plug { bool multiple_queues; bool nowait; }; -#define BLK_MAX_REQUEST_COUNT 16 -#define BLK_PLUG_FLUSH_SIZE (128 * 1024)
struct blk_plug_cb; typedef void (*blk_plug_cb_fn)(struct blk_plug_cb *, bool);
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit 662167e59d2f3c15a44a88088fc6c1a67c8a3650 ]
platform_device_unregister() should only be called when a respective platform_device_register() is called. However the floppy driver currently allows failures when registring a drive and a bail out could easily cause an invalid call to platform_device_unregister() where it was not intended.
Fix this by adding a bool to keep track of when the platform device was registered for a drive.
This does not fix any known panic / bug. This issue was found through code inspection while preparing the driver to use the up and coming support for device_add_disk() error handling.
From what I can tell from code inspection, chances of this
ever happening should be insanely small, perhaps OOM.
Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20210927220302.1073499-5-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/floppy.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 9538146e520e0..3592a6277d0bb 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4478,6 +4478,7 @@ static const struct blk_mq_ops floppy_mq_ops = { };
static struct platform_device floppy_device[N_DRIVE]; +static bool registered[N_DRIVE];
static bool floppy_available(int drive) { @@ -4693,6 +4694,8 @@ static int __init do_floppy_init(void) if (err) goto out_remove_drives;
+ registered[drive] = true; + device_add_disk(&floppy_device[drive].dev, disks[drive][0], NULL); } @@ -4703,7 +4706,8 @@ out_remove_drives: while (drive--) { if (floppy_available(drive)) { del_gendisk(disks[drive][0]); - platform_device_unregister(&floppy_device[drive]); + if (registered[drive]) + platform_device_unregister(&floppy_device[drive]); } } out_release_dma: @@ -4946,7 +4950,8 @@ static void __exit floppy_module_exit(void) if (disks[drive][i]) del_gendisk(disks[drive][i]); } - platform_device_unregister(&floppy_device[drive]); + if (registered[drive]) + platform_device_unregister(&floppy_device[drive]); } for (i = 0; i < ARRAY_SIZE(floppy_type); i++) { if (disks[drive][i])
From: Xiao Ni xni@redhat.com
[ Upstream commit 8b9e2291e355a0eafdd5b1e21a94a6659f24b351 ]
When the in memory flag is changed, we need to persist the change in the rdev superblock flags. This is needed for "writemostly" and "failfast".
Reviewed-by: Li Feng fengli@smartx.com Signed-off-by: Xiao Ni xni@redhat.com Signed-off-by: Song Liu songliubraving@fb.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c index 6c0c3d0d905aa..e89eb467f1429 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2976,7 +2976,11 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len) * -write_error - clears WriteErrorSeen * {,-}failfast - set/clear FailFast */ + + struct mddev *mddev = rdev->mddev; int err = -EINVAL; + bool need_update_sb = false; + if (cmd_match(buf, "faulty") && rdev->mddev->pers) { md_error(rdev->mddev, rdev); if (test_bit(Faulty, &rdev->flags)) @@ -2991,7 +2995,6 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len) if (rdev->raid_disk >= 0) err = -EBUSY; else { - struct mddev *mddev = rdev->mddev; err = 0; if (mddev_is_clustered(mddev)) err = md_cluster_ops->remove_disk(mddev, rdev); @@ -3008,10 +3011,12 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len) } else if (cmd_match(buf, "writemostly")) { set_bit(WriteMostly, &rdev->flags); mddev_create_serial_pool(rdev->mddev, rdev, false); + need_update_sb = true; err = 0; } else if (cmd_match(buf, "-writemostly")) { mddev_destroy_serial_pool(rdev->mddev, rdev, false); clear_bit(WriteMostly, &rdev->flags); + need_update_sb = true; err = 0; } else if (cmd_match(buf, "blocked")) { set_bit(Blocked, &rdev->flags); @@ -3037,9 +3042,11 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len) err = 0; } else if (cmd_match(buf, "failfast")) { set_bit(FailFast, &rdev->flags); + need_update_sb = true; err = 0; } else if (cmd_match(buf, "-failfast")) { clear_bit(FailFast, &rdev->flags); + need_update_sb = true; err = 0; } else if (cmd_match(buf, "-insync") && rdev->raid_disk >= 0 && !test_bit(Journal, &rdev->flags)) { @@ -3118,6 +3125,8 @@ state_store(struct md_rdev *rdev, const char *buf, size_t len) clear_bit(ExternalBbl, &rdev->flags); err = 0; } + if (need_update_sb) + md_update_sb(mddev, 1); if (!err) sysfs_notify_dirent_safe(rdev->sysfs_state); return err ? err : len;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 738216c1953e802aa9f930c5d15b8f9092c847ff ]
In r592_remove(), the driver will free dma after freeing the host, which may cause a UAF bug.
The following log reveals it:
[ 45.361796 ] BUG: KASAN: use-after-free in r592_remove+0x269/0x350 [r592] [ 45.364286 ] Call Trace: [ 45.364472 ] dump_stack_lvl+0xa8/0xd1 [ 45.364751 ] print_address_description+0x87/0x3b0 [ 45.365137 ] kasan_report+0x172/0x1c0 [ 45.365415 ] ? r592_remove+0x269/0x350 [r592] [ 45.365834 ] ? r592_remove+0x269/0x350 [r592] [ 45.366168 ] __asan_report_load8_noabort+0x14/0x20 [ 45.366531 ] r592_remove+0x269/0x350 [r592] [ 45.378785 ] [ 45.378903 ] Allocated by task 4674: [ 45.379162 ] ____kasan_kmalloc+0xb5/0xe0 [ 45.379455 ] __kasan_kmalloc+0x9/0x10 [ 45.379730 ] __kmalloc+0x150/0x280 [ 45.379984 ] memstick_alloc_host+0x2a/0x190 [ 45.380664 ] [ 45.380781 ] Freed by task 5509: [ 45.381014 ] kasan_set_track+0x3d/0x70 [ 45.381293 ] kasan_set_free_info+0x23/0x40 [ 45.381635 ] ____kasan_slab_free+0x10b/0x140 [ 45.381950 ] __kasan_slab_free+0x11/0x20 [ 45.382241 ] slab_free_freelist_hook+0x81/0x150 [ 45.382575 ] kfree+0x13e/0x290 [ 45.382805 ] memstick_free+0x1c/0x20 [ 45.383070 ] device_release+0x9c/0x1d0 [ 45.383349 ] kobject_put+0x2ef/0x4c0 [ 45.383616 ] put_device+0x1f/0x30 [ 45.383865 ] memstick_free_host+0x24/0x30 [ 45.384162 ] r592_remove+0x242/0x350 [r592] [ 45.384473 ] pci_device_remove+0xa9/0x250
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Link: https://lore.kernel.org/r/1634383581-11055-1-git-send-email-zheyuma97@gmail.... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/host/r592.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index e79a0218c492e..1d35d147552d4 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c @@ -838,15 +838,15 @@ static void r592_remove(struct pci_dev *pdev) } memstick_remove_host(dev->host);
+ if (dev->dummy_dma_page) + dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->dummy_dma_page, + dev->dummy_dma_page_physical_address); + free_irq(dev->irq, dev); iounmap(dev->mmio); pci_release_regions(pdev); pci_disable_device(pdev); memstick_free_host(dev->host); - - if (dev->dummy_dma_page) - dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->dummy_dma_page, - dev->dummy_dma_page_physical_address); }
#ifdef CONFIG_PM_SLEEP
From: Yanfei Xu yanfei.xu@windriver.com
[ Upstream commit 7cdacc5f52d68a9370f182c844b5b3e6cc975cc1 ]
The spinning region rwsem_spin_on_owner() should not be preempted, however the rwsem_down_write_slowpath() invokes it and don't disable preemption. Fix it by adding a pair of preempt_disable/enable().
Signed-off-by: Yanfei Xu yanfei.xu@windriver.com [peterz: Fix CONFIG_RWSEM_SPIN_ON_OWNER=n build] Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Waiman Long longman@redhat.com Link: https://lore.kernel.org/r/20211013134154.1085649-3-yanfei.xu@windriver.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/rwsem.c | 53 ++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 23 deletions(-)
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 000e8d5a28841..29eea50a3e678 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -577,6 +577,24 @@ static inline bool rwsem_try_write_lock(struct rw_semaphore *sem, return true; }
+/* + * The rwsem_spin_on_owner() function returns the following 4 values + * depending on the lock owner state. + * OWNER_NULL : owner is currently NULL + * OWNER_WRITER: when owner changes and is a writer + * OWNER_READER: when owner changes and the new owner may be a reader. + * OWNER_NONSPINNABLE: + * when optimistic spinning has to stop because either the + * owner stops running, is unknown, or its timeslice has + * been used up. + */ +enum owner_state { + OWNER_NULL = 1 << 0, + OWNER_WRITER = 1 << 1, + OWNER_READER = 1 << 2, + OWNER_NONSPINNABLE = 1 << 3, +}; + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER /* * Try to acquire write lock before the writer has been put on wait queue. @@ -632,23 +650,6 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) return ret; }
-/* - * The rwsem_spin_on_owner() function returns the following 4 values - * depending on the lock owner state. - * OWNER_NULL : owner is currently NULL - * OWNER_WRITER: when owner changes and is a writer - * OWNER_READER: when owner changes and the new owner may be a reader. - * OWNER_NONSPINNABLE: - * when optimistic spinning has to stop because either the - * owner stops running, is unknown, or its timeslice has - * been used up. - */ -enum owner_state { - OWNER_NULL = 1 << 0, - OWNER_WRITER = 1 << 1, - OWNER_READER = 1 << 2, - OWNER_NONSPINNABLE = 1 << 3, -}; #define OWNER_SPINNABLE (OWNER_NULL | OWNER_WRITER | OWNER_READER)
static inline enum owner_state @@ -878,12 +879,11 @@ static inline bool rwsem_optimistic_spin(struct rw_semaphore *sem)
static inline void clear_nonspinnable(struct rw_semaphore *sem) { }
-static inline int +static inline enum owner_state rwsem_spin_on_owner(struct rw_semaphore *sem) { - return 0; + return OWNER_NONSPINNABLE; } -#define OWNER_NULL 1 #endif
/* @@ -1095,9 +1095,16 @@ wait: * In this case, we attempt to acquire the lock again * without sleeping. */ - if (wstate == WRITER_HANDOFF && - rwsem_spin_on_owner(sem) == OWNER_NULL) - goto trylock_again; + if (wstate == WRITER_HANDOFF) { + enum owner_state owner_state; + + preempt_disable(); + owner_state = rwsem_spin_on_owner(sem); + preempt_enable(); + + if (owner_state == OWNER_NULL) + goto trylock_again; + }
/* Block until there are no active lockers. */ for (;;) {
From: Lasse Collin lasse.collin@tukaani.org
[ Upstream commit 83d3c4f22a36d005b55f44628f46cc0d319a75e8 ]
With valid files, the safety margin described in lib/decompress_unxz.c ensures that these buffers cannot overlap. But if the uncompressed size of the input is larger than the caller thought, which is possible when the input file is invalid/corrupt, the buffers can overlap. Obviously the result will then be garbage (and usually the decoder will return an error too) but no other harm will happen when such an over-run occurs.
This change only affects uncompressed LZMA2 chunks and so this should have no effect on performance.
Link: https://lore.kernel.org/r/20211010213145.17462-2-xiang@kernel.org Signed-off-by: Lasse Collin lasse.collin@tukaani.org Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- lib/decompress_unxz.c | 2 +- lib/xz/xz_dec_lzma2.c | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c index a2f38e23004aa..f7a3dc13316a3 100644 --- a/lib/decompress_unxz.c +++ b/lib/decompress_unxz.c @@ -167,7 +167,7 @@ * memeq and memzero are not used much and any remotely sane implementation * is fast enough. memcpy/memmove speed matters in multi-call mode, but * the kernel image is decompressed in single-call mode, in which only - * memcpy speed can matter and only if there is a lot of uncompressible data + * memmove speed can matter and only if there is a lot of uncompressible data * (LZMA2 stores uncompressible chunks in uncompressed form). Thus, the * functions below should just be kept small; it's probably not worth * optimizing for speed. diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c index 7a6781e3f47b6..d548cf0e59fe6 100644 --- a/lib/xz/xz_dec_lzma2.c +++ b/lib/xz/xz_dec_lzma2.c @@ -387,7 +387,14 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
*left -= copy_size;
- memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size); + /* + * If doing in-place decompression in single-call mode and the + * uncompressed size of the file is larger than the caller + * thought (i.e. it is invalid input!), the buffers below may + * overlap and cause undefined behavior with memcpy(). + * With valid inputs memcpy() would be fine here. + */ + memmove(dict->buf + dict->pos, b->in + b->in_pos, copy_size); dict->pos += copy_size;
if (dict->full < dict->pos) @@ -397,7 +404,11 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b, if (dict->pos == dict->end) dict->pos = 0;
- memcpy(b->out + b->out_pos, b->in + b->in_pos, + /* + * Like above but for multi-call mode: use memmove() + * to avoid undefined behavior with invalid input. + */ + memmove(b->out + b->out_pos, b->in + b->in_pos, copy_size); }
@@ -421,6 +432,12 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b) if (dict->pos == dict->end) dict->pos = 0;
+ /* + * These buffers cannot overlap even if doing in-place + * decompression because in multi-call mode dict->buf + * has been allocated by us in this file; it's not + * provided by the caller like in single-call mode. + */ memcpy(b->out + b->out_pos, dict->buf + dict->start, copy_size); }
From: Lasse Collin lasse.collin@tukaani.org
[ Upstream commit 4f8d7abaa413c34da9d751289849dbfb7c977d05 ]
This might matter, for example, if the underlying type of enum xz_check was a signed char. In such a case the validation wouldn't have caught an unsupported header. I don't know if this problem can occur in the kernel on any arch but it's still good to fix it because some people might copy the XZ code to their own projects from Linux instead of the upstream XZ Embedded repository.
This change may increase the code size by a few bytes. An alternative would have been to use an unsigned int instead of enum xz_check but using an enumeration looks cleaner.
Link: https://lore.kernel.org/r/20211010213145.17462-3-xiang@kernel.org Signed-off-by: Lasse Collin lasse.collin@tukaani.org Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- lib/xz/xz_dec_stream.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/xz/xz_dec_stream.c b/lib/xz/xz_dec_stream.c index fea86deaaa01d..683570b93a8c4 100644 --- a/lib/xz/xz_dec_stream.c +++ b/lib/xz/xz_dec_stream.c @@ -402,12 +402,12 @@ static enum xz_ret dec_stream_header(struct xz_dec *s) * we will accept other check types too, but then the check won't * be verified and a warning (XZ_UNSUPPORTED_CHECK) will be given. */ + if (s->temp.buf[HEADER_MAGIC_SIZE + 1] > XZ_CHECK_MAX) + return XZ_OPTIONS_ERROR; + s->check_type = s->temp.buf[HEADER_MAGIC_SIZE + 1];
#ifdef XZ_DEC_ANY_CHECK - if (s->check_type > XZ_CHECK_MAX) - return XZ_OPTIONS_ERROR; - if (s->check_type > XZ_CHECK_CRC32) return XZ_UNSUPPORTED_CHECK; #else
From: Menglong Dong imagedong@tencent.com
[ Upstream commit d25302e46592c97d29f70ccb1be558df31a9a360 ]
Some unfriendly component, such as dpdk, write the same mask to unbound kworker cpumask again and again. Every time it write to this interface some work is queue to cpu, even though the mask is same with the original mask.
So, fix it by return success and do nothing if the cpumask is equal with the old one.
Signed-off-by: Mengen Sun mengensun@tencent.com Signed-off-by: Menglong Dong imagedong@tencent.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/workqueue.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 1b3eb1e9531f4..76988f39ed5ac 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -5384,9 +5384,6 @@ int workqueue_set_unbound_cpumask(cpumask_var_t cpumask) int ret = -EINVAL; cpumask_var_t saved_cpumask;
- if (!zalloc_cpumask_var(&saved_cpumask, GFP_KERNEL)) - return -ENOMEM; - /* * Not excluding isolated cpus on purpose. * If the user wishes to include them, we allow that. @@ -5394,6 +5391,15 @@ int workqueue_set_unbound_cpumask(cpumask_var_t cpumask) cpumask_and(cpumask, cpumask, cpu_possible_mask); if (!cpumask_empty(cpumask)) { apply_wqattrs_lock(); + if (cpumask_equal(cpumask, wq_unbound_cpumask)) { + ret = 0; + goto out_unlock; + } + + if (!zalloc_cpumask_var(&saved_cpumask, GFP_KERNEL)) { + ret = -ENOMEM; + goto out_unlock; + }
/* save the old wq_unbound_cpumask. */ cpumask_copy(saved_cpumask, wq_unbound_cpumask); @@ -5406,10 +5412,11 @@ int workqueue_set_unbound_cpumask(cpumask_var_t cpumask) if (ret < 0) cpumask_copy(wq_unbound_cpumask, saved_cpumask);
+ free_cpumask_var(saved_cpumask); +out_unlock: apply_wqattrs_unlock(); }
- free_cpumask_var(saved_cpumask); return ret; }
From: Kalesh Singh kaleshsingh@google.com
[ Upstream commit 7ce1bb83a14019f8c396d57ec704d19478747716 ]
If CONFIG_CFI_CLANG=y, attempting to read an event histogram will cause the kernel to panic due to failed CFI check.
1. echo 'hist:keys=common_pid' >> events/sched/sched_switch/trigger 2. cat events/sched/sched_switch/hist 3. kernel panics on attempting to read hist
This happens because the sort() function expects a generic int (*)(const void *, const void *) pointer for the compare function. To prevent this CFI failure, change tracing map cmp_entries_* function signatures to match this.
Also, fix the build error reported by the kernel test robot [1].
[1] https://lore.kernel.org/r/202110141140.zzi4dRh4-lkp@intel.com/
Link: https://lkml.kernel.org/r/20211014045217.3265162-1-kaleshsingh@google.com
Signed-off-by: Kalesh Singh kaleshsingh@google.com Reported-by: kernel test robot lkp@intel.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/tracing_map.c | 40 ++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c index d6bddb157ef20..39bb56d2dcbef 100644 --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c @@ -834,29 +834,35 @@ int tracing_map_init(struct tracing_map *map) return err; }
-static int cmp_entries_dup(const struct tracing_map_sort_entry **a, - const struct tracing_map_sort_entry **b) +static int cmp_entries_dup(const void *A, const void *B) { + const struct tracing_map_sort_entry *a, *b; int ret = 0;
- if (memcmp((*a)->key, (*b)->key, (*a)->elt->map->key_size)) + a = *(const struct tracing_map_sort_entry **)A; + b = *(const struct tracing_map_sort_entry **)B; + + if (memcmp(a->key, b->key, a->elt->map->key_size)) ret = 1;
return ret; }
-static int cmp_entries_sum(const struct tracing_map_sort_entry **a, - const struct tracing_map_sort_entry **b) +static int cmp_entries_sum(const void *A, const void *B) { const struct tracing_map_elt *elt_a, *elt_b; + const struct tracing_map_sort_entry *a, *b; struct tracing_map_sort_key *sort_key; struct tracing_map_field *field; tracing_map_cmp_fn_t cmp_fn; void *val_a, *val_b; int ret = 0;
- elt_a = (*a)->elt; - elt_b = (*b)->elt; + a = *(const struct tracing_map_sort_entry **)A; + b = *(const struct tracing_map_sort_entry **)B; + + elt_a = a->elt; + elt_b = b->elt;
sort_key = &elt_a->map->sort_key;
@@ -873,18 +879,21 @@ static int cmp_entries_sum(const struct tracing_map_sort_entry **a, return ret; }
-static int cmp_entries_key(const struct tracing_map_sort_entry **a, - const struct tracing_map_sort_entry **b) +static int cmp_entries_key(const void *A, const void *B) { const struct tracing_map_elt *elt_a, *elt_b; + const struct tracing_map_sort_entry *a, *b; struct tracing_map_sort_key *sort_key; struct tracing_map_field *field; tracing_map_cmp_fn_t cmp_fn; void *val_a, *val_b; int ret = 0;
- elt_a = (*a)->elt; - elt_b = (*b)->elt; + a = *(const struct tracing_map_sort_entry **)A; + b = *(const struct tracing_map_sort_entry **)B; + + elt_a = a->elt; + elt_b = b->elt;
sort_key = &elt_a->map->sort_key;
@@ -989,10 +998,8 @@ static void sort_secondary(struct tracing_map *map, struct tracing_map_sort_key *primary_key, struct tracing_map_sort_key *secondary_key) { - int (*primary_fn)(const struct tracing_map_sort_entry **, - const struct tracing_map_sort_entry **); - int (*secondary_fn)(const struct tracing_map_sort_entry **, - const struct tracing_map_sort_entry **); + int (*primary_fn)(const void *, const void *); + int (*secondary_fn)(const void *, const void *); unsigned i, start = 0, n_sub = 1;
if (is_key(map, primary_key->field_idx)) @@ -1061,8 +1068,7 @@ int tracing_map_sort_entries(struct tracing_map *map, unsigned int n_sort_keys, struct tracing_map_sort_entry ***sort_entries) { - int (*cmp_entries_fn)(const struct tracing_map_sort_entry **, - const struct tracing_map_sort_entry **); + int (*cmp_entries_fn)(const void *, const void *); struct tracing_map_sort_entry *sort_entry, **entries; int i, n_entries, ret;
From: Ryder Lee ryder.lee@mediatek.com
[ Upstream commit d45dac0732a287fc371a23f257cce04e65627947 ]
The bounds check on datalen is off-by-one, so fix it.
Signed-off-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 43960770a9af2..2f30047bd80f2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -925,7 +925,7 @@ static void mt7915_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
elem = ieee80211_bss_get_elem(bss, WLAN_EID_EXT_CAPABILITY);
- if (!elem || elem->datalen < 10 || + if (!elem || elem->datalen <= 10 || !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) data->tolerated = false;
From: Zheyu Ma zheyuma97@gmail.com
[ Upstream commit 257051a235c17e33782b6e24a4b17f2d7915aaec ]
When the driver fails to request the firmware, it calls its error handler. In the error handler, the driver detaches device from driver first before releasing the firmware, which can cause a use-after-free bug.
Fix this by releasing firmware first.
The following log reveals it:
[ 9.007301 ] BUG: KASAN: use-after-free in mwl8k_fw_state_machine+0x320/0xba0 [ 9.010143 ] Workqueue: events request_firmware_work_func [ 9.010830 ] Call Trace: [ 9.010830 ] dump_stack_lvl+0xa8/0xd1 [ 9.010830 ] print_address_description+0x87/0x3b0 [ 9.010830 ] kasan_report+0x172/0x1c0 [ 9.010830 ] ? mutex_unlock+0xd/0x10 [ 9.010830 ] ? mwl8k_fw_state_machine+0x320/0xba0 [ 9.010830 ] ? mwl8k_fw_state_machine+0x320/0xba0 [ 9.010830 ] __asan_report_load8_noabort+0x14/0x20 [ 9.010830 ] mwl8k_fw_state_machine+0x320/0xba0 [ 9.010830 ] ? mwl8k_load_firmware+0x5f0/0x5f0 [ 9.010830 ] request_firmware_work_func+0x172/0x250 [ 9.010830 ] ? read_lock_is_recursive+0x20/0x20 [ 9.010830 ] ? process_one_work+0x7a1/0x1100 [ 9.010830 ] ? request_firmware_nowait+0x460/0x460 [ 9.010830 ] ? __this_cpu_preempt_check+0x13/0x20 [ 9.010830 ] process_one_work+0x9bb/0x1100
Signed-off-by: Zheyu Ma zheyuma97@gmail.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1634356979-6211-1-git-send-email-zheyuma97@gmail.c... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwl8k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index 3bf6571f41490..529e325498cdb 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -5800,8 +5800,8 @@ static void mwl8k_fw_state_machine(const struct firmware *fw, void *context) fail: priv->fw_state = FW_STATE_ERROR; complete(&priv->firmware_loading_complete); - device_release_driver(&priv->pdev->dev); mwl8k_release_firmware(priv); + device_release_driver(&priv->pdev->dev); }
#define MAX_RESTART_ATTEMPTS 1
From: Yaara Baruch yaara.baruch@intel.com
[ Upstream commit 70382b0897eeecfcd35ba5f6161dbceeb556ea1e ]
JnP should not have the 160 MHz.
Signed-off-by: Yaara Baruch yaara.baruch@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/iwlwifi.20211016114029.ee163f4a7513.I7f87bd969a0b0... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c index e3996ff99bad5..3b974388d834d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -931,9 +931,9 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_b0_hr1_b0, iwl_ax101_name), _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, - IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, + IWL_CFG_MAC_TYPE_QU, SILICON_B_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_b0_hr_b0, iwl_ax203_name),
/* Qu C step */ @@ -945,7 +945,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_MAC_TYPE_QU, SILICON_C_STEP, IWL_CFG_RF_TYPE_HR2, IWL_CFG_ANY, - IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, + IWL_CFG_NO_160, IWL_CFG_ANY, IWL_CFG_NO_CDB, iwl_qu_c0_hr_b0, iwl_ax203_name),
/* QuZ */
From: Jens Axboe axboe@kernel.dk
[ Upstream commit 037057a5a979c7eeb2ee5d12cf4c24b805192c75 ]
This check is meant to catch cases where a requeue is attempted on a request that is still inserted. It's never really been useful to catch any misuse, and now it's actively wrong. Outside of that, this should not be a BUG_ON() to begin with.
Remove the check as it's now causing active harm, as requeue off the plug path will trigger it even though the request state is just fine.
Reported-by: Yi Zhang yi.zhang@redhat.com Link: https://lore.kernel.org/linux-block/CAHj4cs80zAUc2grnCZ015-2Rvd-=gXRfB_dFKy=... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-mq.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c index 49587c181e3fd..c8a9d10f7c18b 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -763,7 +763,6 @@ void blk_mq_requeue_request(struct request *rq, bool kick_requeue_list) /* this request will be re-inserted to io scheduler queue */ blk_mq_sched_requeue_request(rq);
- BUG_ON(!list_empty(&rq->queuelist)); blk_mq_add_to_requeue_list(rq, true, kick_requeue_list); } EXPORT_SYMBOL(blk_mq_requeue_request);
From: Michael Tretter m.tretter@pengutronix.de
[ Upstream commit 1ecda6393db4be44aba27a243e648dc98c9b92e3 ]
The mailbox is initialized after the interrupt handler is installed. As the firmware is loaded and started even later, it should not happen that the interrupt occurs without the mailbox being initialized.
As the Linux Driver Verification project (linuxtesting.org) keeps reporting this as an error, add a check to ignore interrupts before the mailbox is initialized to fix this potential null pointer dereference.
Reported-by: Yuri Savinykh s02190703@gse.cs.msu.ru Reported-by: Nadezda Lutovinova lutovinova@ispras.ru Signed-off-by: Michael Tretter m.tretter@pengutronix.de Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/allegro-dvt/allegro-core.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c index 887b492e4ad1c..14a119b43bca0 100644 --- a/drivers/media/platform/allegro-dvt/allegro-core.c +++ b/drivers/media/platform/allegro-dvt/allegro-core.c @@ -2185,6 +2185,15 @@ static irqreturn_t allegro_irq_thread(int irq, void *data) { struct allegro_dev *dev = data;
+ /* + * The firmware is initialized after the mailbox is setup. We further + * check the AL5_ITC_CPU_IRQ_STA register, if the firmware actually + * triggered the interrupt. Although this should not happen, make sure + * that we ignore interrupts, if the mailbox is not initialized. + */ + if (!dev->mbox_status) + return IRQ_NONE; + allegro_mbox_notify(dev->mbox_status);
return IRQ_HANDLED;
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 68e3871dcd6e547f6c47454492bc452356cb9eac ]
When selecting between levels in the force performance levels interface sclk (gfxclk) was not set correctly for all levels. Select the proper sclk settings for all levels.
Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1726 Reviewed-by: Evan Quan evan.quan@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c | 89 ++++++------------- 1 file changed, 29 insertions(+), 60 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index f6ef0ce6e9e2c..a9dceef4a7011 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -1386,52 +1386,38 @@ static int vangogh_set_performance_level(struct smu_context *smu, uint32_t soc_mask, mclk_mask, fclk_mask; uint32_t vclk_mask = 0, dclk_mask = 0;
+ smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; + smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; + switch (level) { case AMD_DPM_FORCED_LEVEL_HIGH: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; + smu->gfx_actual_hard_min_freq = smu->gfx_default_soft_max_freq; smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq;
ret = vangogh_force_dpm_limit_value(smu, true); + if (ret) + return ret; break; case AMD_DPM_FORCED_LEVEL_LOW: smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - - smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; + smu->gfx_actual_soft_max_freq = smu->gfx_default_hard_min_freq;
ret = vangogh_force_dpm_limit_value(smu, false); + if (ret) + return ret; break; case AMD_DPM_FORCED_LEVEL_AUTO: smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; - ret = vangogh_unforce_dpm_levels(smu); - break; - case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - - smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; - - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_SetHardMinGfxClk, - VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL); - if (ret) - return ret; - - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_SetSoftMaxGfxClk, - VANGOGH_UMD_PSTATE_STANDARD_GFXCLK, NULL); if (ret) return ret; + break; + case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD: + smu->gfx_actual_hard_min_freq = VANGOGH_UMD_PSTATE_STANDARD_GFXCLK; + smu->gfx_actual_soft_max_freq = VANGOGH_UMD_PSTATE_STANDARD_GFXCLK;
ret = vangogh_get_profiling_clk_mask(smu, level, &vclk_mask, @@ -1446,32 +1432,15 @@ static int vangogh_set_performance_level(struct smu_context *smu, vangogh_force_clk_levels(smu, SMU_SOCCLK, 1 << soc_mask); vangogh_force_clk_levels(smu, SMU_VCLK, 1 << vclk_mask); vangogh_force_clk_levels(smu, SMU_DCLK, 1 << dclk_mask); - break; case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK: smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - - smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; - - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinVcn, - VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL); - if (ret) - return ret; - - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxVcn, - VANGOGH_UMD_PSTATE_PEAK_DCLK, NULL); - if (ret) - return ret; + smu->gfx_actual_soft_max_freq = smu->gfx_default_hard_min_freq; break; case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK: smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
- smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; - ret = vangogh_get_profiling_clk_mask(smu, level, NULL, NULL, @@ -1484,29 +1453,29 @@ static int vangogh_set_performance_level(struct smu_context *smu, vangogh_force_clk_levels(smu, SMU_FCLK, 1 << fclk_mask); break; case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK: - smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq; - smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq; - - smu->cpu_actual_soft_min_freq = smu->cpu_default_soft_min_freq; - smu->cpu_actual_soft_max_freq = smu->cpu_default_soft_max_freq; - - ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, - VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL); - if (ret) - return ret; + smu->gfx_actual_hard_min_freq = VANGOGH_UMD_PSTATE_PEAK_GFXCLK; + smu->gfx_actual_soft_max_freq = VANGOGH_UMD_PSTATE_PEAK_GFXCLK;
- ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, - VANGOGH_UMD_PSTATE_PEAK_GFXCLK, NULL); + ret = vangogh_set_peak_clock_by_device(smu); if (ret) return ret; - - ret = vangogh_set_peak_clock_by_device(smu); break; case AMD_DPM_FORCED_LEVEL_MANUAL: case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT: default: - break; + return 0; } + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk, + smu->gfx_actual_hard_min_freq, NULL); + if (ret) + return ret; + + ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk, + smu->gfx_actual_soft_max_freq, NULL); + if (ret) + return ret; + return ret; }
From: Israel Rukshin israelr@nvidia.com
[ Upstream commit e3e19dcc4c416d65f99f13d55be2b787f8d0050e ]
When a port is removed through configfs, any connected controllers are starting teardown flow asynchronously and can still send commands. This causes a use-after-free bug for any command that dereferences req->port (like in nvmet_parse_io_cmd).
To fix this, wait for all the teardown scheduled works to complete (like release_work at rdma/tcp drivers). This ensures there are no active controllers when the port is eventually removed.
Signed-off-by: Israel Rukshin israelr@nvidia.com Reviewed-by: Max Gurtovoy mgurtovoy@nvidia.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/configfs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index be5d82421e3a4..496d775c67707 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -1553,6 +1553,8 @@ static void nvmet_port_release(struct config_item *item) { struct nvmet_port *port = to_nvmet_port(item);
+ /* Let inflight controllers teardown complete */ + flush_scheduled_work(); list_del(&port->global_entry);
kfree(port->ana_state);
From: Israel Rukshin israelr@nvidia.com
[ Upstream commit fcf73a804c7d6bbf0ea63531c6122aa363852e04 ]
When removing a port, all its controllers are being removed, but there are queues on the port that doesn't belong to any controller (during connection time). This causes a use-after-free bug for any command that dereferences req->port (like in nvmet_alloc_ctrl). Those queues should be destroyed before freeing the port via configfs. Destroy the remaining queues after the RDMA-CM was destroyed guarantees that no new queue will be created.
Signed-off-by: Israel Rukshin israelr@nvidia.com Reviewed-by: Max Gurtovoy mgurtovoy@nvidia.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/rdma.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index 891174ccd44bb..f1eedbf493d5b 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -1818,12 +1818,36 @@ restart: mutex_unlock(&nvmet_rdma_queue_mutex); }
+static void nvmet_rdma_destroy_port_queues(struct nvmet_rdma_port *port) +{ + struct nvmet_rdma_queue *queue, *tmp; + struct nvmet_port *nport = port->nport; + + mutex_lock(&nvmet_rdma_queue_mutex); + list_for_each_entry_safe(queue, tmp, &nvmet_rdma_queue_list, + queue_list) { + if (queue->port != nport) + continue; + + list_del_init(&queue->queue_list); + __nvmet_rdma_queue_disconnect(queue); + } + mutex_unlock(&nvmet_rdma_queue_mutex); +} + static void nvmet_rdma_disable_port(struct nvmet_rdma_port *port) { struct rdma_cm_id *cm_id = xchg(&port->cm_id, NULL);
if (cm_id) rdma_destroy_id(cm_id); + + /* + * Destroy the remaining queues, which are not belong to any + * controller yet. Do it here after the RDMA-CM was destroyed + * guarantees that no new queue will be created. + */ + nvmet_rdma_destroy_port_queues(port); }
static int nvmet_rdma_enable_port(struct nvmet_rdma_port *port)
From: Israel Rukshin israelr@nvidia.com
[ Upstream commit 2351ead99ce9164fb42555aee3f96af84c4839e9 ]
When removing a port, all its controllers are being removed, but there are queues on the port that doesn't belong to any controller (during connection time). This causes a use-after-free bug for any command that dereferences req->port (like in nvmet_alloc_ctrl). Those queues should be destroyed before freeing the port via configfs. Destroy the remaining queues after the accept_work was cancelled guarantees that no new queue will be created.
Signed-off-by: Israel Rukshin israelr@nvidia.com Reviewed-by: Max Gurtovoy mgurtovoy@nvidia.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/tcp.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 46c3b3be7e033..84c387e4bf431 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1740,6 +1740,17 @@ err_port: return ret; }
+static void nvmet_tcp_destroy_port_queues(struct nvmet_tcp_port *port) +{ + struct nvmet_tcp_queue *queue; + + mutex_lock(&nvmet_tcp_queue_mutex); + list_for_each_entry(queue, &nvmet_tcp_queue_list, queue_list) + if (queue->port == port) + kernel_sock_shutdown(queue->sock, SHUT_RDWR); + mutex_unlock(&nvmet_tcp_queue_mutex); +} + static void nvmet_tcp_remove_port(struct nvmet_port *nport) { struct nvmet_tcp_port *port = nport->priv; @@ -1749,6 +1760,11 @@ static void nvmet_tcp_remove_port(struct nvmet_port *nport) port->sock->sk->sk_user_data = NULL; write_unlock_bh(&port->sock->sk->sk_callback_lock); cancel_work_sync(&port->accept_work); + /* + * Destroy the remaining queues, which are not belong to any + * controller yet. + */ + nvmet_tcp_destroy_port_queues(port);
sock_release(port->sock); kfree(port);
From: Hannes Reinecke hare@suse.de
[ Upstream commit 2b81a5f015199f3d585ce710190a9e87714d3c1e ]
When reading the partition table on initial scan hits an I/O error the I/O will hang with the scan_mutex held:
[<0>] do_read_cache_page+0x49b/0x790 [<0>] read_part_sector+0x39/0xe0 [<0>] read_lba+0xf9/0x1d0 [<0>] efi_partition+0xf1/0x7f0 [<0>] bdev_disk_changed+0x1ee/0x550 [<0>] blkdev_get_whole+0x81/0x90 [<0>] blkdev_get_by_dev+0x128/0x2e0 [<0>] device_add_disk+0x377/0x3c0 [<0>] nvme_mpath_set_live+0x130/0x1b0 [nvme_core] [<0>] nvme_mpath_add_disk+0x150/0x160 [nvme_core] [<0>] nvme_alloc_ns+0x417/0x950 [nvme_core] [<0>] nvme_validate_or_alloc_ns+0xe9/0x1e0 [nvme_core] [<0>] nvme_scan_work+0x168/0x310 [nvme_core] [<0>] process_one_work+0x231/0x420
and trying to delete the controller will deadlock as it tries to grab the scan mutex:
[<0>] nvme_mpath_clear_ctrl_paths+0x25/0x80 [nvme_core] [<0>] nvme_remove_namespaces+0x31/0xf0 [nvme_core] [<0>] nvme_do_delete_ctrl+0x4b/0x80 [nvme_core]
As we're now properly ordering the namespace list there is no need to hold the scan_mutex in nvme_mpath_clear_ctrl_paths() anymore. And we always need to kick the requeue list as the path will be marked as unusable and I/O will be requeued _without_ a current path.
Signed-off-by: Hannes Reinecke hare@suse.de Reviewed-by: Keith Busch kbusch@kernel.org Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/multipath.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index fba06618c6c23..2f76969408b27 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -138,13 +138,12 @@ void nvme_mpath_clear_ctrl_paths(struct nvme_ctrl *ctrl) { struct nvme_ns *ns;
- mutex_lock(&ctrl->scan_lock); down_read(&ctrl->namespaces_rwsem); - list_for_each_entry(ns, &ctrl->namespaces, list) - if (nvme_mpath_clear_current_path(ns)) - kblockd_schedule_work(&ns->head->requeue_work); + list_for_each_entry(ns, &ctrl->namespaces, list) { + nvme_mpath_clear_current_path(ns); + kblockd_schedule_work(&ns->head->requeue_work); + } up_read(&ctrl->namespaces_rwsem); - mutex_unlock(&ctrl->scan_lock); }
void nvme_mpath_revalidate_paths(struct nvme_ns *ns)
From: David Yang davidcomponentone@gmail.com
[ Upstream commit b599015f044df53e93ad0a2957b615bc1a26bf73 ]
The coccinelle check report: "./samples/bpf/xdp_redirect_cpu_user.c:397:32-38: ERROR: application of sizeof to pointer" Using the "strlen" to fix it.
Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: David Yang davidcomponentone@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20211012111649.983253-1-davidcomponentone@gmail.... Signed-off-by: Sasha Levin sashal@kernel.org --- samples/bpf/xdp_redirect_cpu_user.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 6e25fba64c72b..d84e6949007cc 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -325,7 +325,6 @@ int main(int argc, char **argv) int add_cpu = -1; int ifindex = -1; int *cpu, i, opt; - char *ifname; __u32 qsize; int n_cpus;
@@ -393,9 +392,8 @@ int main(int argc, char **argv) fprintf(stderr, "-d/--dev name too long\n"); goto end_cpu; } - ifname = (char *)&ifname_buf; - safe_strncpy(ifname, optarg, sizeof(ifname)); - ifindex = if_nametoindex(ifname); + safe_strncpy(ifname_buf, optarg, strlen(ifname_buf)); + ifindex = if_nametoindex(ifname_buf); if (!ifindex) ifindex = strtoul(optarg, NULL, 0); if (!ifindex) {
From: Nick Desaulniers ndesaulniers@google.com
[ Upstream commit 14831fad73f5ac30ac61760487d95a538e6ab3cb ]
When running the following command without arm-linux-gnueabi-gcc in one's $PATH, the following warning is observed:
$ ARCH=arm64 CROSS_COMPILE_COMPAT=arm-linux-gnueabi- make -j72 LLVM=1 mrproper make[1]: arm-linux-gnueabi-gcc: No such file or directory
This is because KCONFIG is not run for mrproper, so CONFIG_CC_IS_CLANG is not set, and we end up eagerly evaluating various variables that try to invoke CC_COMPAT.
This is a similar problem to what was observed in commit dc960bfeedb0 ("h8300: suppress error messages for 'make clean'")
Reported-by: Lucas Henneman henneman@google.com Suggested-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Nick Desaulniers ndesaulniers@google.com Reviewed-by: Vincenzo Frascino vincenzo.frascino@arm.com Reviewed-by: Nathan Chancellor nathan@kernel.org Tested-by: Nathan Chancellor nathan@kernel.org Link: https://lore.kernel.org/r/20211019223646.1146945-4-ndesaulniers@google.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/vdso32/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile index 3dba0c4f8f42b..764d1900d5aab 100644 --- a/arch/arm64/kernel/vdso32/Makefile +++ b/arch/arm64/kernel/vdso32/Makefile @@ -40,7 +40,8 @@ cc32-as-instr = $(call try-run,\ # As a result we set our own flags here.
# KBUILD_CPPFLAGS and NOSTDINC_FLAGS from top-level Makefile -VDSO_CPPFLAGS := -DBUILD_VDSO -D__KERNEL__ -nostdinc -isystem $(shell $(CC_COMPAT) -print-file-name=include) +VDSO_CPPFLAGS := -DBUILD_VDSO -D__KERNEL__ -nostdinc +VDSO_CPPFLAGS += -isystem $(shell $(CC_COMPAT) -print-file-name=include 2>/dev/null) VDSO_CPPFLAGS += $(LINUXINCLUDE)
# Common C and assembly flags
From: Ye Bin yebin10@huawei.com
[ Upstream commit 39fbef4b0f77f9c89c8f014749ca533643a37c9f ]
The following kernel crash can be triggered:
[ 89.266592] ------------[ cut here ]------------ [ 89.267427] kernel BUG at fs/buffer.c:3020! [ 89.268264] invalid opcode: 0000 [#1] SMP KASAN PTI [ 89.269116] CPU: 7 PID: 1750 Comm: kmmpd-loop0 Not tainted 5.10.0-862.14.0.6.x86_64-08610-gc932cda3cef4-dirty #20 [ 89.273169] RIP: 0010:submit_bh_wbc.isra.0+0x538/0x6d0 [ 89.277157] RSP: 0018:ffff888105ddfd08 EFLAGS: 00010246 [ 89.278093] RAX: 0000000000000005 RBX: ffff888124231498 RCX: ffffffffb2772612 [ 89.279332] RDX: 1ffff11024846293 RSI: 0000000000000008 RDI: ffff888124231498 [ 89.280591] RBP: ffff8881248cc000 R08: 0000000000000001 R09: ffffed1024846294 [ 89.281851] R10: ffff88812423149f R11: ffffed1024846293 R12: 0000000000003800 [ 89.283095] R13: 0000000000000001 R14: 0000000000000000 R15: ffff8881161f7000 [ 89.284342] FS: 0000000000000000(0000) GS:ffff88839b5c0000(0000) knlGS:0000000000000000 [ 89.285711] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 89.286701] CR2: 00007f166ebc01a0 CR3: 0000000435c0e000 CR4: 00000000000006e0 [ 89.287919] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 89.289138] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 89.290368] Call Trace: [ 89.290842] write_mmp_block+0x2ca/0x510 [ 89.292218] kmmpd+0x433/0x9a0 [ 89.294902] kthread+0x2dd/0x3e0 [ 89.296268] ret_from_fork+0x22/0x30 [ 89.296906] Modules linked in:
by running the following commands:
1. mkfs.ext4 -O mmp /dev/sda -b 1024 2. mount /dev/sda /home/test 3. echo "/dev/sda" > /sys/power/resume
That happens because swsusp_check() calls set_blocksize() on the target partition which confuses the file system:
Thread1 Thread2 mount /dev/sda /home/test get s_mmp_bh --> has mapped flag start kmmpd thread echo "/dev/sda" > /sys/power/resume resume_store software_resume swsusp_check set_blocksize truncate_inode_pages_range truncate_cleanup_page block_invalidatepage discard_buffer --> clean mapped flag write_mmp_block submit_bh submit_bh_wbc BUG_ON(!buffer_mapped(bh))
To address this issue, modify swsusp_check() to open the target block device with exclusive access.
Signed-off-by: Ye Bin yebin10@huawei.com [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/power/swap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 3cb89baebc796..0aabc94125d6b 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -1521,9 +1521,10 @@ end: int swsusp_check(void) { int error; + void *holder;
hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device, - FMODE_READ, NULL); + FMODE_READ | FMODE_EXCL, &holder); if (!IS_ERR(hib_resume_bdev)) { set_blocksize(hib_resume_bdev, PAGE_SIZE); clear_page(swsusp_header); @@ -1545,7 +1546,7 @@ int swsusp_check(void)
put: if (error) - blkdev_put(hib_resume_bdev, FMODE_READ); + blkdev_put(hib_resume_bdev, FMODE_READ | FMODE_EXCL); else pr_debug("Image signature found, resuming\n"); } else {
From: Shuah Khan skhan@linuxfoundation.org
[ Upstream commit c3867ab5924b7a9a0b4a117902a08669d8be7c21 ]
get_warnings_count() does fclose() using File * returned from popen(). Fix it to call pclose() as it should.
tools/testing/selftests/kvm/x86_64/mmio_warning_test x86_64/mmio_warning_test.c: In function ‘get_warnings_count’: x86_64/mmio_warning_test.c:87:9: warning: ‘fclose’ called on pointer returned from a mismatched allocation function [-Wmismatched-dealloc] 87 | fclose(f); | ^~~~~~~~~ x86_64/mmio_warning_test.c:84:13: note: returned from ‘popen’ 84 | f = popen("dmesg | grep "WARNING:" | wc -l", "r"); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Shuah Khan skhan@linuxfoundation.org Acked-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/kvm/x86_64/mmio_warning_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c index 8039e1eff9388..9f55ccd169a13 100644 --- a/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c +++ b/tools/testing/selftests/kvm/x86_64/mmio_warning_test.c @@ -84,7 +84,7 @@ int get_warnings_count(void) f = popen("dmesg | grep "WARNING:" | wc -l", "r"); if (fscanf(f, "%d", &warnings) < 1) warnings = 0; - fclose(f); + pclose(f);
return warnings; }
From: Jiri Olsa jolsa@redhat.com
[ Upstream commit d4121376ac7a9c81a696d7558789b2f29ef3574e ]
The perf_buffer fails on system with offline cpus:
# test_progs -t perf_buffer test_perf_buffer:PASS:nr_cpus 0 nsec test_perf_buffer:PASS:nr_on_cpus 0 nsec test_perf_buffer:PASS:skel_load 0 nsec test_perf_buffer:PASS:attach_kprobe 0 nsec test_perf_buffer:PASS:perf_buf__new 0 nsec test_perf_buffer:PASS:epoll_fd 0 nsec skipping offline CPU #24 skipping offline CPU #25 skipping offline CPU #26 skipping offline CPU #27 skipping offline CPU #28 skipping offline CPU #29 skipping offline CPU #30 skipping offline CPU #31 test_perf_buffer:PASS:perf_buffer__poll 0 nsec test_perf_buffer:PASS:seen_cpu_cnt 0 nsec test_perf_buffer:FAIL:buf_cnt got 24, expected 32 Summary: 0/0 PASSED, 0 SKIPPED, 1 FAILED
Changing the test to check online cpus instead of possible.
Signed-off-by: Jiri Olsa jolsa@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/bpf/20211021114132.8196-2-jolsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/perf_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/perf_buffer.c b/tools/testing/selftests/bpf/prog_tests/perf_buffer.c index 6490e9673002f..7daaaab13681b 100644 --- a/tools/testing/selftests/bpf/prog_tests/perf_buffer.c +++ b/tools/testing/selftests/bpf/prog_tests/perf_buffer.c @@ -107,8 +107,8 @@ void test_perf_buffer(void) "expect %d, seen %d\n", nr_on_cpus, CPU_COUNT(&cpu_seen))) goto out_free_pb;
- if (CHECK(perf_buffer__buffer_cnt(pb) != nr_cpus, "buf_cnt", - "got %zu, expected %d\n", perf_buffer__buffer_cnt(pb), nr_cpus)) + if (CHECK(perf_buffer__buffer_cnt(pb) != nr_on_cpus, "buf_cnt", + "got %zu, expected %d\n", perf_buffer__buffer_cnt(pb), nr_on_cpus)) goto out_close;
for (i = 0; i < nr_cpus; i++) {
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit e5322b9ab5f63536c41301150b7ce64605ce52cc ]
Just like we have default SMPS mode as dynamic in powersave, we should not enable RX-diversity in powersave, to reduce power consumption when connected to a non-MIMO AP.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Link: https://lore.kernel.org/r/iwlwifi.20211017113927.fc896bc5cdaa.I1d11da71b8a5c... Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index 4a3d2971a98b7..ec8a223f90e85 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -405,6 +405,9 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm,
lockdep_assert_held(&mvm->mutex);
+ if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) + return false; + if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1) return false;
From: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp
[ Upstream commit f91488ee15bd3cac467e2d6a361fc2d34d1052ae ]
syzbot is reporting kernel panic at smk_cipso_doi() due to memory allocation fault injection [1]. The reason for need to use panic() was not explained. But since no fix was proposed for 18 months, for now let's use __GFP_NOFAIL for utilizing syzbot resource on other bugs.
Link: https://syzkaller.appspot.com/bug?extid=89731ccb6fec15ce1c22 [1] Reported-by: syzbot syzbot+89731ccb6fec15ce1c22@syzkaller.appspotmail.com Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smackfs.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 9d853c0e55b84..89989d28ffc55 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -693,9 +693,7 @@ static void smk_cipso_doi(void) printk(KERN_WARNING "%s:%d remove rc = %d\n", __func__, __LINE__, rc);
- doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL); - if (doip == NULL) - panic("smack: Failed to initialize cipso DOI.\n"); + doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL | __GFP_NOFAIL); doip->map.std = NULL; doip->doi = smk_cipso_doi_value; doip->type = CIPSO_V4_MAP_PASS;
From: Masami Hiramatsu mhiramat@kernel.org
[ Upstream commit b3ea5d56f212ad81328c82454829a736197ebccc ]
Currently the stacktrace on clang compiled arm kernel uses the 'lr' register to find the first frame address from pt_regs. However, that is wrong after calling another function, because the 'lr' register is used by 'bl' instruction and never be recovered.
As same as gcc arm kernel, directly use the frame pointer (r11) of the pt_regs to find the first frame address.
Note that this fixes kretprobe stacktrace issue only with CONFIG_UNWINDER_FRAME_POINTER=y. For the CONFIG_UNWINDER_ARM, we need another fix.
Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/kernel/stacktrace.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 76ea4178a55cb..db798eac74315 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c @@ -54,8 +54,7 @@ int notrace unwind_frame(struct stackframe *frame)
frame->sp = frame->fp; frame->fp = *(unsigned long *)(fp); - frame->pc = frame->lr; - frame->lr = *(unsigned long *)(fp + 4); + frame->pc = *(unsigned long *)(fp + 4); #else /* check current frame pointer is within bounds */ if (fp < low + 12 || fp > high - 4)
From: Stephen Suryaputra ssuryaextr@gmail.com
[ Upstream commit 61e18ce7348bfefb5688a8bcd4b4d6b37c0f9b2a ]
When addr_gen_mode is set to IN6_ADDR_GEN_MODE_NONE, the link-local addr should not be generated. But it isn't the case for GRE (as well as GRE6) and SIT tunnels. Make it so that tunnels consider the addr_gen_mode, especially for IN6_ADDR_GEN_MODE_NONE.
Do this in add_v4_addrs() to cover both GRE and SIT only if the addr scope is link.
Signed-off-by: Stephen Suryaputra ssuryaextr@gmail.com Acked-by: Antonio Quartulli a@unstable.cc Link: https://lore.kernel.org/r/20211020200618.467342-1-ssuryaextr@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv6/addrconf.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c6a90b7bbb70e..846037e73723f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3110,6 +3110,9 @@ static void add_v4_addrs(struct inet6_dev *idev) memcpy(&addr.s6_addr32[3], idev->dev->dev_addr + offset, 4);
if (idev->dev->flags&IFF_POINTOPOINT) { + if (idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_NONE) + return; + addr.s6_addr32[0] = htonl(0xfe800000); scope = IFA_LINK; plen = 64;
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 49753a75b9a32de4c0393bb8d1e51ea223fda8e4 ]
Looking at the code, the GSWIP switch appears to hold bridging service structures (VLANs, FDBs, forwarding rules) in PCE table entries. Hardware access to the PCE table is non-atomic, and is comprised of several register reads and writes.
These accesses are currently serialized by the rtnl_lock, but DSA is changing its driver API and that lock will no longer be held when calling ->port_fdb_add() and ->port_fdb_del().
So this driver needs to serialize the access to the PCE table using its own locking scheme. This patch adds that.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Hauke Mehrtens hauke@hauke-m.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/lantiq_gswip.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index dbd4486a173ff..1a96df70d1e85 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -276,6 +276,7 @@ struct gswip_priv { int num_gphy_fw; struct gswip_gphy_fw *gphy_fw; u32 port_vlan_filter; + struct mutex pce_table_lock; };
struct gswip_pce_table_entry { @@ -523,10 +524,14 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSRD : GSWIP_PCE_TBL_CTRL_OPMOD_ADRD;
+ mutex_lock(&priv->pce_table_lock); + err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS); - if (err) + if (err) { + mutex_unlock(&priv->pce_table_lock); return err; + }
gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK | @@ -536,8 +541,10 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv,
err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS); - if (err) + if (err) { + mutex_unlock(&priv->pce_table_lock); return err; + }
for (i = 0; i < ARRAY_SIZE(tbl->key); i++) tbl->key[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_KEY(i)); @@ -553,6 +560,8 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, tbl->valid = !!(crtl & GSWIP_PCE_TBL_CTRL_VLD); tbl->gmap = (crtl & GSWIP_PCE_TBL_CTRL_GMAP_MASK) >> 7;
+ mutex_unlock(&priv->pce_table_lock); + return 0; }
@@ -565,10 +574,14 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSWR : GSWIP_PCE_TBL_CTRL_OPMOD_ADWR;
+ mutex_lock(&priv->pce_table_lock); + err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS); - if (err) + if (err) { + mutex_unlock(&priv->pce_table_lock); return err; + }
gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK | @@ -600,8 +613,12 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, crtl |= GSWIP_PCE_TBL_CTRL_BAS; gswip_switch_w(priv, crtl, GSWIP_PCE_TBL_CTRL);
- return gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, - GSWIP_PCE_TBL_CTRL_BAS); + err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, + GSWIP_PCE_TBL_CTRL_BAS); + + mutex_unlock(&priv->pce_table_lock); + + return err; }
/* Add the LAN port into a bridge with the CPU port by @@ -2106,6 +2123,7 @@ static int gswip_probe(struct platform_device *pdev) priv->ds->priv = priv; priv->ds->ops = priv->hw_info->ops; priv->dev = dev; + mutex_init(&priv->pce_table_lock); version = gswip_switch_r(priv, GSWIP_VERSION);
np = dev->of_node;
On Mon, Nov 15, 2021 at 05:56:26PM +0100, Greg Kroah-Hartman wrote:
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 49753a75b9a32de4c0393bb8d1e51ea223fda8e4 ]
Looking at the code, the GSWIP switch appears to hold bridging service structures (VLANs, FDBs, forwarding rules) in PCE table entries. Hardware access to the PCE table is non-atomic, and is comprised of several register reads and writes.
These accesses are currently serialized by the rtnl_lock, but DSA is changing its driver API and that lock will no longer be held when calling ->port_fdb_add() and ->port_fdb_del().
So this driver needs to serialize the access to the PCE table using its own locking scheme. This patch adds that.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Hauke Mehrtens hauke@hauke-m.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
drivers/net/dsa/lantiq_gswip.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index dbd4486a173ff..1a96df70d1e85 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -276,6 +276,7 @@ struct gswip_priv { int num_gphy_fw; struct gswip_gphy_fw *gphy_fw; u32 port_vlan_filter;
- struct mutex pce_table_lock;
}; struct gswip_pce_table_entry { @@ -523,10 +524,14 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSRD : GSWIP_PCE_TBL_CTRL_OPMOD_ADRD;
- mutex_lock(&priv->pce_table_lock);
- err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS);
- if (err)
- if (err) {
return err;mutex_unlock(&priv->pce_table_lock);
- }
gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK | @@ -536,8 +541,10 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS);
- if (err)
- if (err) {
return err;mutex_unlock(&priv->pce_table_lock);
- }
for (i = 0; i < ARRAY_SIZE(tbl->key); i++) tbl->key[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_KEY(i)); @@ -553,6 +560,8 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, tbl->valid = !!(crtl & GSWIP_PCE_TBL_CTRL_VLD); tbl->gmap = (crtl & GSWIP_PCE_TBL_CTRL_GMAP_MASK) >> 7;
- mutex_unlock(&priv->pce_table_lock);
- return 0;
} @@ -565,10 +574,14 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSWR : GSWIP_PCE_TBL_CTRL_OPMOD_ADWR;
- mutex_lock(&priv->pce_table_lock);
- err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS);
- if (err)
- if (err) {
return err;mutex_unlock(&priv->pce_table_lock);
- }
gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK | @@ -600,8 +613,12 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, crtl |= GSWIP_PCE_TBL_CTRL_BAS; gswip_switch_w(priv, crtl, GSWIP_PCE_TBL_CTRL);
- return gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
GSWIP_PCE_TBL_CTRL_BAS);
- err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
GSWIP_PCE_TBL_CTRL_BAS);
- mutex_unlock(&priv->pce_table_lock);
- return err;
} /* Add the LAN port into a bridge with the CPU port by @@ -2106,6 +2123,7 @@ static int gswip_probe(struct platform_device *pdev) priv->ds->priv = priv; priv->ds->ops = priv->hw_info->ops; priv->dev = dev;
- mutex_init(&priv->pce_table_lock); version = gswip_switch_r(priv, GSWIP_VERSION);
np = dev->of_node; -- 2.33.0
As discussed on the v5.14 backport, this patch can be dropped.
On Mon, Nov 15, 2021 at 11:35:47PM +0000, Vladimir Oltean wrote:
On Mon, Nov 15, 2021 at 05:56:26PM +0100, Greg Kroah-Hartman wrote:
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 49753a75b9a32de4c0393bb8d1e51ea223fda8e4 ]
Looking at the code, the GSWIP switch appears to hold bridging service structures (VLANs, FDBs, forwarding rules) in PCE table entries. Hardware access to the PCE table is non-atomic, and is comprised of several register reads and writes.
These accesses are currently serialized by the rtnl_lock, but DSA is changing its driver API and that lock will no longer be held when calling ->port_fdb_add() and ->port_fdb_del().
So this driver needs to serialize the access to the PCE table using its own locking scheme. This patch adds that.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Hauke Mehrtens hauke@hauke-m.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
drivers/net/dsa/lantiq_gswip.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index dbd4486a173ff..1a96df70d1e85 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -276,6 +276,7 @@ struct gswip_priv { int num_gphy_fw; struct gswip_gphy_fw *gphy_fw; u32 port_vlan_filter;
- struct mutex pce_table_lock;
};
struct gswip_pce_table_entry { @@ -523,10 +524,14 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSRD : GSWIP_PCE_TBL_CTRL_OPMOD_ADRD;
- mutex_lock(&priv->pce_table_lock);
- err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS);
- if (err)
if (err) {
mutex_unlock(&priv->pce_table_lock);
return err;
}
gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK |
@@ -536,8 +541,10 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv,
err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS);
- if (err)
if (err) {
mutex_unlock(&priv->pce_table_lock);
return err;
}
for (i = 0; i < ARRAY_SIZE(tbl->key); i++) tbl->key[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_KEY(i));
@@ -553,6 +560,8 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, tbl->valid = !!(crtl & GSWIP_PCE_TBL_CTRL_VLD); tbl->gmap = (crtl & GSWIP_PCE_TBL_CTRL_GMAP_MASK) >> 7;
- mutex_unlock(&priv->pce_table_lock);
- return 0;
}
@@ -565,10 +574,14 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSWR : GSWIP_PCE_TBL_CTRL_OPMOD_ADWR;
- mutex_lock(&priv->pce_table_lock);
- err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS);
- if (err)
if (err) {
mutex_unlock(&priv->pce_table_lock);
return err;
}
gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK |
@@ -600,8 +613,12 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, crtl |= GSWIP_PCE_TBL_CTRL_BAS; gswip_switch_w(priv, crtl, GSWIP_PCE_TBL_CTRL);
- return gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
GSWIP_PCE_TBL_CTRL_BAS);
- err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL,
GSWIP_PCE_TBL_CTRL_BAS);
- mutex_unlock(&priv->pce_table_lock);
- return err;
}
/* Add the LAN port into a bridge with the CPU port by @@ -2106,6 +2123,7 @@ static int gswip_probe(struct platform_device *pdev) priv->ds->priv = priv; priv->ds->ops = priv->hw_info->ops; priv->dev = dev;
mutex_init(&priv->pce_table_lock); version = gswip_switch_r(priv, GSWIP_VERSION);
np = dev->of_node;
-- 2.33.0
As discussed on the v5.14 backport, this patch can be dropped.
Dropped, thanks!
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit e346290439609a8ac67122418ca2efbad8d0a7e7 ]
All timing calculation is done with unsigned integers, so change type of tseg1 and alltseg to unsigned int, too.
Link: https://lore.kernel.org/all/20211013130653.1513627-1-mkl@pengutronix.de Link: https://github.com/linux-can/can-utils/pull/314 Reported-by: Gary Bisson bisson.gary@gmail.com Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/dev/bittiming.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/dev/bittiming.c b/drivers/net/can/dev/bittiming.c index f49170eadd547..b1b5a82f08299 100644 --- a/drivers/net/can/dev/bittiming.c +++ b/drivers/net/can/dev/bittiming.c @@ -209,7 +209,7 @@ static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, const struct can_bittiming_const *btc) { struct can_priv *priv = netdev_priv(dev); - int tseg1, alltseg; + unsigned int tseg1, alltseg; u64 brp64;
tseg1 = bt->prop_seg + bt->phase_seg1;
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit 486408d690e130c3adacf816754b97558d715f46 ]
In gfs2_inode_lookup and gfs2_create_inode, we're calling gfs2_cancel_delete_work which currently cancels any remote delete work (delete_work_func) synchronously. This means that if the work is currently running, it will wait for it to finish. We're doing this to pevent a previous instance of an inode from having any influence on the next instance.
However, delete_work_func uses gfs2_inode_lookup internally, and we can end up in a deadlock when delete_work_func gets interrupted at the wrong time. For example,
(1) An inode's iopen glock has delete work queued, but the inode itself has been evicted from the inode cache.
(2) The delete work is preempted before reaching gfs2_inode_lookup.
(3) Another process recreates the inode (gfs2_create_inode). It tries to cancel any outstanding delete work, which blocks waiting for the ongoing delete work to finish.
(4) The delete work calls gfs2_inode_lookup, which blocks waiting for gfs2_create_inode to instantiate and unlock the new inode => deadlock.
It turns out that when the delete work notices that its inode has been re-instantiated, it will do nothing. This means that it's safe to cancel the delete work asynchronously. This prevents the kind of deadlock described above.
Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Bob Peterson rpeterso@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/glock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index e0eaa9cf9fb6f..8ca89adf31a86 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1919,7 +1919,7 @@ bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
void gfs2_cancel_delete_work(struct gfs2_glock *gl) { - if (cancel_delayed_work_sync(&gl->gl_delete)) { + if (cancel_delayed_work(&gl->gl_delete)) { clear_bit(GLF_PENDING_DELETE, &gl->gl_flags); gfs2_glock_put(gl); }
From: Andreas Gruenbacher agruenba@redhat.com
[ Upstream commit 7427f3bb49d81525b7dd1d0f7c5f6bbc752e6f0e ]
So far, glock_hash_walk took a reference on each glock it iterated over, and it was the examiner's responsibility to drop those references. Dropping the final reference to a glock can sleep and the examiners are called in a RCU critical section with spin locks held, so examiners that didn't need the extra reference had to drop it asynchronously via gfs2_glock_queue_put or similar. This wasn't done correctly in thaw_glock which did call gfs2_glock_put, and not at all in dump_glock_func.
Change glock_hash_walk to not take glock references at all. That way, the examiners that don't need them won't have to bother with slow asynchronous puts, and the examiners that do need references can take them themselves.
Reported-by: Alexander Aring aahringo@redhat.com Signed-off-by: Andreas Gruenbacher agruenba@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/gfs2/glock.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 8ca89adf31a86..02cd0ae98208d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1893,10 +1893,10 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp) do { rhashtable_walk_start(&iter);
- while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl)) - if (gl->gl_name.ln_sbd == sdp && - lockref_get_not_dead(&gl->gl_lockref)) + while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl)) { + if (gl->gl_name.ln_sbd == sdp) examiner(gl); + }
rhashtable_walk_stop(&iter); } while (cond_resched(), gl == ERR_PTR(-EAGAIN)); @@ -1938,7 +1938,6 @@ static void flush_delete_work(struct gfs2_glock *gl) &gl->gl_delete, 0); } } - gfs2_glock_queue_work(gl, 0); }
void gfs2_flush_delete_work(struct gfs2_sbd *sdp) @@ -1955,10 +1954,10 @@ void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
static void thaw_glock(struct gfs2_glock *gl) { - if (!test_and_clear_bit(GLF_FROZEN, &gl->gl_flags)) { - gfs2_glock_put(gl); + if (!test_and_clear_bit(GLF_FROZEN, &gl->gl_flags)) + return; + if (!lockref_get_not_dead(&gl->gl_lockref)) return; - } set_bit(GLF_REPLY_PENDING, &gl->gl_flags); gfs2_glock_queue_work(gl, 0); } @@ -1974,9 +1973,12 @@ static void clear_glock(struct gfs2_glock *gl) gfs2_glock_remove_from_lru(gl);
spin_lock(&gl->gl_lockref.lock); - if (gl->gl_state != LM_ST_UNLOCKED) - handle_callback(gl, LM_ST_UNLOCKED, 0, false); - __gfs2_glock_queue_work(gl, 0); + if (!__lockref_is_dead(&gl->gl_lockref)) { + gl->gl_lockref.count++; + if (gl->gl_state != LM_ST_UNLOCKED) + handle_callback(gl, LM_ST_UNLOCKED, 0, false); + __gfs2_glock_queue_work(gl, 0); + } spin_unlock(&gl->gl_lockref.lock); }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 345dac33f58894a56d17b92a41be10e16585ceff ]
When configuring the kernel for big-endian, we set either BE-8 or BE-32 based on the CPU architecture level. Until linux-4.4, we did not have any ARMv7-M platform allowing big-endian builds, but now i.MX/Vybrid is in that category, adn we get a build error because of this:
arch/arm/kernel/module-plts.c: In function 'get_module_plt': arch/arm/kernel/module-plts.c:60:46: error: implicit declaration of function '__opcode_to_mem_thumb32' [-Werror=implicit-function-declaration]
This comes down to picking the wrong default, ARMv7-M uses BE8 like ARMv7-A does. Changing the default gets the kernel to compile and presumably works.
https://lore.kernel.org/all/1455804123-2526139-2-git-send-email-arnd@arndb.d...
Tested-by: Vladimir Murzin vladimir.murzin@arm.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 8355c38958942..82aa990c4180c 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -750,7 +750,7 @@ config CPU_BIG_ENDIAN config CPU_ENDIAN_BE8 bool depends on CPU_BIG_ENDIAN - default CPU_V6 || CPU_V6K || CPU_V7 + default CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M help Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors.
From: Viktor Rosendahl Viktor.Rosendahl@bmw.de
[ Upstream commit f604de20c0a47e0e9518940a1810193678c92fa8 ]
queue_full_warning is a pointer, so it is wrong to use sizeof to calculate the number of characters of the string it points to. The effect is that we only print out the first few characters of the warning string.
The correct way is to use strlen(). We don't need to add 1 to the strlen() because we don't want to write the terminating null character to stdout.
Link: https://lkml.kernel.org/r/20211019160701.15587-1-Viktor.Rosendahl@bmw.de
Link: https://lore.kernel.org/r/8fd4bb65ef3da67feac9ce3258cdbe9824752cf1.162919850... Link: https://lore.kernel.org/r/20211012025424.180781-1-davidcomponentone@gmail.co... Reported-by: Zeal Robot zealci@zte.com.cn Signed-off-by: Viktor Rosendahl Viktor.Rosendahl@bmw.de Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/tracing/latency/latency-collector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/tracing/latency/latency-collector.c b/tools/tracing/latency/latency-collector.c index 3a2e6bb781a8c..59a7f2346eab4 100644 --- a/tools/tracing/latency/latency-collector.c +++ b/tools/tracing/latency/latency-collector.c @@ -1538,7 +1538,7 @@ static void tracing_loop(void) mutex_lock(&print_mtx); check_signals(); write_or_die(fd_stdout, queue_full_warning, - sizeof(queue_full_warning)); + strlen(queue_full_warning)); mutex_unlock(&print_mtx); } modified--;
From: Florian Westphal fw@strlen.de
[ Upstream commit 8c9c296adfae9ea05f655d69e9f6e13daa86fb4a ]
The VRF driver invokes netfilter for output+postrouting hooks so that users can create rules that check for 'oif $vrf' rather than lower device name.
This is a problem when NAT rules are configured.
To avoid any conntrack involvement in round 1, tag skbs as 'untracked' to prevent conntrack from picking them up.
This gets cleared before the packet gets handed to the ip stack so conntrack will be active on the second iteration.
One remaining issue is that a rule like
output ... oif $vrfname notrack
won't propagate to the second round because we can't tell 'notrack set via ruleset' and 'notrack set by vrf driver' apart. However, this isn't a regression: the 'notrack' removal happens instead of unconditional nf_reset_ct(). I'd also like to avoid leaking more vrf specific conditionals into the netfilter infra.
For ingress, conntrack has already been done before the packet makes it to the vrf driver, with this patch egress does connection tracking with lower/physical device as well.
Signed-off-by: Florian Westphal fw@strlen.de Acked-by: David Ahern dsahern@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/vrf.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 662e261173539..ccf677015d5bc 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -35,6 +35,7 @@ #include <net/l3mdev.h> #include <net/fib_rules.h> #include <net/netns/generic.h> +#include <net/netfilter/nf_conntrack.h>
#define DRV_NAME "vrf" #define DRV_VERSION "1.1" @@ -424,12 +425,26 @@ static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev, return NETDEV_TX_OK; }
+static void vrf_nf_set_untracked(struct sk_buff *skb) +{ + if (skb_get_nfct(skb) == 0) + nf_ct_set(skb, NULL, IP_CT_UNTRACKED); +} + +static void vrf_nf_reset_ct(struct sk_buff *skb) +{ + if (skb_get_nfct(skb) == IP_CT_UNTRACKED) + nf_reset_ct(skb); +} + #if IS_ENABLED(CONFIG_IPV6) static int vrf_ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) { int err;
+ vrf_nf_reset_ct(skb); + err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, NULL, skb_dst(skb)->dev, dst_output);
@@ -508,6 +523,8 @@ static int vrf_ip_local_out(struct net *net, struct sock *sk, { int err;
+ vrf_nf_reset_ct(skb); + err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk, skb, NULL, skb_dst(skb)->dev, dst_output); if (likely(err == 1)) @@ -626,8 +643,7 @@ static void vrf_finish_direct(struct sk_buff *skb) skb_pull(skb, ETH_HLEN); }
- /* reset skb device */ - nf_reset_ct(skb); + vrf_nf_reset_ct(skb); }
#if IS_ENABLED(CONFIG_IPV6) @@ -641,7 +657,7 @@ static int vrf_finish_output6(struct net *net, struct sock *sk, struct neighbour *neigh; int ret;
- nf_reset_ct(skb); + vrf_nf_reset_ct(skb);
skb->protocol = htons(ETH_P_IPV6); skb->dev = dev; @@ -752,6 +768,8 @@ static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev,
skb->dev = vrf_dev;
+ vrf_nf_set_untracked(skb); + err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, NULL, vrf_dev, vrf_ip6_out_direct_finish);
@@ -858,7 +876,7 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s struct neighbour *neigh; bool is_v6gw = false;
- nf_reset_ct(skb); + vrf_nf_reset_ct(skb);
/* Be paranoid, rather than too clever. */ if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { @@ -980,6 +998,8 @@ static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev,
skb->dev = vrf_dev;
+ vrf_nf_set_untracked(skb); + err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk, skb, NULL, vrf_dev, vrf_ip_out_direct_finish);
From: Eric Dumazet edumazet@google.com
[ Upstream commit d18785e213866935b4c3dc0c33c3e18801ce0ce8 ]
neigh_output() reads n->nud_state and hh->hh_len locklessly.
This is fine, but we need to add annotations and document this.
We evaluate skip_cache first to avoid reading these fields if the cache has to by bypassed.
syzbot report:
BUG: KCSAN: data-race in __neigh_event_send / ip_finish_output2
write to 0xffff88810798a885 of 1 bytes by interrupt on cpu 1: __neigh_event_send+0x40d/0xac0 net/core/neighbour.c:1128 neigh_event_send include/net/neighbour.h:444 [inline] neigh_resolve_output+0x104/0x410 net/core/neighbour.c:1476 neigh_output include/net/neighbour.h:510 [inline] ip_finish_output2+0x80a/0xaa0 net/ipv4/ip_output.c:221 ip_finish_output+0x3b5/0x510 net/ipv4/ip_output.c:309 NF_HOOK_COND include/linux/netfilter.h:296 [inline] ip_output+0xf3/0x1a0 net/ipv4/ip_output.c:423 dst_output include/net/dst.h:450 [inline] ip_local_out+0x164/0x220 net/ipv4/ip_output.c:126 __ip_queue_xmit+0x9d3/0xa20 net/ipv4/ip_output.c:525 ip_queue_xmit+0x34/0x40 net/ipv4/ip_output.c:539 __tcp_transmit_skb+0x142a/0x1a00 net/ipv4/tcp_output.c:1405 tcp_transmit_skb net/ipv4/tcp_output.c:1423 [inline] tcp_xmit_probe_skb net/ipv4/tcp_output.c:4011 [inline] tcp_write_wakeup+0x4a9/0x810 net/ipv4/tcp_output.c:4064 tcp_send_probe0+0x2c/0x2b0 net/ipv4/tcp_output.c:4079 tcp_probe_timer net/ipv4/tcp_timer.c:398 [inline] tcp_write_timer_handler+0x394/0x520 net/ipv4/tcp_timer.c:626 tcp_write_timer+0xb9/0x180 net/ipv4/tcp_timer.c:642 call_timer_fn+0x2e/0x1d0 kernel/time/timer.c:1421 expire_timers+0x135/0x240 kernel/time/timer.c:1466 __run_timers+0x368/0x430 kernel/time/timer.c:1734 run_timer_softirq+0x19/0x30 kernel/time/timer.c:1747 __do_softirq+0x12c/0x26e kernel/softirq.c:558 invoke_softirq kernel/softirq.c:432 [inline] __irq_exit_rcu kernel/softirq.c:636 [inline] irq_exit_rcu+0x4e/0xa0 kernel/softirq.c:648 sysvec_apic_timer_interrupt+0x69/0x80 arch/x86/kernel/apic/apic.c:1097 asm_sysvec_apic_timer_interrupt+0x12/0x20 native_safe_halt arch/x86/include/asm/irqflags.h:51 [inline] arch_safe_halt arch/x86/include/asm/irqflags.h:89 [inline] acpi_safe_halt drivers/acpi/processor_idle.c:109 [inline] acpi_idle_do_entry drivers/acpi/processor_idle.c:553 [inline] acpi_idle_enter+0x258/0x2e0 drivers/acpi/processor_idle.c:688 cpuidle_enter_state+0x2b4/0x760 drivers/cpuidle/cpuidle.c:237 cpuidle_enter+0x3c/0x60 drivers/cpuidle/cpuidle.c:351 call_cpuidle kernel/sched/idle.c:158 [inline] cpuidle_idle_call kernel/sched/idle.c:239 [inline] do_idle+0x1a3/0x250 kernel/sched/idle.c:306 cpu_startup_entry+0x15/0x20 kernel/sched/idle.c:403 secondary_startup_64_no_verify+0xb1/0xbb
read to 0xffff88810798a885 of 1 bytes by interrupt on cpu 0: neigh_output include/net/neighbour.h:507 [inline] ip_finish_output2+0x79a/0xaa0 net/ipv4/ip_output.c:221 ip_finish_output+0x3b5/0x510 net/ipv4/ip_output.c:309 NF_HOOK_COND include/linux/netfilter.h:296 [inline] ip_output+0xf3/0x1a0 net/ipv4/ip_output.c:423 dst_output include/net/dst.h:450 [inline] ip_local_out+0x164/0x220 net/ipv4/ip_output.c:126 __ip_queue_xmit+0x9d3/0xa20 net/ipv4/ip_output.c:525 ip_queue_xmit+0x34/0x40 net/ipv4/ip_output.c:539 __tcp_transmit_skb+0x142a/0x1a00 net/ipv4/tcp_output.c:1405 tcp_transmit_skb net/ipv4/tcp_output.c:1423 [inline] tcp_xmit_probe_skb net/ipv4/tcp_output.c:4011 [inline] tcp_write_wakeup+0x4a9/0x810 net/ipv4/tcp_output.c:4064 tcp_send_probe0+0x2c/0x2b0 net/ipv4/tcp_output.c:4079 tcp_probe_timer net/ipv4/tcp_timer.c:398 [inline] tcp_write_timer_handler+0x394/0x520 net/ipv4/tcp_timer.c:626 tcp_write_timer+0xb9/0x180 net/ipv4/tcp_timer.c:642 call_timer_fn+0x2e/0x1d0 kernel/time/timer.c:1421 expire_timers+0x135/0x240 kernel/time/timer.c:1466 __run_timers+0x368/0x430 kernel/time/timer.c:1734 run_timer_softirq+0x19/0x30 kernel/time/timer.c:1747 __do_softirq+0x12c/0x26e kernel/softirq.c:558 invoke_softirq kernel/softirq.c:432 [inline] __irq_exit_rcu kernel/softirq.c:636 [inline] irq_exit_rcu+0x4e/0xa0 kernel/softirq.c:648 sysvec_apic_timer_interrupt+0x69/0x80 arch/x86/kernel/apic/apic.c:1097 asm_sysvec_apic_timer_interrupt+0x12/0x20 native_safe_halt arch/x86/include/asm/irqflags.h:51 [inline] arch_safe_halt arch/x86/include/asm/irqflags.h:89 [inline] acpi_safe_halt drivers/acpi/processor_idle.c:109 [inline] acpi_idle_do_entry drivers/acpi/processor_idle.c:553 [inline] acpi_idle_enter+0x258/0x2e0 drivers/acpi/processor_idle.c:688 cpuidle_enter_state+0x2b4/0x760 drivers/cpuidle/cpuidle.c:237 cpuidle_enter+0x3c/0x60 drivers/cpuidle/cpuidle.c:351 call_cpuidle kernel/sched/idle.c:158 [inline] cpuidle_idle_call kernel/sched/idle.c:239 [inline] do_idle+0x1a3/0x250 kernel/sched/idle.c:306 cpu_startup_entry+0x15/0x20 kernel/sched/idle.c:403 rest_init+0xee/0x100 init/main.c:734 arch_call_rest_init+0xa/0xb start_kernel+0x5e4/0x669 init/main.c:1142 secondary_startup_64_no_verify+0xb1/0xbb
value changed: 0x20 -> 0x01
Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.15.0-rc6-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/neighbour.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 22ced1381ede5..990f9b1d17092 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -504,10 +504,15 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb, { const struct hh_cache *hh = &n->hh;
- if ((n->nud_state & NUD_CONNECTED) && hh->hh_len && !skip_cache) + /* n->nud_state and hh->hh_len could be changed under us. + * neigh_hh_output() is taking care of the race later. + */ + if (!skip_cache && + (READ_ONCE(n->nud_state) & NUD_CONNECTED) && + READ_ONCE(hh->hh_len)) return neigh_hh_output(hh, skb); - else - return n->output(n, skb); + + return n->output(n, skb); }
static inline struct neighbour *
From: Stefan Schaeckeler schaecsn@gmx.net
[ Upstream commit 3d730ee686800d71ecc5c3cb8460dcdcdeaf38a3 ]
Let GK45 not go into BIOS for determining the AC power state.
The BIOS wrongly returns 0, so hardcode the power state to 1.
The mini PC GK45 by Besstar Tech Lld. (aka Kodlix) just runs off AC. It does not include any batteries. Nevertheless BIOS reports AC off:
root@kodlix:/usr/src/linux# cat /sys/class/power_supply/ADP1/online 0
root@kodlix:/usr/src/linux# modprobe acpi_dbg root@kodlix:/usr/src/linux# tools/power/acpi/acpidbg
- find _PSR _SB.PCI0.SBRG.H_EC.ADP1._PSR Method 000000009283cee8 001 Args 0 Len 001C Aml 00000000f54e5f67
- execute _SB.PCI0.SBRG.H_EC.ADP1._PSR Evaluating _SB.PCI0.SBRG.H_EC.ADP1._PSR Evaluation of _SB.PCI0.SBRG.H_EC.ADP1._PSR returned object 00000000dc08c187, external buffer length 18 [Integer] = 0000000000000000
that should be
[Integer] = 0000000000000001
Signed-off-by: Stefan Schaeckeler schaecsn@gmx.net Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/ac.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index b0cb662233f1a..81aff651a0d49 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -61,6 +61,7 @@ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
static int ac_sleep_before_get_state_ms; static int ac_check_pmic = 1; +static int ac_only;
static struct acpi_driver acpi_ac_driver = { .name = "ac", @@ -93,6 +94,11 @@ static int acpi_ac_get_state(struct acpi_ac *ac) if (!ac) return -EINVAL;
+ if (ac_only) { + ac->state = 1; + return 0; + } + status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); if (ACPI_FAILURE(status)) { @@ -200,6 +206,12 @@ static int __init ac_do_not_check_pmic_quirk(const struct dmi_system_id *d) return 0; }
+static int __init ac_only_quirk(const struct dmi_system_id *d) +{ + ac_only = 1; + return 0; +} + /* Please keep this list alphabetically sorted */ static const struct dmi_system_id ac_dmi_table[] __initconst = { { @@ -209,6 +221,13 @@ static const struct dmi_system_id ac_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), }, }, + { + /* Kodlix GK45 returning incorrect state */ + .callback = ac_only_quirk, + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "GK45"), + }, + }, { /* Lenovo Ideapad Miix 320, AXP288 PMIC, separate fuel-gauge */ .callback = ac_do_not_check_pmic_quirk,
From: Hui Wang hui.wang@canonical.com
[ Upstream commit 1b26ae40092b43bb6e9c5df376227382b390b953 ]
The Medion s17 series laptops have the same issue on the keyboard as the s15 series, if skipping to call acpi_get_override_irq(), the keyboard could work well. So put the DMI info of s17 series in the IRQ override quirk table as well.
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=213031 Tested-by: dirksche dirksche@posteo.de Signed-off-by: Hui Wang hui.wang@canonical.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/resource.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 7bf38652e6aca..3c25ce8c95ba1 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -389,6 +389,13 @@ static const struct dmi_system_id medion_laptop[] = { DMI_MATCH(DMI_BOARD_NAME, "M15T"), }, }, + { + .ident = "MEDION S17405", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_BOARD_NAME, "M17T"), + }, + }, { } };
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit d7d0d423dbaa73fd0506e25971dfdab6bf185d00 ]
DSA is preparing to offer switch drivers an API through which they can associate each FDB entry with a struct net_device *bridge_dev. This can be used to perform FDB isolation (the FDB lookup performed on the ingress of a standalone, or bridged port, should not find an FDB entry that is present in the FDB of another bridge).
In preparation of that work, DSA needs to ensure that by the time we call the switch .port_fdb_add and .port_fdb_del methods, the dp->bridge_dev pointer is still valid, i.e. the port is still a bridge port.
This is not guaranteed because the SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE API requires drivers that must have sleepable context to handle those events to schedule the deferred work themselves. DSA does this through the dsa_owq.
It can happen that a port leaves a bridge, del_nbp() flushes the FDB on that port, SWITCHDEV_FDB_DEL_TO_DEVICE is notified in atomic context, DSA schedules its deferred work, but del_nbp() finishes unlinking the bridge as a master from the port before DSA's deferred work is run.
Fundamentally, the port must not be unlinked from the bridge until all FDB deletion deferred work items have been flushed. The bridge must wait for the completion of these hardware accesses.
An attempt has been made to address this issue centrally in switchdev by making SWITCHDEV_FDB_DEL_TO_DEVICE deferred (=> blocking) at the switchdev level, which would offer implicit synchronization with del_nbp:
https://patchwork.kernel.org/project/netdevbpf/cover/20210820115746.3701811-...
but it seems that any attempt to modify switchdev's behavior and make the events blocking there would introduce undesirable side effects in other switchdev consumers.
The most undesirable behavior seems to be that switchdev_deferred_process_work() takes the rtnl_mutex itself, which would be worse off than having the rtnl_mutex taken individually from drivers which is what we have now (except DSA which has removed that lock since commit 0faf890fc519 ("net: dsa: drop rtnl_lock from dsa_slave_switchdev_event_work")).
So to offer the needed guarantee to DSA switch drivers, I have come up with a compromise solution that does not require switchdev rework: we already have a hook at the last moment in time when the bridge is still an upper of ours: the NETDEV_PRECHANGEUPPER handler. We can flush the dsa_owq manually from there, which makes all FDB deletions synchronous.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/port.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/dsa/port.c b/net/dsa/port.c index 616330a16d319..3947537ed46ba 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -380,6 +380,8 @@ void dsa_port_pre_bridge_leave(struct dsa_port *dp, struct net_device *br) switchdev_bridge_port_unoffload(brport_dev, dp, &dsa_slave_switchdev_notifier, &dsa_slave_switchdev_blocking_notifier); + + dsa_flush_workqueue(); }
void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
On Mon, Nov 15, 2021 at 05:56:36PM +0100, Greg Kroah-Hartman wrote:
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit d7d0d423dbaa73fd0506e25971dfdab6bf185d00 ]
DSA is preparing to offer switch drivers an API through which they can associate each FDB entry with a struct net_device *bridge_dev. This can be used to perform FDB isolation (the FDB lookup performed on the ingress of a standalone, or bridged port, should not find an FDB entry that is present in the FDB of another bridge).
In preparation of that work, DSA needs to ensure that by the time we call the switch .port_fdb_add and .port_fdb_del methods, the dp->bridge_dev pointer is still valid, i.e. the port is still a bridge port.
This is not guaranteed because the SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE API requires drivers that must have sleepable context to handle those events to schedule the deferred work themselves. DSA does this through the dsa_owq.
It can happen that a port leaves a bridge, del_nbp() flushes the FDB on that port, SWITCHDEV_FDB_DEL_TO_DEVICE is notified in atomic context, DSA schedules its deferred work, but del_nbp() finishes unlinking the bridge as a master from the port before DSA's deferred work is run.
Fundamentally, the port must not be unlinked from the bridge until all FDB deletion deferred work items have been flushed. The bridge must wait for the completion of these hardware accesses.
An attempt has been made to address this issue centrally in switchdev by making SWITCHDEV_FDB_DEL_TO_DEVICE deferred (=> blocking) at the switchdev level, which would offer implicit synchronization with del_nbp:
https://patchwork.kernel.org/project/netdevbpf/cover/20210820115746.3701811-...
but it seems that any attempt to modify switchdev's behavior and make the events blocking there would introduce undesirable side effects in other switchdev consumers.
The most undesirable behavior seems to be that switchdev_deferred_process_work() takes the rtnl_mutex itself, which would be worse off than having the rtnl_mutex taken individually from drivers which is what we have now (except DSA which has removed that lock since commit 0faf890fc519 ("net: dsa: drop rtnl_lock from dsa_slave_switchdev_event_work")).
So to offer the needed guarantee to DSA switch drivers, I have come up with a compromise solution that does not require switchdev rework: we already have a hook at the last moment in time when the bridge is still an upper of ours: the NETDEV_PRECHANGEUPPER handler. We can flush the dsa_owq manually from there, which makes all FDB deletions synchronous.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
net/dsa/port.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/dsa/port.c b/net/dsa/port.c index 616330a16d319..3947537ed46ba 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -380,6 +380,8 @@ void dsa_port_pre_bridge_leave(struct dsa_port *dp, struct net_device *br) switchdev_bridge_port_unoffload(brport_dev, dp, &dsa_slave_switchdev_notifier, &dsa_slave_switchdev_blocking_notifier);
- dsa_flush_workqueue();
} void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) -- 2.33.0
This patch represents preparation work for a new feature. Unless it constitutes a dependency for some other bugfix patches (which I doubt), my suggestion is to not backport it. Thanks.
On Mon, Nov 15, 2021 at 11:33:59PM +0000, Vladimir Oltean wrote:
On Mon, Nov 15, 2021 at 05:56:36PM +0100, Greg Kroah-Hartman wrote:
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit d7d0d423dbaa73fd0506e25971dfdab6bf185d00 ]
DSA is preparing to offer switch drivers an API through which they can associate each FDB entry with a struct net_device *bridge_dev. This can be used to perform FDB isolation (the FDB lookup performed on the ingress of a standalone, or bridged port, should not find an FDB entry that is present in the FDB of another bridge).
In preparation of that work, DSA needs to ensure that by the time we call the switch .port_fdb_add and .port_fdb_del methods, the dp->bridge_dev pointer is still valid, i.e. the port is still a bridge port.
This is not guaranteed because the SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE API requires drivers that must have sleepable context to handle those events to schedule the deferred work themselves. DSA does this through the dsa_owq.
It can happen that a port leaves a bridge, del_nbp() flushes the FDB on that port, SWITCHDEV_FDB_DEL_TO_DEVICE is notified in atomic context, DSA schedules its deferred work, but del_nbp() finishes unlinking the bridge as a master from the port before DSA's deferred work is run.
Fundamentally, the port must not be unlinked from the bridge until all FDB deletion deferred work items have been flushed. The bridge must wait for the completion of these hardware accesses.
An attempt has been made to address this issue centrally in switchdev by making SWITCHDEV_FDB_DEL_TO_DEVICE deferred (=> blocking) at the switchdev level, which would offer implicit synchronization with del_nbp:
https://patchwork.kernel.org/project/netdevbpf/cover/20210820115746.3701811-...
but it seems that any attempt to modify switchdev's behavior and make the events blocking there would introduce undesirable side effects in other switchdev consumers.
The most undesirable behavior seems to be that switchdev_deferred_process_work() takes the rtnl_mutex itself, which would be worse off than having the rtnl_mutex taken individually from drivers which is what we have now (except DSA which has removed that lock since commit 0faf890fc519 ("net: dsa: drop rtnl_lock from dsa_slave_switchdev_event_work")).
So to offer the needed guarantee to DSA switch drivers, I have come up with a compromise solution that does not require switchdev rework: we already have a hook at the last moment in time when the bridge is still an upper of ours: the NETDEV_PRECHANGEUPPER handler. We can flush the dsa_owq manually from there, which makes all FDB deletions synchronous.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org
net/dsa/port.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/dsa/port.c b/net/dsa/port.c index 616330a16d319..3947537ed46ba 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -380,6 +380,8 @@ void dsa_port_pre_bridge_leave(struct dsa_port *dp, struct net_device *br) switchdev_bridge_port_unoffload(brport_dev, dp, &dsa_slave_switchdev_notifier, &dsa_slave_switchdev_blocking_notifier);
- dsa_flush_workqueue();
}
void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
2.33.0
This patch represents preparation work for a new feature. Unless it constitutes a dependency for some other bugfix patches (which I doubt), my suggestion is to not backport it. Thanks.
Dropped, thanks!
From: Sidong Yang realwakka@gmail.com
[ Upstream commit 44bee215f72f13874c0e734a0712c2e3264c0108 ]
Fix a warning reported by smatch that ret could be returned without initialized. The dedupe operations are supposed to to return 0 for a 0 length range but the caller does not pass olen == 0. To keep this behaviour and also fix the warning initialize ret to 0.
Reviewed-by: Filipe Manana fdmanana@suse.com Signed-off-by: Sidong Yang realwakka@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/reflink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c index 9b0814318e726..c71e49782e86d 100644 --- a/fs/btrfs/reflink.c +++ b/fs/btrfs/reflink.c @@ -649,7 +649,7 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 len, static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen, struct inode *dst, u64 dst_loff) { - int ret; + int ret = 0; u64 i, tail_len, chunk_count; struct btrfs_root *root_dst = BTRFS_I(dst)->root;
From: Josef Bacik josef@toxicpanda.com
[ Upstream commit 8ef9dc0f14ba6124c62547a4fdc59b163d8b864e ]
We got the following lockdep splat while running fstests (specifically btrfs/003 and btrfs/020 in a row) with the new rc. This was uncovered by 87579e9b7d8d ("loop: use worker per cgroup instead of kworker") which converted loop to using workqueues, which comes with lockdep annotations that don't exist with kworkers. The lockdep splat is as follows:
WARNING: possible circular locking dependency detected 5.14.0-rc2-custom+ #34 Not tainted ------------------------------------------------------ losetup/156417 is trying to acquire lock: ffff9c7645b02d38 ((wq_completion)loop0){+.+.}-{0:0}, at: flush_workqueue+0x84/0x600
but task is already holding lock: ffff9c7647395468 (&lo->lo_mutex){+.+.}-{3:3}, at: __loop_clr_fd+0x41/0x650 [loop]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #5 (&lo->lo_mutex){+.+.}-{3:3}: __mutex_lock+0xba/0x7c0 lo_open+0x28/0x60 [loop] blkdev_get_whole+0x28/0xf0 blkdev_get_by_dev.part.0+0x168/0x3c0 blkdev_open+0xd2/0xe0 do_dentry_open+0x163/0x3a0 path_openat+0x74d/0xa40 do_filp_open+0x9c/0x140 do_sys_openat2+0xb1/0x170 __x64_sys_openat+0x54/0x90 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #4 (&disk->open_mutex){+.+.}-{3:3}: __mutex_lock+0xba/0x7c0 blkdev_get_by_dev.part.0+0xd1/0x3c0 blkdev_get_by_path+0xc0/0xd0 btrfs_scan_one_device+0x52/0x1f0 [btrfs] btrfs_control_ioctl+0xac/0x170 [btrfs] __x64_sys_ioctl+0x83/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #3 (uuid_mutex){+.+.}-{3:3}: __mutex_lock+0xba/0x7c0 btrfs_rm_device+0x48/0x6a0 [btrfs] btrfs_ioctl+0x2d1c/0x3110 [btrfs] __x64_sys_ioctl+0x83/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #2 (sb_writers#11){.+.+}-{0:0}: lo_write_bvec+0x112/0x290 [loop] loop_process_work+0x25f/0xcb0 [loop] process_one_work+0x28f/0x5d0 worker_thread+0x55/0x3c0 kthread+0x140/0x170 ret_from_fork+0x22/0x30
-> #1 ((work_completion)(&lo->rootcg_work)){+.+.}-{0:0}: process_one_work+0x266/0x5d0 worker_thread+0x55/0x3c0 kthread+0x140/0x170 ret_from_fork+0x22/0x30
-> #0 ((wq_completion)loop0){+.+.}-{0:0}: __lock_acquire+0x1130/0x1dc0 lock_acquire+0xf5/0x320 flush_workqueue+0xae/0x600 drain_workqueue+0xa0/0x110 destroy_workqueue+0x36/0x250 __loop_clr_fd+0x9a/0x650 [loop] lo_ioctl+0x29d/0x780 [loop] block_ioctl+0x3f/0x50 __x64_sys_ioctl+0x83/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
other info that might help us debug this: Chain exists of: (wq_completion)loop0 --> &disk->open_mutex --> &lo->lo_mutex Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&lo->lo_mutex); lock(&disk->open_mutex); lock(&lo->lo_mutex); lock((wq_completion)loop0);
*** DEADLOCK *** 1 lock held by losetup/156417: #0: ffff9c7647395468 (&lo->lo_mutex){+.+.}-{3:3}, at: __loop_clr_fd+0x41/0x650 [loop]
stack backtrace: CPU: 8 PID: 156417 Comm: losetup Not tainted 5.14.0-rc2-custom+ #34 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 Call Trace: dump_stack_lvl+0x57/0x72 check_noncircular+0x10a/0x120 __lock_acquire+0x1130/0x1dc0 lock_acquire+0xf5/0x320 ? flush_workqueue+0x84/0x600 flush_workqueue+0xae/0x600 ? flush_workqueue+0x84/0x600 drain_workqueue+0xa0/0x110 destroy_workqueue+0x36/0x250 __loop_clr_fd+0x9a/0x650 [loop] lo_ioctl+0x29d/0x780 [loop] ? __lock_acquire+0x3a0/0x1dc0 ? update_dl_rq_load_avg+0x152/0x360 ? lock_is_held_type+0xa5/0x120 ? find_held_lock.constprop.0+0x2b/0x80 block_ioctl+0x3f/0x50 __x64_sys_ioctl+0x83/0xb0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f645884de6b
Usually the uuid_mutex exists to protect the fs_devices that map together all of the devices that match a specific uuid. In rm_device we're messing with the uuid of a device, so it makes sense to protect that here.
However in doing that it pulls in a whole host of lockdep dependencies, as we call mnt_may_write() on the sb before we grab the uuid_mutex, thus we end up with the dependency chain under the uuid_mutex being added under the normal sb write dependency chain, which causes problems with loop devices.
We don't need the uuid mutex here however. If we call btrfs_scan_one_device() before we scratch the super block we will find the fs_devices and not find the device itself and return EBUSY because the fs_devices is open. If we call it after the scratch happens it will not appear to be a valid btrfs file system.
We do not need to worry about other fs_devices modifying operations here because we're protected by the exclusive operations locking.
So drop the uuid_mutex here in order to fix the lockdep splat.
A more detailed explanation from the discussion:
We are worried about rm and scan racing with each other, before this change we'll zero the device out under the UUID mutex so when scan does run it'll make sure that it can go through the whole device scan thing without rm messing with us.
We aren't worried if the scratch happens first, because the result is we don't think this is a btrfs device and we bail out.
The only case we are concerned with is we scratch _after_ scan is able to read the superblock and gets a seemingly valid super block, so lets consider this case.
Scan will call device_list_add() with the device we're removing. We'll call find_fsid_with_metadata_uuid() and get our fs_devices for this UUID. At this point we lock the fs_devices->device_list_mutex. This is what protects us in this case, but we have two cases here.
1. We aren't to the device removal part of the RM. We found our device, and device name matches our path, we go down and we set total_devices to our super number of devices, which doesn't affect anything because we haven't done the remove yet.
2. We are past the device removal part, which is protected by the device_list_mutex. Scan doesn't find the device, it goes down and does the
if (fs_devices->opened) return -EBUSY;
check and we bail out.
Nothing about this situation is ideal, but the lockdep splat is real, and the fix is safe, tho admittedly a bit scary looking.
Reviewed-by: Anand Jain anand.jain@oracle.com Signed-off-by: Josef Bacik josef@toxicpanda.com Reviewed-by: David Sterba dsterba@suse.com [ copy more from the discussion ] Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/volumes.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 56252cc5c5f7b..6afebc5b10c84 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2083,8 +2083,11 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, u64 num_devices; int ret = 0;
- mutex_lock(&uuid_mutex); - + /* + * The device list in fs_devices is accessed without locks (neither + * uuid_mutex nor device_list_mutex) as it won't change on a mounted + * filesystem and another device rm cannot run. + */ num_devices = btrfs_num_devices(fs_info);
ret = btrfs_check_raid_min_devices(fs_info, num_devices - 1); @@ -2128,11 +2131,9 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, mutex_unlock(&fs_info->chunk_mutex); }
- mutex_unlock(&uuid_mutex); ret = btrfs_shrink_device(device, 0); if (!ret) btrfs_reada_remove_dev(device); - mutex_lock(&uuid_mutex); if (ret) goto error_undo;
@@ -2219,7 +2220,6 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, }
out: - mutex_unlock(&uuid_mutex); return ret;
error_undo:
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit ca9b8f56ec089d3a436050afefd17b7237301f47 ]
Fix the missing clk_disable_unprepare() before return from bcm_qspi_probe() in the error handling case.
Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211018073413.2029081-1-yangyingliang@huawei.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-bcm-qspi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 3043677ba2226..ea1865c08fc22 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -1460,7 +1460,7 @@ int bcm_qspi_probe(struct platform_device *pdev, &qspi->dev_ids[val]); if (ret < 0) { dev_err(&pdev->dev, "IRQ %s not found\n", name); - goto qspi_probe_err; + goto qspi_unprepare_err; }
qspi->dev_ids[val].dev = qspi; @@ -1475,7 +1475,7 @@ int bcm_qspi_probe(struct platform_device *pdev, if (!num_ints) { dev_err(&pdev->dev, "no IRQs registered, cannot init driver\n"); ret = -EINVAL; - goto qspi_probe_err; + goto qspi_unprepare_err; }
bcm_qspi_hw_init(qspi); @@ -1499,6 +1499,7 @@ int bcm_qspi_probe(struct platform_device *pdev,
qspi_reg_err: bcm_qspi_hw_uninit(qspi); +qspi_unprepare_err: clk_disable_unprepare(qspi->clk); qspi_probe_err: kfree(qspi->dev_ids);
From: Loic Poulain loic.poulain@linaro.org
[ Upstream commit 8a27ca39478270e07baf9c09aa0c99709769ba03 ]
For packets originating from hardware scan, the channel and band is included in the buffer descriptor (bd->rf_band & bd->rx_ch).
For 2Ghz band the channel value is directly reported in the 4-bit rx_ch field. For 5Ghz band, the rx_ch field contains a mapping index (given the 4-bit limitation).
The reserved0 value field is also used to extend 4-bit mapping to 5-bit mapping to support more than 16 5Ghz channels.
This change adds correct reporting of the frequency/band, that is used in scan mechanism. And is required for 5Ghz hardware scan support.
Signed-off-by: Loic Poulain loic.poulain@linaro.org Tested-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1634554678-7993-1-git-send-email-loic.poulain@lina... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 23 +++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/txrx.h | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index eaf2410e39647..c0f51fa13dfa1 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -31,6 +31,13 @@ struct wcn36xx_rate { enum rate_info_bw bw; };
+/* Buffer descriptor rx_ch field is limited to 5-bit (4+1), a mapping is used + * for 11A Channels. + */ +static const u8 ab_rx_ch_map[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, + 108, 112, 116, 120, 124, 128, 132, 136, 140, + 149, 153, 157, 161, 165, 144 }; + static const struct wcn36xx_rate wcn36xx_rate_table[] = { /* 11b rates */ { 10, 0, RX_ENC_LEGACY, 0, RATE_INFO_BW_20 }, @@ -291,6 +298,22 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) ieee80211_is_probe_resp(hdr->frame_control)) status.boottime_ns = ktime_get_boottime_ns();
+ if (bd->scan_learn) { + /* If packet originates from hardware scanning, extract the + * band/channel from bd descriptor. + */ + u8 hwch = (bd->reserved0 << 4) + bd->rx_ch; + + if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) { + status.band = NL80211_BAND_5GHZ; + status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1], + status.band); + } else { + status.band = NL80211_BAND_2GHZ; + status.freq = ieee80211_channel_to_frequency(hwch, status.band); + } + } + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
if (ieee80211_is_beacon(hdr->frame_control)) { diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.h b/drivers/net/wireless/ath/wcn36xx/txrx.h index 032216e82b2be..b54311ffde9c5 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.h +++ b/drivers/net/wireless/ath/wcn36xx/txrx.h @@ -110,7 +110,8 @@ struct wcn36xx_rx_bd { /* 0x44 */ u32 exp_seq_num:12; u32 cur_seq_num:12; - u32 fr_type_subtype:8; + u32 rf_band:2; + u32 fr_type_subtype:6;
/* 0x48 */ u32 msdu_size:16;
From: Loic Poulain loic.poulain@linaro.org
[ Upstream commit df0697801d8aa2eebfe7f0b7388879639f8fe7cc ]
If the system is resumed because of an incoming packet, the wcn36xx RX interrupts is fired before actual resuming of the wireless/mac80211 stack, causing any received packets to be simply dropped. E.g. a ping request causes a system resume, but is dropped and so never forwarded to the IP stack.
This change fixes that, disabling DMA interrupts on suspend to no pass packets until mac80211 is resumed and ready to handle them.
Note that it's not incompatible with RX irq wake.
Signed-off-by: Loic Poulain loic.poulain@linaro.org Reviewed-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1635150496-19290-1-git-send-email-loic.poulain@lin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index bd1c83aeea606..39d86e3031bd7 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1115,6 +1115,13 @@ static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow) goto out; ret = wcn36xx_smd_wlan_host_suspend_ind(wcn); } + + /* Disable IRQ, we don't want to handle any packet before mac80211 is + * resumed and ready to receive packets. + */ + disable_irq(wcn->tx_irq); + disable_irq(wcn->rx_irq); + out: mutex_unlock(&wcn->conf_mutex); return ret; @@ -1137,6 +1144,10 @@ static int wcn36xx_resume(struct ieee80211_hw *hw) wcn36xx_smd_ipv6_ns_offload(wcn, vif, false); wcn36xx_smd_arp_offload(wcn, vif, false); } + + enable_irq(wcn->tx_irq); + enable_irq(wcn->rx_irq); + mutex_unlock(&wcn->conf_mutex);
return 0;
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit 43ea9bd84f27d06482cc823d9749cc9dd2993bc8 ]
Firmware link offload monitoring can be made to work in 3/4 cases by switching on firmware feature bit WLANACTIVE_OFFLOAD
- Secure power-save on - Secure power-save off - Open power-save on
However, with an open AP if we switch off power-saving - thus never entering Beacon Mode Power Save - BMPS, firmware never forwards loss of beacon upwards.
We had hoped that WLANACTIVE_OFFLOAD and some fixes for sequence numbers would unblock this but, it hasn't and further investigation is required.
Its possible to have a complete set of Secure power-save on/off and Open power-save on/off provided we use Linux' link monitoring mechanism.
While we debug the Open AP failure we need to fix upstream.
This reverts commit c973fdad79f6eaf247d48b5fc77733e989eb01e1.
Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211025093037.3966022-2-bryan.odonoghue@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/main.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 39d86e3031bd7..28d6251ad77a6 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1341,7 +1341,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL); ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS); ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS); - ieee80211_hw_set(wcn->hw, CONNECTION_MONITOR);
wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) |
From: 王贇 yun.wang@linux.alibaba.com
[ Upstream commit d33cc657372366a8959f099c619a208b4c5dc664 ]
With CONFIG_DEBUG_PREEMPT we observed reports like:
BUG: using smp_processor_id() in preemptible caller is perf_ftrace_function_call+0x6f/0x2e0 CPU: 1 PID: 680 Comm: a.out Not tainted Call Trace: <TASK> dump_stack_lvl+0x8d/0xcf check_preemption_disabled+0x104/0x110 ? optimize_nops.isra.7+0x230/0x230 ? text_poke_bp_batch+0x9f/0x310 perf_ftrace_function_call+0x6f/0x2e0 ... __text_poke+0x5/0x620 text_poke_bp_batch+0x9f/0x310
This telling us the CPU could be changed after task is preempted, and the checking on CPU before preemption will be invalid.
Since now ftrace_test_recursion_trylock() will help to disable the preemption, this patch just do the checking after trylock() to address the issue.
Link: https://lkml.kernel.org/r/54880691-5fe2-33e7-d12f-1fa6136f5183@linux.alibaba...
CC: Steven Rostedt rostedt@goodmis.org Cc: Guo Ren guoren@kernel.org Cc: Ingo Molnar mingo@redhat.com Cc: "James E.J. Bottomley" James.Bottomley@HansenPartnership.com Cc: Helge Deller deller@gmx.de Cc: Michael Ellerman mpe@ellerman.id.au Cc: Benjamin Herrenschmidt benh@kernel.crashing.org Cc: Paul Mackerras paulus@samba.org Cc: Paul Walmsley paul.walmsley@sifive.com Cc: Palmer Dabbelt palmer@dabbelt.com Cc: Albert Ou aou@eecs.berkeley.edu Cc: Thomas Gleixner tglx@linutronix.de Cc: Borislav Petkov bp@alien8.de Cc: "H. Peter Anvin" hpa@zytor.com Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Jiri Kosina jikos@kernel.org Cc: Miroslav Benes mbenes@suse.cz Cc: Petr Mladek pmladek@suse.com Cc: Joe Lawrence joe.lawrence@redhat.com Cc: Masami Hiramatsu mhiramat@kernel.org Cc: "Peter Zijlstra (Intel)" peterz@infradead.org Cc: Nicholas Piggin npiggin@gmail.com Cc: Jisheng Zhang jszhang@kernel.org Reported-by: Abaci abaci@linux.alibaba.com Signed-off-by: Michael Wang yun.wang@linux.alibaba.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/trace_event_perf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 6aed10e2f7ce0..fba8cb77a73af 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -441,13 +441,13 @@ perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip, if (!rcu_is_watching()) return;
- if ((unsigned long)ops->private != smp_processor_id()) - return; - bit = ftrace_test_recursion_trylock(ip, parent_ip); if (bit < 0) return;
+ if ((unsigned long)ops->private != smp_processor_id()) + goto out; + event = container_of(ops, struct perf_event, ftrace_ops);
/*
From: Eric Dumazet edumazet@google.com
[ Upstream commit 9dfc685e0262d4c5e44e13302f89841fa75173ca ]
syzbot reported data-races in inet_getname() multiple times, it is time we fix this instead of pretending applications should not trigger them.
getsockname() and getpeername() are not really considered fast path.
v2: added the missing BPF_CGROUP_RUN_SA_PROG() declaration needed when CONFIG_CGROUP_BPF=n, as reported by kernel test robot lkp@intel.com
syzbot typical report:
BUG: KCSAN: data-race in __inet_hash_connect / inet_getname
write to 0xffff888136d66cf8 of 2 bytes by task 14374 on cpu 1: __inet_hash_connect+0x7ec/0x950 net/ipv4/inet_hashtables.c:831 inet_hash_connect+0x85/0x90 net/ipv4/inet_hashtables.c:853 tcp_v4_connect+0x782/0xbb0 net/ipv4/tcp_ipv4.c:275 __inet_stream_connect+0x156/0x6e0 net/ipv4/af_inet.c:664 inet_stream_connect+0x44/0x70 net/ipv4/af_inet.c:728 __sys_connect_file net/socket.c:1896 [inline] __sys_connect+0x254/0x290 net/socket.c:1913 __do_sys_connect net/socket.c:1923 [inline] __se_sys_connect net/socket.c:1920 [inline] __x64_sys_connect+0x3d/0x50 net/socket.c:1920 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xa0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
read to 0xffff888136d66cf8 of 2 bytes by task 14408 on cpu 0: inet_getname+0x11f/0x170 net/ipv4/af_inet.c:790 __sys_getsockname+0x11d/0x1b0 net/socket.c:1946 __do_sys_getsockname net/socket.c:1961 [inline] __se_sys_getsockname net/socket.c:1958 [inline] __x64_sys_getsockname+0x3e/0x50 net/socket.c:1958 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x44/0xa0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae
value changed: 0x0000 -> 0xdee0
Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 14408 Comm: syz-executor.3 Not tainted 5.15.0-rc3-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Link: https://lore.kernel.org/r/20211026213014.3026708-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/bpf-cgroup.h | 1 + net/ipv4/af_inet.c | 16 +++++++++------- net/ipv6/af_inet6.c | 21 +++++++++++---------- 3 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index 2746fd8042162..3536ab432b30c 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h @@ -517,6 +517,7 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
#define cgroup_bpf_enabled(atype) (0) #define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, atype, t_ctx) ({ 0; }) +#define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, atype) ({ 0; }) #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0) #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; }) #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; }) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 1d816a5fd3eb9..64062b7ce61df 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -773,26 +773,28 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr, DECLARE_SOCKADDR(struct sockaddr_in *, sin, uaddr);
sin->sin_family = AF_INET; + lock_sock(sk); if (peer) { if (!inet->inet_dport || (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) && - peer == 1)) + peer == 1)) { + release_sock(sk); return -ENOTCONN; + } sin->sin_port = inet->inet_dport; sin->sin_addr.s_addr = inet->inet_daddr; - BPF_CGROUP_RUN_SA_PROG_LOCK(sk, (struct sockaddr *)sin, - CGROUP_INET4_GETPEERNAME, - NULL); + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + CGROUP_INET4_GETPEERNAME); } else { __be32 addr = inet->inet_rcv_saddr; if (!addr) addr = inet->inet_saddr; sin->sin_port = inet->inet_sport; sin->sin_addr.s_addr = addr; - BPF_CGROUP_RUN_SA_PROG_LOCK(sk, (struct sockaddr *)sin, - CGROUP_INET4_GETSOCKNAME, - NULL); + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + CGROUP_INET4_GETSOCKNAME); } + release_sock(sk); memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); return sizeof(*sin); } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index b5878bb8e419d..0c4da163535ad 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -521,31 +521,32 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, sin->sin6_family = AF_INET6; sin->sin6_flowinfo = 0; sin->sin6_scope_id = 0; + lock_sock(sk); if (peer) { - if (!inet->inet_dport) - return -ENOTCONN; - if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) && - peer == 1) + if (!inet->inet_dport || + (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) && + peer == 1)) { + release_sock(sk); return -ENOTCONN; + } sin->sin6_port = inet->inet_dport; sin->sin6_addr = sk->sk_v6_daddr; if (np->sndflow) sin->sin6_flowinfo = np->flow_label; - BPF_CGROUP_RUN_SA_PROG_LOCK(sk, (struct sockaddr *)sin, - CGROUP_INET6_GETPEERNAME, - NULL); + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + CGROUP_INET6_GETPEERNAME); } else { if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) sin->sin6_addr = np->saddr; else sin->sin6_addr = sk->sk_v6_rcv_saddr; sin->sin6_port = inet->inet_sport; - BPF_CGROUP_RUN_SA_PROG_LOCK(sk, (struct sockaddr *)sin, - CGROUP_INET6_GETSOCKNAME, - NULL); + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + CGROUP_INET6_GETSOCKNAME); } sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr, sk->sk_bound_dev_if); + release_sock(sk); return sizeof(*sin); } EXPORT_SYMBOL(inet6_getname);
From: Vitaly Kuznetsov vkuznets@redhat.com
[ Upstream commit 285f68afa8b20f752b0b7194d54980b5e0e27b75 ]
The following issue is observed with CONFIG_DEBUG_PREEMPT when KVM loads:
KVM: vmx: using Hyper-V Enlightened VMCS BUG: using smp_processor_id() in preemptible [00000000] code: systemd-udevd/488 caller is set_hv_tscchange_cb+0x16/0x80 CPU: 1 PID: 488 Comm: systemd-udevd Not tainted 5.15.0-rc5+ #396 Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.0 12/17/2019 Call Trace: dump_stack_lvl+0x6a/0x9a check_preemption_disabled+0xde/0xe0 ? kvm_gen_update_masterclock+0xd0/0xd0 [kvm] set_hv_tscchange_cb+0x16/0x80 kvm_arch_init+0x23f/0x290 [kvm] kvm_init+0x30/0x310 [kvm] vmx_init+0xaf/0x134 [kvm_intel] ...
set_hv_tscchange_cb() can get preempted in between acquiring smp_processor_id() and writing to HV_X64_MSR_REENLIGHTENMENT_CONTROL. This is not an issue by itself: HV_X64_MSR_REENLIGHTENMENT_CONTROL is a partition-wide MSR and it doesn't matter which particular CPU will be used to receive reenlightenment notifications. The only real problem can (in theory) be observed if the CPU whose id was acquired with smp_processor_id() goes offline before we manage to write to the MSR, the logic in hv_cpu_die() won't be able to reassign it correctly.
Reported-by: Michael Kelley mikelley@microsoft.com Signed-off-by: Vitaly Kuznetsov vkuznets@redhat.com Link: https://lore.kernel.org/r/20211012155005.1613352-1-vkuznets@redhat.com Signed-off-by: Wei Liu wei.liu@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/hyperv/hv_init.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 708a2712a516d..179fc173104d7 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -139,7 +139,6 @@ void set_hv_tscchange_cb(void (*cb)(void)) struct hv_reenlightenment_control re_ctrl = { .vector = HYPERV_REENLIGHTENMENT_VECTOR, .enabled = 1, - .target_vp = hv_vp_index[smp_processor_id()] }; struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1};
@@ -153,8 +152,12 @@ void set_hv_tscchange_cb(void (*cb)(void)) /* Make sure callback is registered before we write to MSRs */ wmb();
+ re_ctrl.target_vp = hv_vp_index[get_cpu()]; + wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl)); wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl)); + + put_cpu(); } EXPORT_SYMBOL_GPL(set_hv_tscchange_cb);
From: Anson Jacob Anson.Jacob@amd.com
[ Upstream commit bc39a69a2ac484e6575a958567c162ef56c9f278 ]
Limit when FPU is enabled to only functions that does FPU operations for dcn20_resource_construct, which gets called during driver initialization.
Enabling FPU operation disables preemption. Sleeping functions(mutex (un)lock, memory allocation using GFP_KERNEL, etc.) should not be called when preemption is disabled.
Fixes the following case caught by enabling CONFIG_DEBUG_ATOMIC_SLEEP in kernel config [ 1.338434] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:281 [ 1.347395] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 197, name: systemd-udevd [ 1.356356] CPU: 7 PID: 197 Comm: systemd-udevd Not tainted 5.13.0+ #3 [ 1.356358] Hardware name: System manufacturer System Product Name/PRIME X570-PRO, BIOS 3405 02/01/2021 [ 1.356360] Call Trace: [ 1.356361] dump_stack+0x6b/0x86 [ 1.356366] ___might_sleep.cold+0x87/0x98 [ 1.356370] __might_sleep+0x4b/0x80 [ 1.356372] mutex_lock+0x21/0x50 [ 1.356376] smu_get_uclk_dpm_states+0x3f/0x80 [amdgpu] [ 1.356538] pp_nv_get_uclk_dpm_states+0x35/0x50 [amdgpu] [ 1.356711] init_soc_bounding_box+0xf9/0x210 [amdgpu] [ 1.356892] ? create_object+0x20d/0x340 [ 1.356897] ? dcn20_resource_construct+0x46f/0xd30 [amdgpu] [ 1.357077] dcn20_resource_construct+0x4b1/0xd30 [amdgpu] ...
Tested on: 5700XT (NAVI10 0x1002:0x731F 0x1DA2:0xE410 0xC1)
Cc: Christian König christian.koenig@amd.com Cc: Hersen Wu hersenxs.wu@amd.com Cc: Anson Jacob Anson.Jacob@amd.com Cc: Harry Wentland harry.wentland@amd.com
Reviewed-by: Rodrigo Siqueira Rodrigo.Siqueira@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Acked-by: Agustin Gutierrez agustin.gutierrez@amd.com Signed-off-by: Anson Jacob Anson.Jacob@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index e3e01b17c164e..f2f258e70f9da 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -3668,16 +3668,22 @@ static bool init_soc_bounding_box(struct dc *dc, clock_limits_available = (status == PP_SMU_RESULT_OK); }
- if (clock_limits_available && uclk_states_available && num_states) + if (clock_limits_available && uclk_states_available && num_states) { + DC_FP_START(); dcn20_update_bounding_box(dc, loaded_bb, &max_clocks, uclk_states, num_states); - else if (clock_limits_available) + DC_FP_END(); + } else if (clock_limits_available) { + DC_FP_START(); dcn20_cap_soc_clocks(loaded_bb, max_clocks); + DC_FP_END(); + } }
loaded_ip->max_num_otg = pool->base.res_cap->num_timing_generator; loaded_ip->max_num_dpp = pool->base.pipe_count; + DC_FP_START(); dcn20_patch_bounding_box(dc, loaded_bb); - + DC_FP_END(); return true; }
@@ -3697,8 +3703,6 @@ static bool dcn20_resource_construct( enum dml_project dml_project_version = get_dml_project_version(ctx->asic_id.hw_internal_rev);
- DC_FP_START(); - ctx->dc_bios->regs = &bios_regs; pool->base.funcs = &dcn20_res_pool_funcs;
@@ -4047,12 +4051,10 @@ static bool dcn20_resource_construct( pool->base.oem_device = NULL; }
- DC_FP_END(); return true;
create_fail:
- DC_FP_END(); dcn20_resource_destruct(pool);
return false;
From: Shuah Khan skhan@linuxfoundation.org
[ Upstream commit f35dcaa0a8a29188ed61083d153df1454cf89d08 ]
close_range() test type conflicts with close_range() library call in x86_64-linux-gnu/bits/unistd_ext.h. Fix it by changing the name to core_close_range().
gcc -g -I../../../../usr/include/ close_range_test.c -o ../tools/testing/selftests/core/close_range_test In file included from close_range_test.c:16: close_range_test.c:57:6: error: conflicting types for ‘close_range’; have ‘void(struct __test_metadata *)’ 57 | TEST(close_range) | ^~~~~~~~~~~ ../kselftest_harness.h:181:21: note: in definition of macro ‘__TEST_IMPL’ 181 | static void test_name(struct __test_metadata *_metadata); \ | ^~~~~~~~~ close_range_test.c:57:1: note: in expansion of macro ‘TEST’ 57 | TEST(close_range) | ^~~~ In file included from /usr/include/unistd.h:1204, from close_range_test.c:13: /usr/include/x86_64-linux-gnu/bits/unistd_ext.h:56:12: note: previous declaration of ‘close_range’ with type ‘int(unsigned int, unsigned int, int)’ 56 | extern int close_range (unsigned int __fd, unsigned int __max_fd, | ^~~~~~~~~~~
Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/core/close_range_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/core/close_range_test.c b/tools/testing/selftests/core/close_range_test.c index 73eb29c916d1b..aa7d13d91963f 100644 --- a/tools/testing/selftests/core/close_range_test.c +++ b/tools/testing/selftests/core/close_range_test.c @@ -54,7 +54,7 @@ static inline int sys_close_range(unsigned int fd, unsigned int max_fd, #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #endif
-TEST(close_range) +TEST(core_close_range) { int i, ret; int open_fds[101];
From: Stephane Eranian eranian@google.com
[ Upstream commit 2de71ee153efa93099d2ab864acffeec70a8dcd5 ]
This patch fixes the encoding for INST_RETIRED.PREC_DIST as published by Intel (download.01.org/perfmon/) for Icelake. The official encoding is event code 0x00 umask 0x1, a change from Skylake where it was code 0xc0 umask 0x1.
With this patch applied it is possible to run: $ perf record -a -e cpu/event=0x00,umask=0x1/pp .....
Whereas before this would fail.
To avoid problems with tools which may use the old code, we maintain the old encoding for Icelake.
Signed-off-by: Stephane Eranian eranian@google.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20211014001214.2680534-1-eranian@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/core.c | 5 +++-- arch/x86/events/intel/ds.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 9a044438072ba..bc3f97f834011 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -243,7 +243,8 @@ static struct extra_reg intel_skl_extra_regs[] __read_mostly = {
static struct event_constraint intel_icl_event_constraints[] = { FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ - FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ + FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* old INST_RETIRED.PREC_DIST */ + FIXED_EVENT_CONSTRAINT(0x0100, 0), /* INST_RETIRED.PREC_DIST */ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ @@ -288,7 +289,7 @@ static struct extra_reg intel_spr_extra_regs[] __read_mostly = {
static struct event_constraint intel_spr_event_constraints[] = { FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ - FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ + FIXED_EVENT_CONSTRAINT(0x0100, 0), /* INST_RETIRED.PREC_DIST */ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 8647713276a73..4dbb55a43dad2 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -923,7 +923,8 @@ struct event_constraint intel_skl_pebs_event_constraints[] = { };
struct event_constraint intel_icl_pebs_event_constraints[] = { - INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */ + INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x100000000ULL), /* old INST_RETIRED.PREC_DIST */ + INTEL_FLAGS_UEVENT_CONSTRAINT(0x0100, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), /* SLOTS */
INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ @@ -943,7 +944,7 @@ struct event_constraint intel_icl_pebs_event_constraints[] = { };
struct event_constraint intel_spr_pebs_event_constraints[] = { - INTEL_FLAGS_UEVENT_CONSTRAINT(0x1c0, 0x100000000ULL), + INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL), /* INST_RETIRED.PREC_DIST */ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),
INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe),
From: Sven Schnelle svens@stackframe.org
[ Upstream commit 1030d681319b43869e0d5b568b9d0226652d1a6f ]
I've got the following splat after enabling preemption:
[ 3.724721] BUG: using __this_cpu_add() in preemptible [00000000] code: swapper/0/1 [ 3.734630] caller is __this_cpu_preempt_check+0x38/0x50 [ 3.740635] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.0-rc4-64bit+ #324 [ 3.744605] Hardware name: 9000/785/C8000 [ 3.744605] Backtrace: [ 3.744605] [<00000000401d9d58>] show_stack+0x74/0xb0 [ 3.744605] [<0000000040c27bd4>] dump_stack_lvl+0x10c/0x188 [ 3.744605] [<0000000040c27c84>] dump_stack+0x34/0x48 [ 3.744605] [<0000000040c33438>] check_preemption_disabled+0x178/0x1b0 [ 3.744605] [<0000000040c334f8>] __this_cpu_preempt_check+0x38/0x50 [ 3.744605] [<00000000401d632c>] flush_tlb_all+0x58/0x2e0 [ 3.744605] [<00000000401075c0>] 0x401075c0 [ 3.744605] [<000000004010b8fc>] 0x4010b8fc [ 3.744605] [<00000000401080fc>] 0x401080fc [ 3.744605] [<00000000401d5224>] do_one_initcall+0x128/0x378 [ 3.744605] [<0000000040102de8>] 0x40102de8 [ 3.744605] [<0000000040c33864>] kernel_init+0x60/0x3a8 [ 3.744605] [<00000000401d1020>] ret_from_kernel_thread+0x20/0x28 [ 3.744605]
Fix this by moving the __inc_irq_stat() into the locked section.
Signed-off-by: Sven Schnelle svens@stackframe.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/parisc/mm/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 3f7d6d5b56ac8..65f50f072a87b 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -842,9 +842,9 @@ void flush_tlb_all(void) { int do_recycle;
- __inc_irq_stat(irq_tlb_count); do_recycle = 0; spin_lock(&sid_lock); + __inc_irq_stat(irq_tlb_count); if (dirty_space_ids > RECYCLE_THRESHOLD) { BUG_ON(recycle_inuse); /* FIXME: Use a semaphore/wait queue here */ get_dirty_sids(&recycle_ndirty,recycle_dirty_array); @@ -863,8 +863,8 @@ void flush_tlb_all(void) #else void flush_tlb_all(void) { - __inc_irq_stat(irq_tlb_count); spin_lock(&sid_lock); + __inc_irq_stat(irq_tlb_count); flush_tlb_all_local(NULL); recycle_sids(); spin_unlock(&sid_lock);
From: Helge Deller deller@gmx.de
[ Upstream commit 9cc2fa4f4a92ccc6760d764e7341be46ee8aaaa1 ]
The function end_of_stack() returns a pointer to the last entry of a stack. For architectures like parisc where the stack grows upwards return the pointer to the highest address in the stack.
Without this change I faced a crash on parisc, because the stackleak functionality wrote STACKLEAK_POISON to the lowest address and thus overwrote the first 4 bytes of the task_struct which included the TIF_FLAGS.
Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched/task_stack.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/linux/sched/task_stack.h b/include/linux/sched/task_stack.h index 2413427e439c7..d10150587d819 100644 --- a/include/linux/sched/task_stack.h +++ b/include/linux/sched/task_stack.h @@ -25,7 +25,11 @@ static inline void *task_stack_page(const struct task_struct *task)
static inline unsigned long *end_of_stack(const struct task_struct *task) { +#ifdef CONFIG_STACK_GROWSUP + return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1; +#else return task->stack; +#endif }
#elif !defined(__HAVE_THREAD_FUNCTIONS)
From: Gao Xiang hsiangkao@linux.alibaba.com
[ Upstream commit a0961f351d82d43ab0b845304caa235dfe249ae9 ]
syzbot reported a WARNING [1] due to corrupted compressed data.
As Dmitry said, "If this is not a kernel bug, then the code should not use WARN. WARN if for kernel bugs and is recognized as such by all testing systems and humans."
[1] https://lore.kernel.org/r/000000000000b3586105cf0ff45e@google.com
Link: https://lore.kernel.org/r/20211025074311.130395-1-hsiangkao@linux.alibaba.co... Cc: Dmitry Vyukov dvyukov@google.com Reviewed-by: Chao Yu chao@kernel.org Reported-by: syzbot+d8aaffc3719597e8cfb4@syzkaller.appspotmail.com Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/erofs/decompressor.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c index a5bc4b1b7813e..ad3f31380e6b2 100644 --- a/fs/erofs/decompressor.c +++ b/fs/erofs/decompressor.c @@ -233,7 +233,6 @@ static int z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq, u8 *out) erofs_err(rq->sb, "failed to decompress %d in[%u, %u] out[%u]", ret, rq->inputsize, inputmargin, rq->outputsize);
- WARN_ON(1); print_hex_dump(KERN_DEBUG, "[ in]: ", DUMP_PREFIX_OFFSET, 16, 1, src + inputmargin, rq->inputsize, true); print_hex_dump(KERN_DEBUG, "[out]: ", DUMP_PREFIX_OFFSET,
From: Sven Schnelle svens@stackframe.org
[ Upstream commit 8e0ba125c2bf1030af3267058019ba86da96863f ]
With 64 bit kernels unwind_special() is not working because it compares the pc to the address of the function descriptor. Add a helper function that compares pc with the dereferenced address. This fixes all of the backtraces on my c8000. Without this changes, a lot of backtraces are missing in kdb or the show-all-tasks command from /proc/sysrq-trigger.
Signed-off-by: Sven Schnelle svens@stackframe.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/parisc/kernel/unwind.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 87ae476d1c4f5..86a57fb0e6fae 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -21,6 +21,8 @@ #include <asm/ptrace.h>
#include <asm/unwind.h> +#include <asm/switch_to.h> +#include <asm/sections.h>
/* #define DEBUG 1 */ #ifdef DEBUG @@ -203,6 +205,11 @@ int __init unwind_init(void) return 0; }
+static bool pc_is_kernel_fn(unsigned long pc, void *fn) +{ + return (unsigned long)dereference_kernel_function_descriptor(fn) == pc; +} + static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size) { /* @@ -221,7 +228,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int extern void * const _call_on_stack; #endif /* CONFIG_IRQSTACKS */
- if (pc == (unsigned long) &handle_interruption) { + if (pc_is_kernel_fn(pc, handle_interruption)) { struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); dbg("Unwinding through handle_interruption()\n"); info->prev_sp = regs->gr[30]; @@ -229,13 +236,13 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int return 1; }
- if (pc == (unsigned long) &ret_from_kernel_thread || - pc == (unsigned long) &syscall_exit) { + if (pc_is_kernel_fn(pc, ret_from_kernel_thread) || + pc_is_kernel_fn(pc, syscall_exit)) { info->prev_sp = info->prev_ip = 0; return 1; }
- if (pc == (unsigned long) &intr_return) { + if (pc_is_kernel_fn(pc, intr_return)) { struct pt_regs *regs;
dbg("Found intr_return()\n"); @@ -246,20 +253,20 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int return 1; }
- if (pc == (unsigned long) &_switch_to_ret) { + if (pc_is_kernel_fn(pc, _switch_to) || + pc_is_kernel_fn(pc, _switch_to_ret)) { info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); return 1; }
#ifdef CONFIG_IRQSTACKS - if (pc == (unsigned long) &_call_on_stack) { + if (pc_is_kernel_fn(pc, _call_on_stack)) { info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); return 1; } #endif - return 0; }
From: Sven Schnelle svens@stackframe.org
[ Upstream commit 66e29fcda1824f0427966fbee2bd2c85bf362c82 ]
With idle polling, IPIs are not sent when a CPU idle, but queued and run later from do_idle(). The default kgdb_call_nmi_hook() implementation gets the pointer to struct pt_regs from get_irq_reqs(), which doesn't work in that case because it was not called from the IPI interrupt handler. Fix it by defining our own kgdb_roundup() function which sents an IPI_ENTER_KGDB. When that IPI is received on the target CPU kgdb_nmicallback() is called.
Signed-off-by: Sven Schnelle svens@stackframe.org Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/parisc/kernel/smp.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 1405b603b91b6..cf92ece20b757 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -29,6 +29,7 @@ #include <linux/bitops.h> #include <linux/ftrace.h> #include <linux/cpu.h> +#include <linux/kgdb.h>
#include <linux/atomic.h> #include <asm/current.h> @@ -69,7 +70,10 @@ enum ipi_message_type { IPI_CALL_FUNC, IPI_CPU_START, IPI_CPU_STOP, - IPI_CPU_TEST + IPI_CPU_TEST, +#ifdef CONFIG_KGDB + IPI_ENTER_KGDB, +#endif };
@@ -167,7 +171,12 @@ ipi_interrupt(int irq, void *dev_id) case IPI_CPU_TEST: smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu); break; - +#ifdef CONFIG_KGDB + case IPI_ENTER_KGDB: + smp_debug(100, KERN_DEBUG "CPU%d ENTER_KGDB\n", this_cpu); + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); + break; +#endif default: printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", this_cpu, which); @@ -226,6 +235,12 @@ send_IPI_allbutself(enum ipi_message_type op) } }
+#ifdef CONFIG_KGDB +void kgdb_roundup_cpus(void) +{ + send_IPI_allbutself(IPI_ENTER_KGDB); +} +#endif
inline void smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); }
From: Pablo Neira Ayuso pablo@netfilter.org
[ Upstream commit b7b1d02fc43925a4d569ec221715db2dfa1ce4f5 ]
The internal stream state sets the timeout to 120 seconds 2 seconds after the creation of the flow, attach this internal stream state to the IPS_ASSURED flag for consistent event reporting.
Before this patch:
[NEW] udp 17 30 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 [UNREPLIED] src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [UPDATE] udp 17 30 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [UPDATE] udp 17 30 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [ASSURED] [DESTROY] udp 17 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [ASSURED]
Note IPS_ASSURED for the flow not yet in the internal stream state.
after this update:
[NEW] udp 17 30 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 [UNREPLIED] src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [UPDATE] udp 17 30 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [UPDATE] udp 17 120 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [ASSURED] [DESTROY] udp 17 src=10.246.11.13 dst=216.239.35.0 sport=37282 dport=123 src=216.239.35.0 dst=10.246.11.13 sport=123 dport=37282 [ASSURED]
Before this patch, short-lived UDP flows never entered IPS_ASSURED, so they were already candidate flow to be deleted by early_drop under stress.
Before this patch, IPS_ASSURED is set on regardless the internal stream state, attach this internal stream state to IPS_ASSURED.
packet #1 (original direction) enters NEW state packet #2 (reply direction) enters ESTABLISHED state, sets on IPS_SEEN_REPLY paclet #3 (any direction) sets on IPS_ASSURED (if 2 seconds since the creation has passed by).
Reported-by: Maciej Żenczykowski zenczykowski@gmail.com Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nf_conntrack_proto_udp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index f8e3c0d2602f6..3b516cffc779b 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c @@ -104,10 +104,13 @@ int nf_conntrack_udp_packet(struct nf_conn *ct, */ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { unsigned long extra = timeouts[UDP_CT_UNREPLIED]; + bool stream = false;
/* Still active after two seconds? Extend timeout. */ - if (time_after(jiffies, ct->proto.udp.stream_ts)) + if (time_after(jiffies, ct->proto.udp.stream_ts)) { extra = timeouts[UDP_CT_REPLIED]; + stream = true; + }
nf_ct_refresh_acct(ct, ctinfo, skb, extra);
@@ -116,7 +119,7 @@ int nf_conntrack_udp_packet(struct nf_conn *ct, return NF_ACCEPT;
/* Also, more likely to be important, and not a probe */ - if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) + if (stream && !test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) nf_conntrack_event_cache(IPCT_ASSURED, ct); } else { nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[UDP_CT_UNREPLIED]);
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 0133c20480b14820d43c37c0e9502da4bffcad3a ]
After most recent nightly Clang update strobemeta selftests started failing with the following error (relevant portion of assembly included):
1624: (85) call bpf_probe_read_user_str#114 1625: (bf) r1 = r0 1626: (18) r2 = 0xfffffffe 1628: (5f) r1 &= r2 1629: (55) if r1 != 0x0 goto pc+7 1630: (07) r9 += 104 1631: (6b) *(u16 *)(r9 +0) = r0 1632: (67) r0 <<= 32 1633: (77) r0 >>= 32 1634: (79) r1 = *(u64 *)(r10 -456) 1635: (0f) r1 += r0 1636: (7b) *(u64 *)(r10 -456) = r1 1637: (79) r1 = *(u64 *)(r10 -368) 1638: (c5) if r1 s< 0x1 goto pc+778 1639: (bf) r6 = r8 1640: (0f) r6 += r7 1641: (b4) w1 = 0 1642: (6b) *(u16 *)(r6 +108) = r1 1643: (79) r3 = *(u64 *)(r10 -352) 1644: (79) r9 = *(u64 *)(r10 -456) 1645: (bf) r1 = r9 1646: (b4) w2 = 1 1647: (85) call bpf_probe_read_user_str#114
R1 unbounded memory access, make sure to bounds check any such access
In the above code r0 and r1 are implicitly related. Clang knows that, but verifier isn't able to infer this relationship.
Yonghong Song narrowed down this "regression" in code generation to a recent Clang optimization change ([0]), which for BPF target generates code pattern that BPF verifier can't handle and loses track of register boundaries.
This patch works around the issue by adding an BPF assembly-based helper that helps to prove to the verifier that upper bound of the register is a given constant by controlling the exact share of generated BPF instruction sequence. This fixes the immediate issue for strobemeta selftest.
[0] https://github.com/llvm/llvm-project/commit/acabad9ff6bf13e00305d9d8621ee8ea...
Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20211029182907.166910-1-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/progs/strobemeta.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/strobemeta.h b/tools/testing/selftests/bpf/progs/strobemeta.h index 7de534f38c3f1..3687ea755ab5a 100644 --- a/tools/testing/selftests/bpf/progs/strobemeta.h +++ b/tools/testing/selftests/bpf/progs/strobemeta.h @@ -10,6 +10,14 @@ #include <linux/types.h> #include <bpf/bpf_helpers.h>
+#define bpf_clamp_umax(VAR, UMAX) \ + asm volatile ( \ + "if %0 <= %[max] goto +1\n" \ + "%0 = %[max]\n" \ + : "+r"(VAR) \ + : [max]"i"(UMAX) \ + ) + typedef uint32_t pid_t; struct task_struct {};
@@ -413,6 +421,7 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg,
len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, map.tag); if (len <= STROBE_MAX_STR_LEN) { + bpf_clamp_umax(len, STROBE_MAX_STR_LEN); descr->tag_len = len; payload += len; } @@ -430,6 +439,7 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg, len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, map.entries[i].key); if (len <= STROBE_MAX_STR_LEN) { + bpf_clamp_umax(len, STROBE_MAX_STR_LEN); descr->key_lens[i] = len; payload += len; } @@ -437,6 +447,7 @@ static __always_inline void *read_map_var(struct strobemeta_cfg *cfg, len = bpf_probe_read_user_str(payload, STROBE_MAX_STR_LEN, map.entries[i].val); if (len <= STROBE_MAX_STR_LEN) { + bpf_clamp_umax(len, STROBE_MAX_STR_LEN); descr->val_lens[i] = len; payload += len; }
From: Imre Deak imre.deak@intel.com
[ Upstream commit 55285e21f04517939480966164a33898c34b2af2 ]
Atm the EFI FB platform driver gets a runtime PM reference for the associated GFX PCI device during probing the EFI FB platform device and releases it only when the platform device gets unbound.
When fbcon switches to the FB provided by the PCI device's driver (for instance i915/drmfb), the EFI FB will get only unregistered without the EFI FB platform device getting unbound, keeping the runtime PM reference acquired during the platform device probing. This reference will prevent the PCI driver from runtime suspending the device.
Fix this by releasing the RPM reference from the EFI FB's destroy hook, called when the FB gets unregistered.
While at it assert that pm_runtime_get_sync() didn't fail.
v2: - Move pm_runtime_get_sync() before register_framebuffer() to avoid its race wrt. efifb_destroy()->pm_runtime_put(). (Daniel) - Assert that pm_runtime_get_sync() didn't fail. - Clarify commit message wrt. platform/PCI device/driver and driver removal vs. device unbinding.
Fixes: a6c0fd3d5a8b ("efifb: Ensure graphics device for efifb stays at PCI D0") Cc: Kai-Heng Feng kai.heng.feng@canonical.com Cc: Daniel Vetter daniel.vetter@ffwll.ch Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch (v1) Acked-by: Alex Deucher alexander.deucher@amd.com Acked-by: Kai-Heng Feng kai.heng.feng@canonical.com Signed-off-by: Imre Deak imre.deak@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210809133146.2478382-1-imre.... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/efifb.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 8ea8f079cde26..edca3703b9640 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -47,6 +47,8 @@ static bool use_bgrt = true; static bool request_mem_succeeded = false; static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC;
+static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ + static struct fb_var_screeninfo efifb_defined = { .activate = FB_ACTIVATE_NOW, .height = -1, @@ -243,6 +245,9 @@ static inline void efifb_show_boot_graphics(struct fb_info *info) {}
static void efifb_destroy(struct fb_info *info) { + if (efifb_pci_dev) + pm_runtime_put(&efifb_pci_dev->dev); + if (info->screen_base) { if (mem_flags & (EFI_MEMORY_UC | EFI_MEMORY_WC)) iounmap(info->screen_base); @@ -333,7 +338,6 @@ ATTRIBUTE_GROUPS(efifb);
static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */
-static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ static struct resource *bar_resource; static u64 bar_offset;
@@ -569,17 +573,22 @@ static int efifb_probe(struct platform_device *dev) pr_err("efifb: cannot allocate colormap\n"); goto err_groups; } + + if (efifb_pci_dev) + WARN_ON(pm_runtime_get_sync(&efifb_pci_dev->dev) < 0); + err = register_framebuffer(info); if (err < 0) { pr_err("efifb: cannot register framebuffer\n"); - goto err_fb_dealoc; + goto err_put_rpm_ref; } fb_info(info, "%s frame buffer device\n", info->fix.id); - if (efifb_pci_dev) - pm_runtime_get_sync(&efifb_pci_dev->dev); return 0;
-err_fb_dealoc: +err_put_rpm_ref: + if (efifb_pci_dev) + pm_runtime_put(&efifb_pci_dev->dev); + fb_dealloc_cmap(&info->cmap); err_groups: sysfs_remove_groups(&dev->dev.kobj, efifb_groups); @@ -603,8 +612,6 @@ static int efifb_remove(struct platform_device *pdev) unregister_framebuffer(info); sysfs_remove_groups(&pdev->dev.kobj, efifb_groups); framebuffer_release(info); - if (efifb_pci_dev) - pm_runtime_put(&efifb_pci_dev->dev);
return 0; }
From: Robert Foss robert.foss@linaro.org
[ Upstream commit 7f16d0f3b8e2d13f940e944cd17044ca8eeb8b32 ]
The return value of sp_tx_rst_aux() is not propagated, which means both compiler warnings and potential errors not being handled.
Fixes: 8bdfc5dae4e3 ("drm/bridge: anx7625: Add anx7625 MIPI DSI/DPI to DP")
Reviewed-by: Sam Ravnborg sam@ravnborg.org Reported-by: kernel test robot lkp@intel.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210818171318.1848272-1-rober... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/analogix/anx7625.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 14d73fb1dd15b..ea414cd349b5c 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -720,7 +720,7 @@ static int edid_read(struct anx7625_data *ctx, ret = sp_tx_aux_rd(ctx, 0xf1);
if (ret) { - sp_tx_rst_aux(ctx); + ret = sp_tx_rst_aux(ctx); DRM_DEV_DEBUG_DRIVER(dev, "edid read fail, reset!\n"); } else { ret = anx7625_reg_block_read(ctx, ctx->i2c.rx_p0_client, @@ -735,7 +735,7 @@ static int edid_read(struct anx7625_data *ctx, if (cnt > EDID_TRY_CNT) return -EIO;
- return 0; + return ret; }
static int segments_edid_read(struct anx7625_data *ctx, @@ -785,7 +785,7 @@ static int segments_edid_read(struct anx7625_data *ctx, if (cnt > EDID_TRY_CNT) return -EIO;
- return 0; + return ret; }
static int sp_tx_edid_read(struct anx7625_data *ctx, @@ -887,7 +887,11 @@ static int sp_tx_edid_read(struct anx7625_data *ctx, }
/* Reset aux channel */ - sp_tx_rst_aux(ctx); + ret = sp_tx_rst_aux(ctx); + if (ret < 0) { + DRM_DEV_ERROR(dev, "Failed to reset aux channel!\n"); + return ret; + }
return (blocks_num + 1); }
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit 9d756e408e080d40e7916484b00c802026e6d1ad ]
SPR CHA events have the exact same event constraints as SKX, so add the constraints.
Fixes: 949b11381f81 ("perf/x86/intel/uncore: Add Sapphire Rapids server CHA support") Reported-by: Stephane Eranian eranian@google.com Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/1629991963-102621-5-git-send-email-kan.liang@linux... 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 d941854e4efaa..ce85ee5f60f97 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -5649,6 +5649,7 @@ static struct intel_uncore_type spr_uncore_chabox = { .event_mask = SPR_CHA_PMON_EVENT_MASK, .event_mask_ext = SPR_RAW_EVENT_MASK_EXT, .num_shared_regs = 1, + .constraints = skx_uncore_chabox_constraints, .ops = &spr_uncore_chabox_ops, .format_group = &spr_uncore_chabox_format_group, .attr_update = uncore_alias_groups,
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit 67c5d44384f8dc57e1c1b3040423cfce99b578cd ]
SPR IIO events have the exact same event constraints as ICX, so add the constraints.
Fixes: 3ba7095beaec ("perf/x86/intel/uncore: Add Sapphire Rapids server IIO support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/1629991963-102621-6-git-send-email-kan.liang@linux... 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 ce85ee5f60f97..2d75d212c8cc4 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -5661,6 +5661,7 @@ static struct intel_uncore_type spr_uncore_iio = { .event_mask_ext = SNR_IIO_PMON_RAW_EVENT_MASK_EXT, .format_group = &snr_uncore_iio_format_group, .attr_update = uncore_alias_groups, + .constraints = icx_uncore_iio_constraints, };
static struct attribute *spr_uncore_raw_formats_attr[] = {
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit f01d7d558e1855d4aa8e927b86111846536dd476 ]
Similar to the ICX M2PCIE events, some of the SPR M2PCIE events also have constraints. Add the constraints for SPR M2PCIE.
Fixes: f85ef898f884 ("perf/x86/intel/uncore: Add Sapphire Rapids server M2PCIe support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/1629991963-102621-7-git-send-email-kan.liang@linux... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/intel/uncore_snbep.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 2d75d212c8cc4..cd53057fd52de 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -5690,9 +5690,16 @@ static struct intel_uncore_type spr_uncore_irp = {
};
+static struct event_constraint spr_uncore_m2pcie_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x14, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2d, 0x3), + EVENT_CONSTRAINT_END +}; + static struct intel_uncore_type spr_uncore_m2pcie = { SPR_UNCORE_COMMON_FORMAT(), .name = "m2pcie", + .constraints = spr_uncore_m2pcie_constraints, };
static struct intel_uncore_type spr_uncore_pcu = {
From: Kan Liang kan.liang@linux.intel.com
[ Upstream commit 4034fb207e302cc0b1f304084d379640c1fb1436 ]
SPR M3UPI have the exact same event constraints as ICX, so add the constraints.
Fixes: 2a8e51eae7c8 ("perf/x86/intel/uncore: Add Sapphire Rapids server M3UPI support") Signed-off-by: Kan Liang kan.liang@linux.intel.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/1629991963-102621-8-git-send-email-kan.liang@linux... 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 cd53057fd52de..eb2c6cea9d0d5 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -5776,6 +5776,7 @@ static struct intel_uncore_type spr_uncore_upi = { static struct intel_uncore_type spr_uncore_m3upi = { SPR_UNCORE_PCI_COMMON_FORMAT(), .name = "m3upi", + .constraints = icx_uncore_m3upi_constraints, };
static struct intel_uncore_type spr_uncore_mdf = {
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit 3a5f3d61de657bc1c2b53b77d065c5526f982e10 ]
These two arrays are populated with data read from the I2C device through regmap_read(), and the data is then compared with hardcoded vendor/product ID values of supported chips.
However, the return value of regmap_read() was never checked. This is fine, as long as the two arrays are zero-initialized, so that we don't compare the vendor/product IDs against whatever garbage is left on the stack.
Address this issue by zero-initializing these two arrays.
Signed-off-by: Paul Cercueil paul@crapouillou.net Fixes: 988156dc2fc9 ("drm: bridge: add it66121 driver") Reviewed-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210827163956.27517-1-paul@cr... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ite-it66121.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 2f2a09adb4bc8..b130d01147c6c 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -889,7 +889,7 @@ unlock: static int it66121_probe(struct i2c_client *client, const struct i2c_device_id *id) { - u32 vendor_ids[2], device_ids[2], revision_id; + u32 revision_id, vendor_ids[2] = { 0 }, device_ids[2] = { 0 }; struct device_node *ep; int ret; struct it66121_ctx *ctx;
From: Paul Cercueil paul@crapouillou.net
[ Upstream commit 8b03e3fc79189b17d31a82f5e175698802a11e87 ]
If run before the next bridge is initialized, of_drm_find_bridge() will give us a NULL pointer.
If that's the case, return -EPROBE_DEFER; we may have more luck next time.
Signed-off-by: Paul Cercueil paul@crapouillou.net Fixes: 988156dc2fc9 ("drm: bridge: add it66121 driver") Reviewed-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210827163956.27517-2-paul@cr... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ite-it66121.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index b130d01147c6c..9dc41a7b91362 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -924,6 +924,9 @@ static int it66121_probe(struct i2c_client *client, ctx->next_bridge = of_drm_find_bridge(ep); of_node_put(ep);
+ if (!ctx->next_bridge) + return -EPROBE_DEFER; + i2c_set_clientdata(client, ctx); mutex_init(&ctx->lock);
From: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com
[ Upstream commit 49d8a5606428ca0962d09050a5af81461ff90fbb ]
Before freeing struct sco_conn, all delayed timeout work should be cancelled. Otherwise, sco_sock_timeout could potentially use the sco_conn after it has been freed.
Additionally, sco_conn.timeout_work should be initialized when the connection is allocated, not when the channel is added. This is because an sco_conn can create channels with multiple sockets over its lifetime, which happens if sockets are released but the connection isn't deleted.
Fixes: ba316be1b6a0 ("Bluetooth: schedule SCO timeouts with delayed_work") Signed-off-by: Desmond Cheong Zhi Xi desmondcheongzx@gmail.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/bluetooth/sco.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 4a057f99b60aa..6e047e178c0ab 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -133,6 +133,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) return NULL;
spin_lock_init(&conn->lock); + INIT_DELAYED_WORK(&conn->timeout_work, sco_sock_timeout);
hcon->sco_data = conn; conn->hcon = hcon; @@ -197,11 +198,11 @@ static void sco_conn_del(struct hci_conn *hcon, int err) sco_chan_del(sk, err); release_sock(sk); sock_put(sk); - - /* Ensure no more work items will run before freeing conn. */ - cancel_delayed_work_sync(&conn->timeout_work); }
+ /* Ensure no more work items will run before freeing conn. */ + cancel_delayed_work_sync(&conn->timeout_work); + hcon->sco_data = NULL; kfree(conn); } @@ -214,8 +215,6 @@ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, sco_pi(sk)->conn = conn; conn->sk = sk;
- INIT_DELAYED_WORK(&conn->timeout_work, sco_sock_timeout); - if (parent) bt_accept_enqueue(parent, sk, true); }
From: Toke Høiland-Jørgensen toke@redhat.com
[ Upstream commit 03e601f48b2da6fb44d0f7b86957a8f6bacfb347 ]
If libbpf encounters an ELF file that has been stripped of its symbol table, it will crash in bpf_object__add_programs() when trying to dereference the obj->efile.symbols pointer.
Fix this by erroring out of bpf_object__elf_collect() if it is not able able to find the symbol table.
v2: - Move check into bpf_object__elf_collect() and add nice error message
Fixes: 6245947c1b3c ("libbpf: Allow gaps in BPF program sections to support overriden weak functions") Signed-off-by: Toke Høiland-Jørgensen toke@redhat.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20210901114812.204720-1-toke@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index e4f83c304ec92..51180f300d2e1 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -2993,6 +2993,12 @@ static int bpf_object__elf_collect(struct bpf_object *obj) } }
+ if (!obj->efile.symbols) { + pr_warn("elf: couldn't find symbol table in %s, stripped object file?\n", + obj->path); + return -ENOENT; + } + scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { idx++;
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit 2fc7acb69fa3573d4bf7a90c323296d840daf330 ]
Syzbot hit general protection fault in h5_recv(). The problem was in missing NULL check.
hu->serdev can be NULL and we cannot blindly pass &serdev->dev somewhere, since it can cause GPF.
Fixes: d9dd833cf6d2 ("Bluetooth: hci_h5: Add runtime suspend") Reported-and-tested-by: syzbot+7d41312fe3f123a6f605@syzkaller.appspotmail.com Signed-off-by: Pavel Skripkin paskripkin@gmail.com Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_h5.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index 0c0dedece59c5..eb0099a212888 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -587,9 +587,11 @@ static int h5_recv(struct hci_uart *hu, const void *data, int count) count -= processed; }
- pm_runtime_get(&hu->serdev->dev); - pm_runtime_mark_last_busy(&hu->serdev->dev); - pm_runtime_put_autosuspend(&hu->serdev->dev); + if (hu->serdev) { + pm_runtime_get(&hu->serdev->dev); + pm_runtime_mark_last_busy(&hu->serdev->dev); + pm_runtime_put_autosuspend(&hu->serdev->dev); + }
return 0; }
From: Neeraj Upadhyay neeraju@codeaurora.org
[ Upstream commit f0b2b2df5423fb369ac762c77900bc7765496d58 ]
The sync_sched_exp_online_cleanup() checks to see if RCU needs an expedited quiescent state from the incoming CPU, sending it an IPI if so. Before sending IPI, it checks whether expedited qs need has been already requested for the incoming CPU, by checking rcu_data.cpu_no_qs.b.exp for the current cpu, on which sync_sched_exp_online_cleanup() is running. This works for the case where incoming CPU is same as self. However, for the case where incoming CPU is different from self, expedited request won't get marked, which can potentially delay reporting of expedited quiescent state for the incoming CPU.
Fixes: e015a3411220 ("rcu: Avoid self-IPI in sync_sched_exp_online_cleanup()") Signed-off-by: Neeraj Upadhyay neeraju@codeaurora.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tree_exp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h index 2796084ef85a5..454b516ea566e 100644 --- a/kernel/rcu/tree_exp.h +++ b/kernel/rcu/tree_exp.h @@ -760,7 +760,7 @@ static void sync_sched_exp_online_cleanup(int cpu) my_cpu = get_cpu(); /* Quiescent state either not needed or already requested, leave. */ if (!(READ_ONCE(rnp->expmask) & rdp->grpmask) || - __this_cpu_read(rcu_data.cpu_no_qs.b.exp)) { + rdp->cpu_no_qs.b.exp) { put_cpu(); return; }
From: Aleksander Jan Bajkowski olek2@wp.pl
[ Upstream commit 5ad74d39c51dd41b3c819f4f5396655f0629b4fd ]
The current definition of 2W burst length is invalid. This patch fixes it. Current downstream DEU driver doesn't use DMA. An incorrect burst length value doesn't cause any errors. This patch also adds other burst length values.
Fixes: dfec1a827d2b ("MIPS: Lantiq: Add DMA support") Signed-off-by: Aleksander Jan Bajkowski olek2@wp.pl Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/lantiq/xway/dma.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index 364ab39eb8a41..53fcc672a2944 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c @@ -41,7 +41,11 @@ #define DMA_IRQ_ACK 0x7e /* IRQ status register */ #define DMA_POLL BIT(31) /* turn on channel polling */ #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ -#define DMA_2W_BURST BIT(1) /* 2 word burst length */ +#define DMA_PCTRL_2W_BURST 0x1 /* 2 word burst length */ +#define DMA_PCTRL_4W_BURST 0x2 /* 4 word burst length */ +#define DMA_PCTRL_8W_BURST 0x3 /* 8 word burst length */ +#define DMA_TX_BURST_SHIFT 4 /* tx burst shift */ +#define DMA_RX_BURST_SHIFT 2 /* rx burst shift */ #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */
@@ -192,7 +196,8 @@ ltq_dma_init_port(int p) break;
case DMA_PORT_DEU: - ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2), + ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) | + (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT), LTQ_DMA_PCTRL); break;
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 9af9dcf11bda3e2c0e24c1acaacb8685ad974e93 ]
The asm_cpu_bringup_and_idle() function is required to push the return value on the stack in order to make ORC happy, but the only reason objtool doesn't complain is because of a happy accident.
The thing is that asm_cpu_bringup_and_idle() doesn't return, so validate_branch() never terminates and falls through to the next function, which in the normal case is the hypercall_page. And that, as it happens, is 4095 NOPs and a RET.
Make asm_cpu_bringup_and_idle() terminate on it's own, by making the function it calls as a dead-end. This way we no longer rely on what code happens to come after.
Fixes: c3881eb58d56 ("x86/xen: Make the secondary CPU idle tasks reliable") Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Juergen Gross jgross@suse.com Reviewed-by: Miroslav Benes mbenes@suse.cz Link: https://lore.kernel.org/r/20210624095147.693801717@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/objtool/check.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 06b5c164ae931..8bffc004f4e53 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -173,6 +173,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, "rewind_stack_do_exit", "kunit_try_catch_throw", "xen_start_kernel", + "cpu_bringup_and_idle", };
if (!func)
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit f56dae88a81fded66adf2bea9922d1d98d1da14f ]
Turns out the compilers also generate tail calls to __sanitize_cov*(), make sure to also patch those out in noinstr code.
Fixes: 0f1441b44e82 ("objtool: Fix noinstr vs KCOV") Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Marco Elver elver@google.com Link: https://lore.kernel.org/r/20210624095147.818783799@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/objtool/arch/x86/decode.c | 20 ++++ tools/objtool/check.c | 158 ++++++++++++++------------- tools/objtool/include/objtool/arch.h | 1 + 3 files changed, 105 insertions(+), 74 deletions(-)
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 0893436cc09f8..77b51600e3e94 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -659,6 +659,26 @@ const char *arch_nop_insn(int len) return nops[len-1]; }
+#define BYTE_RET 0xC3 + +const char *arch_ret_insn(int len) +{ + static const char ret[5][5] = { + { BYTE_RET }, + { BYTE_RET, BYTES_NOP1 }, + { BYTE_RET, BYTES_NOP2 }, + { BYTE_RET, BYTES_NOP3 }, + { BYTE_RET, BYTES_NOP4 }, + }; + + if (len < 1 || len > 5) { + WARN("invalid RET size: %d\n", len); + return NULL; + } + + return ret[len-1]; +} + /* asm/alternative.h ? */
#define ALTINSTR_FLAG_INV (1 << 15) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 8bffc004f4e53..81982948f981d 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -829,6 +829,79 @@ static struct reloc *insn_reloc(struct objtool_file *file, struct instruction *i return insn->reloc; }
+static void remove_insn_ops(struct instruction *insn) +{ + struct stack_op *op, *tmp; + + list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) { + list_del(&op->list); + free(op); + } +} + +static void add_call_dest(struct objtool_file *file, struct instruction *insn, + struct symbol *dest, bool sibling) +{ + struct reloc *reloc = insn_reloc(file, insn); + + insn->call_dest = dest; + if (!dest) + return; + + if (insn->call_dest->static_call_tramp) { + list_add_tail(&insn->call_node, + &file->static_call_list); + } + + /* + * Many compilers cannot disable KCOV with a function attribute + * so they need a little help, NOP out any KCOV calls from noinstr + * text. + */ + if (insn->sec->noinstr && + !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) { + if (reloc) { + reloc->type = R_NONE; + elf_write_reloc(file->elf, reloc); + } + + elf_write_insn(file->elf, insn->sec, + insn->offset, insn->len, + sibling ? arch_ret_insn(insn->len) + : arch_nop_insn(insn->len)); + + insn->type = sibling ? INSN_RETURN : INSN_NOP; + } + + if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) { + if (sibling) + WARN_FUNC("Tail call to __fentry__ !?!?", insn->sec, insn->offset); + + if (reloc) { + reloc->type = R_NONE; + elf_write_reloc(file->elf, reloc); + } + + elf_write_insn(file->elf, insn->sec, + insn->offset, insn->len, + arch_nop_insn(insn->len)); + + insn->type = INSN_NOP; + + list_add_tail(&insn->mcount_loc_node, + &file->mcount_loc_list); + } + + /* + * Whatever stack impact regular CALLs have, should be undone + * by the RETURN of the called function. + * + * Annotated intra-function calls retain the stack_ops but + * are converted to JUMP, see read_intra_function_calls(). + */ + remove_insn_ops(insn); +} + /* * Find the destination instructions for all jumps. */ @@ -867,11 +940,7 @@ static int add_jump_destinations(struct objtool_file *file) continue; } else if (insn->func) { /* internal or external sibling call (with reloc) */ - insn->call_dest = reloc->sym; - if (insn->call_dest->static_call_tramp) { - list_add_tail(&insn->call_node, - &file->static_call_list); - } + add_call_dest(file, insn, reloc->sym, true); continue; } else if (reloc->sym->sec->idx) { dest_sec = reloc->sym->sec; @@ -927,13 +996,8 @@ static int add_jump_destinations(struct objtool_file *file)
} else if (insn->jump_dest->func->pfunc != insn->func->pfunc && insn->jump_dest->offset == insn->jump_dest->func->offset) { - /* internal sibling call (without reloc) */ - insn->call_dest = insn->jump_dest->func; - if (insn->call_dest->static_call_tramp) { - list_add_tail(&insn->call_node, - &file->static_call_list); - } + add_call_dest(file, insn, insn->jump_dest->func, true); } } } @@ -941,16 +1005,6 @@ static int add_jump_destinations(struct objtool_file *file) return 0; }
-static void remove_insn_ops(struct instruction *insn) -{ - struct stack_op *op, *tmp; - - list_for_each_entry_safe(op, tmp, &insn->stack_ops, list) { - list_del(&op->list); - free(op); - } -} - static struct symbol *find_call_destination(struct section *sec, unsigned long offset) { struct symbol *call_dest; @@ -969,6 +1023,7 @@ static int add_call_destinations(struct objtool_file *file) { struct instruction *insn; unsigned long dest_off; + struct symbol *dest; struct reloc *reloc;
for_each_insn(file, insn) { @@ -978,7 +1033,9 @@ static int add_call_destinations(struct objtool_file *file) reloc = insn_reloc(file, insn); if (!reloc) { dest_off = arch_jump_destination(insn); - insn->call_dest = find_call_destination(insn->sec, dest_off); + dest = find_call_destination(insn->sec, dest_off); + + add_call_dest(file, insn, dest, false);
if (insn->ignore) continue; @@ -996,9 +1053,8 @@ static int add_call_destinations(struct objtool_file *file)
} else if (reloc->sym->type == STT_SECTION) { dest_off = arch_dest_reloc_offset(reloc->addend); - insn->call_dest = find_call_destination(reloc->sym->sec, - dest_off); - if (!insn->call_dest) { + dest = find_call_destination(reloc->sym->sec, dest_off); + if (!dest) { WARN_FUNC("can't find call dest symbol at %s+0x%lx", insn->sec, insn->offset, reloc->sym->sec->name, @@ -1006,6 +1062,8 @@ static int add_call_destinations(struct objtool_file *file) return -1; }
+ add_call_dest(file, insn, dest, false); + } else if (arch_is_retpoline(reloc->sym)) { /* * Retpoline calls are really dynamic calls in @@ -1021,55 +1079,7 @@ static int add_call_destinations(struct objtool_file *file) continue;
} else - insn->call_dest = reloc->sym; - - if (insn->call_dest && insn->call_dest->static_call_tramp) { - list_add_tail(&insn->call_node, - &file->static_call_list); - } - - /* - * Many compilers cannot disable KCOV with a function attribute - * so they need a little help, NOP out any KCOV calls from noinstr - * text. - */ - if (insn->sec->noinstr && - !strncmp(insn->call_dest->name, "__sanitizer_cov_", 16)) { - if (reloc) { - reloc->type = R_NONE; - elf_write_reloc(file->elf, reloc); - } - - elf_write_insn(file->elf, insn->sec, - insn->offset, insn->len, - arch_nop_insn(insn->len)); - insn->type = INSN_NOP; - } - - if (mcount && !strcmp(insn->call_dest->name, "__fentry__")) { - if (reloc) { - reloc->type = R_NONE; - elf_write_reloc(file->elf, reloc); - } - - elf_write_insn(file->elf, insn->sec, - insn->offset, insn->len, - arch_nop_insn(insn->len)); - - insn->type = INSN_NOP; - - list_add_tail(&insn->mcount_loc_node, - &file->mcount_loc_list); - } - - /* - * Whatever stack impact regular CALLs have, should be undone - * by the RETURN of the called function. - * - * Annotated intra-function calls retain the stack_ops but - * are converted to JUMP, see read_intra_function_calls(). - */ - remove_insn_ops(insn); + add_call_dest(file, insn, reloc->sym, false); }
return 0; diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h index 062bb6e9b8658..478e054fcdf71 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -82,6 +82,7 @@ unsigned long arch_jump_destination(struct instruction *insn); unsigned long arch_dest_reloc_offset(int addend);
const char *arch_nop_insn(int len); +const char *arch_ret_insn(int len);
int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit e9310aed8e6a5003abb2aa6b9229d2fb9ceb9e85 ]
The devlink parameters were published in two steps despite being static and known in advance.
First step was to use devlink_params_publish() which iterated over all known up to that point parameters and sent notification messages. In second step, the call was devlink_param_publish() that looped over same parameters list and sent notification for new parameters.
In order to simplify the API, move devlink_params_publish() to be called when all parameters were already added and save the need to iterate over parameters list again.
As a side effect, this change fixes the error unwind flow in which parameters were not marked as unpublished.
Fixes: 82e6c96f04e1 ("net/mlx5: Register to devlink ingress VLAN filter trap") Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index dcf9f27ba2efd..7d56a927081d0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -625,7 +625,6 @@ static int mlx5_devlink_eth_param_register(struct devlink *devlink) devlink_param_driverinit_value_set(devlink, DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH, value); - devlink_param_publish(devlink, &enable_eth_param); return 0; }
@@ -636,7 +635,6 @@ static void mlx5_devlink_eth_param_unregister(struct devlink *devlink) if (!mlx5_eth_supported(dev)) return;
- devlink_param_unpublish(devlink, &enable_eth_param); devlink_param_unregister(devlink, &enable_eth_param); }
@@ -672,7 +670,6 @@ static int mlx5_devlink_rdma_param_register(struct devlink *devlink) devlink_param_driverinit_value_set(devlink, DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA, value); - devlink_param_publish(devlink, &enable_rdma_param); return 0; }
@@ -681,7 +678,6 @@ static void mlx5_devlink_rdma_param_unregister(struct devlink *devlink) if (!IS_ENABLED(CONFIG_MLX5_INFINIBAND)) return;
- devlink_param_unpublish(devlink, &enable_rdma_param); devlink_param_unregister(devlink, &enable_rdma_param); }
@@ -706,7 +702,6 @@ static int mlx5_devlink_vnet_param_register(struct devlink *devlink) devlink_param_driverinit_value_set(devlink, DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET, value); - devlink_param_publish(devlink, &enable_rdma_param); return 0; }
@@ -717,7 +712,6 @@ static void mlx5_devlink_vnet_param_unregister(struct devlink *devlink) if (!mlx5_vnet_supported(dev)) return;
- devlink_param_unpublish(devlink, &enable_vnet_param); devlink_param_unregister(devlink, &enable_vnet_param); }
@@ -808,7 +802,6 @@ int mlx5_devlink_register(struct devlink *devlink) if (err) goto params_reg_err; mlx5_devlink_set_params_init_values(devlink); - devlink_params_publish(devlink);
err = mlx5_devlink_auxdev_params_register(devlink); if (err) @@ -818,6 +811,7 @@ int mlx5_devlink_register(struct devlink *devlink) if (err) goto traps_reg_err;
+ devlink_params_publish(devlink); return 0;
traps_reg_err: @@ -832,9 +826,9 @@ params_reg_err:
void mlx5_devlink_unregister(struct devlink *devlink) { + devlink_params_unpublish(devlink); mlx5_devlink_traps_unregister(devlink); mlx5_devlink_auxdev_params_unregister(devlink); - devlink_params_unpublish(devlink); devlink_params_unregister(devlink, mlx5_devlink_params, ARRAY_SIZE(mlx5_devlink_params)); devlink_unregister(devlink);
From: Iago Toral Quiroga itoral@igalia.com
[ Upstream commit e4f868191138975f2fdf2f37c11318b47db4acc9 ]
The hardware sets the TMUWCF bit back to 0 when the TMU write combiner flush completes so we should be checking for that instead of the L2TFLS bit.
v2 (Melissa Wen): - Add Signed-off-by and Fixes tags. - Change the error message for the timeout to be more clear.
Fixes spurious Vulkan CTS failures in: dEQP-VK.binding_model.descriptorset_random.*
Fixes: d223f98f02099 ("drm/v3d: Add support for compute shader dispatch.") Signed-off-by: Iago Toral Quiroga itoral@igalia.com Reviewed-by: Melissa Wen mwen@igalia.com Signed-off-by: Melissa Wen melissa.srw@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20210915100507.3945-1-itoral@i... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/v3d/v3d_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index 5689da118197e..772b5831bcc6f 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -197,8 +197,8 @@ v3d_clean_caches(struct v3d_dev *v3d)
V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & - V3D_L2TCACTL_L2TFLS), 100)) { - DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); + V3D_L2TCACTL_TMUWCF), 100)) { + DRM_ERROR("Timeout waiting for TMU write combiner flush\n"); }
mutex_lock(&v3d->cache_clean_lock);
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit 4a7e1e5fc294687a8941fa3eeb4a7e8539ca5e2f ]
When building with clang and GNU as, there is a warning about ignored changed section attributes:
/tmp/sm4-c916c8.s: Assembler messages: /tmp/sm4-c916c8.s:677: Warning: ignoring changed section attributes for .data..cacheline_aligned
"static const" places the data in .rodata but __cacheline_aligned has the section attribute to place it in .data..cacheline_aligned, in addition to the aligned attribute.
To keep the alignment but avoid attempting to change sections, use the ____cacheline_aligned attribute, which is just the aligned attribute.
Fixes: 2b31277af577 ("crypto: sm4 - create SM4 library based on sm4 generic code") Link: https://github.com/ClangBuiltLinux/linux/issues/1441 Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Tianjia Zhang tianjia.zhang@linux.alibaba.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- lib/crypto/sm4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/crypto/sm4.c b/lib/crypto/sm4.c index 633b59fed9db8..284e62576d0c6 100644 --- a/lib/crypto/sm4.c +++ b/lib/crypto/sm4.c @@ -15,7 +15,7 @@ static const u32 fk[4] = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
-static const u32 __cacheline_aligned ck[32] = { +static const u32 ____cacheline_aligned ck[32] = { 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, @@ -26,7 +26,7 @@ static const u32 __cacheline_aligned ck[32] = { 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 };
-static const u8 __cacheline_aligned sbox[256] = { +static const u8 ____cacheline_aligned sbox[256] = { 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
From: liuyuntao liuyuntao10@huawei.com
[ Upstream commit 5bd4f20de8acad37dbb3154feb34dbc36d506c02 ]
When kmem_cache_zalloc in virtio_gpu_get_vbuf fails, it will return an error code. But none of its callers checks this error code, and a core dump will take place.
Considering many of its callers can't handle such error, I add a __GFP_NOFAIL flag when calling kmem_cache_zalloc to make sure it won't fail, and delete those unused error handlings.
Fixes: dc5698e80cf724 ("Add virtio gpu driver.") Signed-off-by: Yuntao Liu liuyuntao10@huawei.com Link: http://patchwork.freedesktop.org/patch/msgid/20210828104321.3410312-1-liuyun... Signed-off-by: Gerd Hoffmann kraxel@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/virtio/virtgpu_vq.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 2e71e91278b45..93a41d018dca6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -91,9 +91,7 @@ virtio_gpu_get_vbuf(struct virtio_gpu_device *vgdev, { struct virtio_gpu_vbuffer *vbuf;
- vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL); - if (!vbuf) - return ERR_PTR(-ENOMEM); + vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL | __GFP_NOFAIL);
BUG_ON(size > MAX_INLINE_CMD_SIZE || size < sizeof(struct virtio_gpu_ctrl_hdr)); @@ -147,10 +145,6 @@ static void *virtio_gpu_alloc_cmd_resp(struct virtio_gpu_device *vgdev,
vbuf = virtio_gpu_get_vbuf(vgdev, cmd_size, resp_size, resp_buf, cb); - if (IS_ERR(vbuf)) { - *vbuffer_p = NULL; - return ERR_CAST(vbuf); - } *vbuffer_p = vbuf; return (struct virtio_gpu_command *)vbuf->buf; }
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit 2507003a1d10917c9158077bf6030719d02c941e ]
lock_is_held_type(, 1) detects acquired read locks. It only recognized locks acquired with lock_acquire_shared(). Read locks acquired with lock_acquire_shared_recursive() are not recognized because a `2' is stored as the read value.
Rework the check to additionally recognise lock's read value one and two as a read held lock.
Fixes: e918188611f07 ("locking: More accurate annotations for read_lock()") Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Boqun Feng boqun.feng@gmail.com Acked-by: Waiman Long longman@redhat.com Link: https://lkml.kernel.org/r/20210903084001.lblecrvz4esl4mrr@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/locking/lockdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 8a509672a4cc9..d624231eab2bb 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -5366,7 +5366,7 @@ int __lock_is_held(const struct lockdep_map *lock, int read) struct held_lock *hlock = curr->held_locks + i;
if (match_held_lock(hlock, lock)) { - if (read == -1 || hlock->read == read) + if (read == -1 || !!hlock->read == read) return LOCK_STATE_HELD;
return LOCK_STATE_NOT_HELD;
From: Yajun Deng yajun.deng@linux.dev
[ Upstream commit aed0826b0cf2e488900ab92193893e803d65c070 ]
The key_domain member in struct net only exists if we define CONFIG_KEYS. So we should add the define when we used key_domain.
Fixes: 9b242610514f ("keys: Network namespace domain tag") Signed-off-by: Yajun Deng yajun.deng@linux.dev Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/net_namespace.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index a448a9b5bb2d6..202fa5eacd0f9 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -473,7 +473,9 @@ struct net *copy_net_ns(unsigned long flags,
if (rv < 0) { put_userns: +#ifdef CONFIG_KEYS key_remove_domain(net->key_domain); +#endif put_user_ns(user_ns); net_free(net); dec_ucounts: @@ -605,7 +607,9 @@ static void cleanup_net(struct work_struct *work) list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { list_del_init(&net->exit_list); dec_net_namespaces(net->ucounts); +#ifdef CONFIG_KEYS key_remove_domain(net->key_domain); +#endif put_user_ns(net->user_ns); net_free(net); }
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
[ Upstream commit cbcca2e3961eac736566ac13ef0d0bf6f0b764ec ]
Dan Carpenter points out that we have a code path that permits a NULL netdev pointer to be passed to netif_carrier_off(), which will cause a kernel oops. In any case, we need to set pl->old_link_state to false to have the desired effect when there is no netdev present.
Fixes: f97493657c63 ("net: phylink: add suspend/resume support") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phylink.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 0a0abe8e4be0b..5a58c77d00022 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1333,7 +1333,10 @@ void phylink_suspend(struct phylink *pl, bool mac_wol) * but one would hope all packets have been sent. This * also means phylink_resolve() will do nothing. */ - netif_carrier_off(pl->netdev); + if (pl->netdev) + netif_carrier_off(pl->netdev); + else + pl->old_link_state = false;
/* We do not call mac_link_down() here as we want the * link to remain up to receive the WoL packets.
From: Alex Bee knaerzche@gmail.com
[ Upstream commit f3bc07eba481942a246926c5b934199e7ccd567b ]
Currently it66121_probe returns -EPROBE_DEFER if the there is no remote endpoint found in the device tree which doesn't seem helpful, since this is not going to change later and it is never checked if the next bridge has been initialized yet. It will fail in that case later while doing drm_bridge_attach for the next bridge in it66121_bridge_attach.
Since the bindings documentation for it66121 bridge driver states there has to be a remote endpoint defined, its safe to return -EINVAL in that case. This additonally adds a check, if the remote endpoint is enabled and returns -EPROBE_DEFER, if the remote bridge hasn't been initialized (yet).
Fixes: 988156dc2fc9 ("drm: bridge: add it66121 driver") Signed-off-by: Alex Bee knaerzche@gmail.com Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210918140420.231346-1-knaerz... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ite-it66121.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ite-it66121.c b/drivers/gpu/drm/bridge/ite-it66121.c index 9dc41a7b91362..06b59b422c696 100644 --- a/drivers/gpu/drm/bridge/ite-it66121.c +++ b/drivers/gpu/drm/bridge/ite-it66121.c @@ -918,11 +918,23 @@ static int it66121_probe(struct i2c_client *client, return -EINVAL;
ep = of_graph_get_remote_node(dev->of_node, 1, -1); - if (!ep) - return -EPROBE_DEFER; + if (!ep) { + dev_err(ctx->dev, "The endpoint is unconnected\n"); + return -EINVAL; + } + + if (!of_device_is_available(ep)) { + of_node_put(ep); + dev_err(ctx->dev, "The remote device is disabled\n"); + return -ENODEV; + }
ctx->next_bridge = of_drm_find_bridge(ep); of_node_put(ep); + if (!ctx->next_bridge) { + dev_dbg(ctx->dev, "Next bridge not found, deferring probe\n"); + return -EPROBE_DEFER; + }
if (!ctx->next_bridge) return -EPROBE_DEFER;
From: Yoshitaka Ikeda ikeda@nskint.co.jp
[ Upstream commit 09134c5322df9f105d9ed324051872d5d0e162aa ]
The reason for dividing by zero is because the dummy bus width is zero, but if the dummy n bytes is zero, it indicates that there is no data transfer, so there is no need for calculation.
Fixes: 7512eaf54190 ("spi: cadence-quadspi: Fix dummy cycle calculation when buswidth > 1") Signed-off-by: Yoshitaka Ikeda ikeda@nskint.co.jp Acked-by: Pratyush Yadav p.yadav@ti.com Link: https://lore.kernel.org/r/OSZPR01MB70049C8F56ED8902852DF97B8BD49@OSZPR01MB70... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/atmel-quadspi.c | 2 +- drivers/spi/spi-bcm-qspi.c | 3 ++- drivers/spi/spi-mtk-nor.c | 2 +- drivers/spi/spi-stm32-qspi.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index 95d4fa32c2995..92d9610df1fd8 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -310,7 +310,7 @@ static int atmel_qspi_set_cfg(struct atmel_qspi *aq, return mode; ifr |= atmel_qspi_modes[mode].config;
- if (op->dummy.buswidth && op->dummy.nbytes) + if (op->dummy.nbytes) dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth;
/* diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index ea1865c08fc22..151e154284bde 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -395,7 +395,8 @@ static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi, if (addrlen == BSPI_ADDRLEN_4BYTES) bpp = BSPI_BPP_ADDR_SELECT_MASK;
- bpp |= (op->dummy.nbytes * 8) / op->dummy.buswidth; + if (op->dummy.nbytes) + bpp |= (op->dummy.nbytes * 8) / op->dummy.buswidth;
switch (width) { case SPI_NBITS_SINGLE: diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index 41e7b341d2616..5c93730615f8d 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c @@ -160,7 +160,7 @@ static bool mtk_nor_match_read(const struct spi_mem_op *op) { int dummy = 0;
- if (op->dummy.buswidth) + if (op->dummy.nbytes) dummy = op->dummy.nbytes * BITS_PER_BYTE / op->dummy.buswidth;
if ((op->data.buswidth == 2) || (op->data.buswidth == 4)) { diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index 27f35aa2d746d..514337c86d2c3 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -397,7 +397,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op) ccr |= FIELD_PREP(CCR_ADSIZE_MASK, op->addr.nbytes - 1); }
- if (op->dummy.buswidth && op->dummy.nbytes) + if (op->dummy.nbytes) ccr |= FIELD_PREP(CCR_DCYC_MASK, op->dummy.nbytes * 8 / op->dummy.buswidth);
From: Waiman Long longman@redhat.com
[ Upstream commit 7ee285395b211cad474b2b989db52666e0430daf ]
It was found that the following warning was displayed when remounting controllers from cgroup v2 to v1:
[ 8042.997778] WARNING: CPU: 88 PID: 80682 at kernel/cgroup/cgroup.c:3130 cgroup_apply_control_disable+0x158/0x190 : [ 8043.091109] RIP: 0010:cgroup_apply_control_disable+0x158/0x190 [ 8043.096946] Code: ff f6 45 54 01 74 39 48 8d 7d 10 48 c7 c6 e0 46 5a a4 e8 7b 67 33 00 e9 41 ff ff ff 49 8b 84 24 e8 01 00 00 0f b7 40 08 eb 95 <0f> 0b e9 5f ff ff ff 48 83 c4 08 5b 5d 41 5c 41 5d 41 5e 41 5f c3 [ 8043.115692] RSP: 0018:ffffba8a47c23d28 EFLAGS: 00010202 [ 8043.120916] RAX: 0000000000000036 RBX: ffffffffa624ce40 RCX: 000000000000181a [ 8043.128047] RDX: ffffffffa63c43e0 RSI: ffffffffa63c43e0 RDI: ffff9d7284ee1000 [ 8043.135180] RBP: ffff9d72874c5800 R08: ffffffffa624b090 R09: 0000000000000004 [ 8043.142314] R10: ffffffffa624b080 R11: 0000000000002000 R12: ffff9d7284ee1000 [ 8043.149447] R13: ffff9d7284ee1000 R14: ffffffffa624ce70 R15: ffffffffa6269e20 [ 8043.156576] FS: 00007f7747cff740(0000) GS:ffff9d7a5fc00000(0000) knlGS:0000000000000000 [ 8043.164663] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8043.170409] CR2: 00007f7747e96680 CR3: 0000000887d60001 CR4: 00000000007706e0 [ 8043.177539] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 8043.184673] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 8043.191804] PKRU: 55555554 [ 8043.194517] Call Trace: [ 8043.196970] rebind_subsystems+0x18c/0x470 [ 8043.201070] cgroup_setup_root+0x16c/0x2f0 [ 8043.205177] cgroup1_root_to_use+0x204/0x2a0 [ 8043.209456] cgroup1_get_tree+0x3e/0x120 [ 8043.213384] vfs_get_tree+0x22/0xb0 [ 8043.216883] do_new_mount+0x176/0x2d0 [ 8043.220550] __x64_sys_mount+0x103/0x140 [ 8043.224474] do_syscall_64+0x38/0x90 [ 8043.228063] entry_SYSCALL_64_after_hwframe+0x44/0xae
It was caused by the fact that rebind_subsystem() disables controllers to be rebound one by one. If more than one disabled controllers are originally from the default hierarchy, it means that cgroup_apply_control_disable() will be called multiple times for the same default hierarchy. A controller may be killed by css_kill() in the first round. In the second round, the killed controller may not be completely dead yet leading to the warning.
To avoid this problem, we collect all the ssid's of controllers that needed to be disabled from the default hierarchy and then disable them in one go instead of one by one.
Fixes: 334c3679ec4b ("cgroup: reimplement rebind_subsystems() using cgroup_apply_control() and friends") Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cgroup/cgroup.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index ea08f01d0111a..d6ea872b23aad 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1740,6 +1740,7 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) struct cgroup *dcgrp = &dst_root->cgrp; struct cgroup_subsys *ss; int ssid, i, ret; + u16 dfl_disable_ss_mask = 0;
lockdep_assert_held(&cgroup_mutex);
@@ -1756,8 +1757,28 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask) /* can't move between two non-dummy roots either */ if (ss->root != &cgrp_dfl_root && dst_root != &cgrp_dfl_root) return -EBUSY; + + /* + * Collect ssid's that need to be disabled from default + * hierarchy. + */ + if (ss->root == &cgrp_dfl_root) + dfl_disable_ss_mask |= 1 << ssid; + } while_each_subsys_mask();
+ if (dfl_disable_ss_mask) { + struct cgroup *scgrp = &cgrp_dfl_root.cgrp; + + /* + * Controllers from default hierarchy that need to be rebound + * are all disabled together in one go. + */ + cgrp_dfl_root.subsys_mask &= ~dfl_disable_ss_mask; + WARN_ON(cgroup_apply_control(scgrp)); + cgroup_finalize_control(scgrp, 0); + } + do_each_subsys_mask(ss, ssid, ss_mask) { struct cgroup_root *src_root = ss->root; struct cgroup *scgrp = &src_root->cgrp; @@ -1766,10 +1787,12 @@ int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
WARN_ON(!css || cgroup_css(dcgrp, ss));
- /* disable from the source */ - src_root->subsys_mask &= ~(1 << ssid); - WARN_ON(cgroup_apply_control(scgrp)); - cgroup_finalize_control(scgrp, 0); + if (src_root != &cgrp_dfl_root) { + /* disable from the source */ + src_root->subsys_mask &= ~(1 << ssid); + WARN_ON(cgroup_apply_control(scgrp)); + cgroup_finalize_control(scgrp, 0); + }
/* rebind */ RCU_INIT_POINTER(scgrp->subsys[ssid], NULL);
From: Bryan O'Donoghue bryan.odonoghue@linaro.org
[ Upstream commit 701668d3bfa03dabc5095fc383d5315544ee5b31 ]
We have been tracking a strange bug with Antenna Diversity Switching (ADS) on wcn3680b for a while.
ADS is configured like this: A. Via a firmware configuration table baked into the NV area. 1. Defines if ADS is enabled. 2. Defines which GPIOs are connected to which antenna enable pin. 3. Defines which antenna/GPIO is primary and which is secondary.
B. WCN36XX_CFG_VAL(ANTENNA_DIVERSITY, N) N is a bitmask of available antenna.
Setting N to 3 indicates a bitmask of enabled antenna (1 | 2).
Obviously then we can set N to 1 or N to 2 to fix to a particular antenna and disable antenna diversity.
C. WCN36XX_CFG_VAL(ASD_PROBE_INTERVAL, XX) XX is the number of beacons between each antenna RSSI check. Setting this value to 50 means, every 50 received beacons, run the ADS algorithm.
D. WCN36XX_CFG_VAL(ASD_TRIGGER_THRESHOLD, YY) YY is a two's complement integer which specifies the RSSI decibel threshold below which ADS will run. We default to -60db here, meaning a measured RSSI <= -60db will trigger an ADS probe.
E. WCN36XX_CFG_VAL(ASD_RTT_RSSI_HYST_THRESHOLD, Z) Z is a hysteresis value, indicating a delta which the RSSI must exceed for the antenna switch to be valid.
For example if HYST_THRESHOLD == 3 AntennaId1-RSSI == -60db and AntennaId-2-RSSI == -58db then firmware will not switch antenna. The threshold needs to be -57db or better to satisfy the criteria.
F. A firmware feature bit also exists ANTENNA_DIVERSITY_SELECTION. This feature bit is used by the firmware to report if ANTENNA_DIVERSITY_SELECTION is supported. The host is not required to toggle this bit to enable or disable ADS.
ADS works like this:
A. Every XX beacons the firmware switches to or remains on the primary antenna.
B. The firmware then sends a Request-To-Send (RTS) packet to the AP.
C. The firmware waits for a Clear-To-Send (CTS) response from the AP.
D. The firmware then notes the received RSSI on the CTS packet.
E. The firmware then repeats steps A-D on the secondary antenna.
F. Subsequently if the RSSI on the measured antenna is better than ASD_TRIGGER_THRESHOLD + the active antenna's RSSI then the measured antenna becomes the active antenna.
G. If RSSI rises past ASD_TRIGGER_THRESHOLD then ADS doesn't run at all even if there is a substantially better RSSI on the alternative antenna.
What we have been observing is that the RTS packet is being sent but the MAC address is a byte-swapped version of the target MAC. The ADS/RTS MAC is corrupted only when the link is encrypted, if the AP is open the RTS MAC is correct. Similarly if we configure the firmware to an RTS/CTS sequence for regular data - the transmitted RTS MAC is correctly formatted.
Internally the wcn36xx firmware uses the indexes in the SMD commands to populate and extract data from specific entries in an STA lookup table. The AP's MAC appears a number of times in different indexes within this lookup table, so the MAC address extracted for the data-transmit RTS and the MAC address extracted for the ADS/RTS packet are not the same STA table index.
Our analysis indicates the relevant firmware STA table index is "bssSelfStaIdx".
There is an STA populate function responsible for formatting the MAC address of the bssSelfStaIdx including byte-swapping the MAC address.
Its clear then that the required STA populate command did not run for bssSelfStaIdx.
So taking a look at the sequence of SMD commands sent to the firmware we see the following downstream when moving from an unencrypted to encrypted BSS setup.
- WLAN_HAL_CONFIG_BSS_REQ - WLAN_HAL_CONFIG_STA_REQ - WLAN_HAL_SET_STAKEY_REQ
Upstream in wcn36xx we have
- WLAN_HAL_CONFIG_BSS_REQ - WLAN_HAL_SET_STAKEY_REQ
The solution then is to add the missing WLAN_HAL_CONFIG_STA_REQ between WLAN_HAL_CONFIG_BSS_REQ and WLAN_HAL_SET_STAKEY_REQ.
No surprise WLAN_HAL_CONFIG_STA_REQ is the routine responsible for populating the STA lookup table in the firmware and once done the MAC sent by the ADS routine is in the correct byte-order.
This bug is apparent with ADS but it is also the case that any other firmware routine that depends on the "bssSelfStaIdx" would retrieve malformed data on an encrypted link.
Fixes: 3e977c5c523d ("wcn36xx: Define wcn3680 specific firmware parameters") Signed-off-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Tested-by: Benjamin Li benl@squareup.com Reviewed-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210909144428.2564650-2-bryan.odonoghue@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 28d6251ad77a6..5974b01f2fd92 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -571,12 +571,14 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) { sta_priv->is_data_encrypted = true; /* Reconfigure bss with encrypt_type */ - if (NL80211_IFTYPE_STATION == vif->type) + if (NL80211_IFTYPE_STATION == vif->type) { wcn36xx_smd_config_bss(wcn, vif, sta, sta->addr, true); + wcn36xx_smd_config_sta(wcn, vif, sta); + }
wcn36xx_smd_set_stakey(wcn, vif_priv->encrypt_type,
From: Ajay Singh ajay.kathat@microchip.com
[ Upstream commit 3c719fed0f3a5e95b1d164609ecc81c4191ade70 ]
When the BSS reference holds a valid reference, it is not freed. The 'if' condition is wrong. Instead of the 'if (bss)' check, the 'if (!bss)' check is used. The issue is solved by removing the unnecessary 'if' check because cfg80211_put_bss() already performs the NULL validation.
Fixes: 6cd4fa5ab691 ("staging: wilc1000: make use of cfg80211_inform_bss_frame()") Signed-off-by: Ajay Singh ajay.kathat@microchip.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210916164902.74629-3-ajay.kathat@microchip.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index 96973ec7bd9ac..87c14969c75fa 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -129,8 +129,7 @@ static void cfg_scan_result(enum scan_event scan_event, info->frame_len, (s32)info->rssi * 100, GFP_KERNEL); - if (!bss) - cfg80211_put_bss(wiphy, bss); + cfg80211_put_bss(wiphy, bss); } else if (scan_event == SCAN_EVENT_DONE) { mutex_lock(&priv->scan_req_lock);
From: Dinghao Liu dinghao.liu@zju.edu.cn
[ Upstream commit 3e5f2d90c28f9454e421108554707620bc23269d ]
bdev->evt_skb will get freed in the normal path and one error path of mtk_hci_wmt_sync, while the other error paths do not free it, which may cause a memleak. This bug is suggested by a static analysis tool, please advise.
Fixes: e0b67035a90b ("Bluetooth: mediatek: update the common setup between MT7622 and other devices") Signed-off-by: Dinghao Liu dinghao.liu@zju.edu.cn Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/btmtkuart.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c index e9d91d7c0db48..9ba22b13b4fa0 100644 --- a/drivers/bluetooth/btmtkuart.c +++ b/drivers/bluetooth/btmtkuart.c @@ -158,8 +158,10 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, int err;
hlen = sizeof(*hdr) + wmt_params->dlen; - if (hlen > 255) - return -EINVAL; + if (hlen > 255) { + err = -EINVAL; + goto err_free_skb; + }
hdr = (struct mtk_wmt_hdr *)&wc; hdr->dir = 1; @@ -173,7 +175,7 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc); if (err < 0) { clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); - return err; + goto err_free_skb; }
/* The vendor specific WMT commands are all answered by a vendor @@ -190,13 +192,14 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, if (err == -EINTR) { bt_dev_err(hdev, "Execution of wmt command interrupted"); clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); - return err; + goto err_free_skb; }
if (err) { bt_dev_err(hdev, "Execution of wmt command timed out"); clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); - return -ETIMEDOUT; + err = -ETIMEDOUT; + goto err_free_skb; }
/* Parse and handle the return WMT event */
From: Andrey Grodzovsky andrey.grodzovsky@amd.com
[ Upstream commit d82e2c249c8ffaec20fa618611ea2ab4dcfd4d01 ]
Crash: BUG: unable to handle page fault for address: 00000000000010e1 RIP: 0010:vega10_power_gate_vce+0x26/0x50 [amdgpu] Call Trace: pp_set_powergating_by_smu+0x16a/0x2b0 [amdgpu] amdgpu_dpm_set_powergating_by_smu+0x92/0xf0 [amdgpu] amdgpu_dpm_enable_vce+0x2e/0xc0 [amdgpu] vce_v4_0_hw_fini+0x95/0xa0 [amdgpu] amdgpu_device_fini_hw+0x232/0x30d [amdgpu] amdgpu_driver_unload_kms+0x5c/0x80 [amdgpu] amdgpu_pci_remove+0x27/0x40 [amdgpu] pci_device_remove+0x3e/0xb0 device_release_driver_internal+0x103/0x1d0 device_release_driver+0x12/0x20 pci_stop_bus_device+0x79/0xa0 pci_stop_and_remove_bus_device_locked+0x1b/0x30 remove_store+0x7b/0x90 dev_attr_store+0x17/0x30 sysfs_kf_write+0x4b/0x60 kernfs_fop_write_iter+0x151/0x1e0
Why: VCE/UVD had dependency on SMC block for their suspend but SMC block is the first to do HW fini due to some constraints
How: Since the original patch was dealing with suspend issues move the SMC block dependency back into suspend hooks as was done in V1 of the original patches. Keep flushing idle work both in suspend and HW fini seuqnces since it's essential in both cases.
Fixes: 859e4659273f1d ("drm/amdgpu: add missing cleanups for more ASICs on UVD/VCE suspend") Fixes: bf756fb833cbe8 ("drm/amdgpu: add missing cleanups for Polaris12 UVD/VCE on suspend") Signed-off-by: Andrey Grodzovsky andrey.grodzovsky@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c | 24 ++++++++------- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 24 ++++++++------- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 24 ++++++++------- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 32 ++++++++++--------- drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 19 +++++++----- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 28 +++++++++-------- drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 44 ++++++++++++++------------- 7 files changed, 105 insertions(+), 90 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c index 7232241e3bfb2..0fef925b66024 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c @@ -698,6 +698,19 @@ static int uvd_v3_1_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->uvd.idle_work); + + if (RREG32(mmUVD_STATUS) != 0) + uvd_v3_1_stop(adev); + + return 0; +} + +static int uvd_v3_1_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -722,17 +735,6 @@ static int uvd_v3_1_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- if (RREG32(mmUVD_STATUS) != 0) - uvd_v3_1_stop(adev); - - return 0; -} - -static int uvd_v3_1_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v3_1_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 52d6de969f462..c108b83817951 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -212,6 +212,19 @@ static int uvd_v4_2_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->uvd.idle_work); + + if (RREG32(mmUVD_STATUS) != 0) + uvd_v4_2_stop(adev); + + return 0; +} + +static int uvd_v4_2_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -236,17 +249,6 @@ static int uvd_v4_2_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- if (RREG32(mmUVD_STATUS) != 0) - uvd_v4_2_stop(adev); - - return 0; -} - -static int uvd_v4_2_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v4_2_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index db6d06758e4d4..563493d1f8306 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -210,6 +210,19 @@ static int uvd_v5_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->uvd.idle_work); + + if (RREG32(mmUVD_STATUS) != 0) + uvd_v5_0_stop(adev); + + return 0; +} + +static int uvd_v5_0_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -234,17 +247,6 @@ static int uvd_v5_0_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- if (RREG32(mmUVD_STATUS) != 0) - uvd_v5_0_stop(adev); - - return 0; -} - -static int uvd_v5_0_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v5_0_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index b6e82d75561f6..1fd9ca21a091b 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -606,6 +606,23 @@ static int uvd_v7_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->uvd.idle_work); + + if (!amdgpu_sriov_vf(adev)) + uvd_v7_0_stop(adev); + else { + /* full access mode, so don't touch any UVD register */ + DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); + } + + return 0; +} + +static int uvd_v7_0_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -630,21 +647,6 @@ static int uvd_v7_0_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- if (!amdgpu_sriov_vf(adev)) - uvd_v7_0_stop(adev); - else { - /* full access mode, so don't touch any UVD register */ - DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); - } - - return 0; -} - -static int uvd_v7_0_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v7_0_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index b70c17f0c52e8..98952fd387e73 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c @@ -479,6 +479,17 @@ static int vce_v2_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->vce.idle_work); + + return 0; +} + +static int vce_v2_0_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -502,14 +513,6 @@ static int vce_v2_0_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- return 0; -} - -static int vce_v2_0_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = vce_v2_0_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 9de66893ccd6d..8fb5df7181e09 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -490,6 +490,21 @@ static int vce_v3_0_hw_fini(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->vce.idle_work); + + r = vce_v3_0_wait_for_idle(handle); + if (r) + return r; + + vce_v3_0_stop(adev); + return vce_v3_0_set_clockgating_state(adev, AMD_CG_STATE_GATE); +} + +static int vce_v3_0_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -513,19 +528,6 @@ static int vce_v3_0_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- r = vce_v3_0_wait_for_idle(handle); - if (r) - return r; - - vce_v3_0_stop(adev); - return vce_v3_0_set_clockgating_state(adev, AMD_CG_STATE_GATE); -} - -static int vce_v3_0_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = vce_v3_0_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index fec902b800c28..70b8c88d30513 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c @@ -542,29 +542,8 @@ static int vce_v4_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
- /* - * Proper cleanups before halting the HW engine: - * - cancel the delayed idle work - * - enable powergating - * - enable clockgating - * - disable dpm - * - * TODO: to align with the VCN implementation, move the - * jobs for clockgating/powergating/dpm setting to - * ->set_powergating_state(). - */ cancel_delayed_work_sync(&adev->vce.idle_work);
- if (adev->pm.dpm_enabled) { - amdgpu_dpm_enable_vce(adev, false); - } else { - amdgpu_asic_set_vce_clocks(adev, 0, 0); - amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, - AMD_PG_STATE_GATE); - amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, - AMD_CG_STATE_GATE); - } - if (!amdgpu_sriov_vf(adev)) { /* vce_v4_0_wait_for_idle(handle); */ vce_v4_0_stop(adev); @@ -594,6 +573,29 @@ static int vce_v4_0_suspend(void *handle) drm_dev_exit(idx); }
+ /* + * Proper cleanups before halting the HW engine: + * - cancel the delayed idle work + * - enable powergating + * - enable clockgating + * - disable dpm + * + * TODO: to align with the VCN implementation, move the + * jobs for clockgating/powergating/dpm setting to + * ->set_powergating_state(). + */ + cancel_delayed_work_sync(&adev->vce.idle_work); + + if (adev->pm.dpm_enabled) { + amdgpu_dpm_enable_vce(adev, false); + } else { + amdgpu_asic_set_vce_clocks(adev, 0, 0); + amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_PG_STATE_GATE); + amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE, + AMD_CG_STATE_GATE); + } + r = vce_v4_0_hw_fini(adev); if (r) return r;
From: Harry Wentland harry.wentland@amd.com
[ Upstream commit 22667e6ec6b2ce9ca706e9061660b059725d009c ]
[Why] This neither needs to be on the stack nor passed by value to each function call. In fact, when building with clang it seems to break the Linux's default 1024 byte stack frame limit.
[How] We can simply pass this as a const pointer.
This patch fixes these Coverity IDs Addresses-Coverity-ID: 1424031: ("Big parameter passed by value") Addresses-Coverity-ID: 1423970: ("Big parameter passed by value") Addresses-Coverity-ID: 1423941: ("Big parameter passed by value") Addresses-Coverity-ID: 1451742: ("Big parameter passed by value") Addresses-Coverity-ID: 1451887: ("Big parameter passed by value") Addresses-Coverity-ID: 1454146: ("Big parameter passed by value") Addresses-Coverity-ID: 1454152: ("Big parameter passed by value") Addresses-Coverity-ID: 1454413: ("Big parameter passed by value") Addresses-Coverity-ID: 1466144: ("Big parameter passed by value") Addresses-Coverity-ID: 1487237: ("Big parameter passed by value")
Signed-off-by: Harry Wentland harry.wentland@amd.com Fixes: 3fe617ccafd6 ("Enable '-Werror' by default for all kernel builds") Cc: Nick Desaulniers ndesaulniers@google.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: amd-gfx@lists.freedesktop.org Cc: Linux Kernel Mailing List linux-kernel@vger.kernel.org Cc: Arnd Bergmann arnd@kernel.org Cc: Leo Li sunpeng.li@amd.com Cc: Alex Deucher alexander.deucher@amd.com Cc: Christian König christian.koenig@amd.com Cc: Xinhui Pan Xinhui.Pan@amd.com Cc: Nathan Chancellor nathan@kernel.org Cc: Guenter Roeck linux@roeck-us.net Cc: llvm@lists.linux.dev Acked-by: Christian König christian.koenig@amd.com Build-tested-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Leo Li sunpeng.li@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/amd/display/dc/dcn20/dcn20_resource.c | 2 +- .../dc/dml/dcn20/display_rq_dlg_calc_20.c | 6 +- .../dc/dml/dcn20/display_rq_dlg_calc_20.h | 4 +- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.c | 6 +- .../dc/dml/dcn20/display_rq_dlg_calc_20v2.h | 4 +- .../dc/dml/dcn21/display_rq_dlg_calc_21.c | 62 ++++++++-------- .../dc/dml/dcn21/display_rq_dlg_calc_21.h | 4 +- .../dc/dml/dcn30/display_rq_dlg_calc_30.c | 72 +++++++++---------- .../dc/dml/dcn30/display_rq_dlg_calc_30.h | 4 +- .../dc/dml/dcn31/display_rq_dlg_calc_31.c | 68 +++++++++--------- .../dc/dml/dcn31/display_rq_dlg_calc_31.h | 4 +- .../drm/amd/display/dc/dml/display_mode_lib.h | 4 +- 12 files changed, 120 insertions(+), 120 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index f2f258e70f9da..34a126816133e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -3152,7 +3152,7 @@ void dcn20_calculate_dlg_params(
context->bw_ctx.dml.funcs.rq_dlg_get_rq_reg(&context->bw_ctx.dml, &context->res_ctx.pipe_ctx[i].rq_regs, - pipes[pipe_idx].pipe); + &pipes[pipe_idx].pipe); pipe_idx++; } } diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c index 2091dd8c252da..8c168f348a27f 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c @@ -768,12 +768,12 @@ static void dml20_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
void dml20_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param) + const display_pipe_params_st *pipe_param) { display_rq_params_st rq_param = {0};
memset(rq_regs, 0, sizeof(*rq_regs)); - dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src); + dml20_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src); extract_rq_regs(mode_lib, rq_regs, rq_param);
print__rq_regs_st(mode_lib, *rq_regs); @@ -1549,7 +1549,7 @@ static void dml20_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, void dml20_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h index d0b90947f5409..8b23867e97c18 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.h @@ -43,7 +43,7 @@ struct display_mode_lib; void dml20_rq_dlg_get_rq_reg( struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param); + const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg @@ -61,7 +61,7 @@ void dml20_rq_dlg_get_dlg_reg( struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c index 1a0c14e465faa..26ececfd40cdc 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -768,12 +768,12 @@ static void dml20v2_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib,
void dml20v2_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param) + const display_pipe_params_st *pipe_param) { display_rq_params_st rq_param = {0};
memset(rq_regs, 0, sizeof(*rq_regs)); - dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param.src); + dml20v2_rq_dlg_get_rq_params(mode_lib, &rq_param, pipe_param->src); extract_rq_regs(mode_lib, rq_regs, rq_param);
print__rq_regs_st(mode_lib, *rq_regs); @@ -1550,7 +1550,7 @@ static void dml20v2_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, void dml20v2_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h index 27cf8bed9376f..2b4e46ea1c3df 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.h @@ -43,7 +43,7 @@ struct display_mode_lib; void dml20v2_rq_dlg_get_rq_reg( struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param); + const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg @@ -61,7 +61,7 @@ void dml20v2_rq_dlg_get_dlg_reg( struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c index 287e31052b307..736978c4d40a1 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c @@ -694,7 +694,7 @@ static void get_surf_rq_param( display_data_rq_sizing_params_st *rq_sizing_param, display_data_rq_dlg_params_st *rq_dlg_param, display_data_rq_misc_params_st *rq_misc_param, - const display_pipe_params_st pipe_param, + const display_pipe_params_st *pipe_param, bool is_chroma) { bool mode_422 = false; @@ -706,30 +706,30 @@ static void get_surf_rq_param(
// FIXME check if ppe apply for both luma and chroma in 422 case if (is_chroma) { - vp_width = pipe_param.src.viewport_width_c / ppe; - vp_height = pipe_param.src.viewport_height_c; - data_pitch = pipe_param.src.data_pitch_c; - meta_pitch = pipe_param.src.meta_pitch_c; + vp_width = pipe_param->src.viewport_width_c / ppe; + vp_height = pipe_param->src.viewport_height_c; + data_pitch = pipe_param->src.data_pitch_c; + meta_pitch = pipe_param->src.meta_pitch_c; } else { - vp_width = pipe_param.src.viewport_width / ppe; - vp_height = pipe_param.src.viewport_height; - data_pitch = pipe_param.src.data_pitch; - meta_pitch = pipe_param.src.meta_pitch; + vp_width = pipe_param->src.viewport_width / ppe; + vp_height = pipe_param->src.viewport_height; + data_pitch = pipe_param->src.data_pitch; + meta_pitch = pipe_param->src.meta_pitch; }
- if (pipe_param.dest.odm_combine) { + if (pipe_param->dest.odm_combine) { unsigned int access_dir; unsigned int full_src_vp_width; unsigned int hactive_half; unsigned int src_hactive_half; - access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed - hactive_half = pipe_param.dest.hactive / 2; + access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed + hactive_half = pipe_param->dest.hactive / 2; if (is_chroma) { - full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width; - src_hactive_half = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_half; + full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; + src_hactive_half = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_half; } else { - full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width; - src_hactive_half = pipe_param.scale_ratio_depth.hscl_ratio * hactive_half; + full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; + src_hactive_half = pipe_param->scale_ratio_depth.hscl_ratio * hactive_half; }
if (access_dir == 0) { @@ -754,7 +754,7 @@ static void get_surf_rq_param( rq_sizing_param->meta_chunk_bytes = 2048; rq_sizing_param->min_meta_chunk_bytes = 256;
- if (pipe_param.src.hostvm) + if (pipe_param->src.hostvm) rq_sizing_param->mpte_group_bytes = 512; else rq_sizing_param->mpte_group_bytes = 2048; @@ -768,23 +768,23 @@ static void get_surf_rq_param( vp_height, data_pitch, meta_pitch, - pipe_param.src.source_format, - pipe_param.src.sw_mode, - pipe_param.src.macro_tile_size, - pipe_param.src.source_scan, - pipe_param.src.hostvm, + pipe_param->src.source_format, + pipe_param->src.sw_mode, + pipe_param->src.macro_tile_size, + pipe_param->src.source_scan, + pipe_param->src.hostvm, is_chroma); }
static void dml_rq_dlg_get_rq_params( struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_params_st pipe_param) + const display_pipe_params_st *pipe_param) { // get param for luma surface - rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 - || pipe_param.src.source_format == dm_420_10; - rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10; + rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 + || pipe_param->src.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10;
get_surf_rq_param( mode_lib, @@ -794,7 +794,7 @@ static void dml_rq_dlg_get_rq_params( pipe_param, 0);
- if (is_dual_plane((enum source_format_class) (pipe_param.src.source_format))) { + if (is_dual_plane((enum source_format_class) (pipe_param->src.source_format))) { // get param for chroma surface get_surf_rq_param( mode_lib, @@ -806,14 +806,14 @@ static void dml_rq_dlg_get_rq_params( }
// calculate how to split the det buffer space between luma and chroma - handle_det_buf_split(mode_lib, rq_param, pipe_param.src); + handle_det_buf_split(mode_lib, rq_param, pipe_param->src); print__rq_params_st(mode_lib, *rq_param); }
void dml21_rq_dlg_get_rq_reg( struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param) + const display_pipe_params_st *pipe_param) { display_rq_params_st rq_param = {0};
@@ -1658,7 +1658,7 @@ void dml21_rq_dlg_get_dlg_reg( struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, @@ -1696,7 +1696,7 @@ void dml21_rq_dlg_get_dlg_reg( // system parameter calculation done
dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); - dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe); + dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); dml_rq_dlg_get_dlg_params( mode_lib, e2e_pipe_param, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h index e8f7785e3fc63..af6ad0ca9cf8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.h @@ -44,7 +44,7 @@ struct display_mode_lib; void dml21_rq_dlg_get_rq_reg( struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param); + const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg // Calculate and return DLG and TTU register struct given the system setting @@ -61,7 +61,7 @@ void dml21_rq_dlg_get_dlg_reg( struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c index 0d934fae1c3a6..2120e0941a095 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.c @@ -747,7 +747,7 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, display_data_rq_sizing_params_st *rq_sizing_param, display_data_rq_dlg_params_st *rq_dlg_param, display_data_rq_misc_params_st *rq_misc_param, - const display_pipe_params_st pipe_param, + const display_pipe_params_st *pipe_param, bool is_chroma, bool is_alpha) { @@ -761,32 +761,32 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib,
// FIXME check if ppe apply for both luma and chroma in 422 case if (is_chroma | is_alpha) { - vp_width = pipe_param.src.viewport_width_c / ppe; - vp_height = pipe_param.src.viewport_height_c; - data_pitch = pipe_param.src.data_pitch_c; - meta_pitch = pipe_param.src.meta_pitch_c; - surface_height = pipe_param.src.surface_height_y / 2.0; + vp_width = pipe_param->src.viewport_width_c / ppe; + vp_height = pipe_param->src.viewport_height_c; + data_pitch = pipe_param->src.data_pitch_c; + meta_pitch = pipe_param->src.meta_pitch_c; + surface_height = pipe_param->src.surface_height_y / 2.0; } else { - vp_width = pipe_param.src.viewport_width / ppe; - vp_height = pipe_param.src.viewport_height; - data_pitch = pipe_param.src.data_pitch; - meta_pitch = pipe_param.src.meta_pitch; - surface_height = pipe_param.src.surface_height_y; + vp_width = pipe_param->src.viewport_width / ppe; + vp_height = pipe_param->src.viewport_height; + data_pitch = pipe_param->src.data_pitch; + meta_pitch = pipe_param->src.meta_pitch; + surface_height = pipe_param->src.surface_height_y; }
- if (pipe_param.dest.odm_combine) { + if (pipe_param->dest.odm_combine) { unsigned int access_dir = 0; unsigned int full_src_vp_width = 0; unsigned int hactive_odm = 0; unsigned int src_hactive_odm = 0; - access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed - hactive_odm = pipe_param.dest.hactive / ((unsigned int)pipe_param.dest.odm_combine*2); + access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed + hactive_odm = pipe_param->dest.hactive / ((unsigned int) pipe_param->dest.odm_combine*2); if (is_chroma) { - full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width; - src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_odm; + full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; + src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_odm; } else { - full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width; - src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio * hactive_odm; + full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; + src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio * hactive_odm; }
if (access_dir == 0) { @@ -815,7 +815,7 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, rq_sizing_param->meta_chunk_bytes = 2048; rq_sizing_param->min_meta_chunk_bytes = 256;
- if (pipe_param.src.hostvm) + if (pipe_param->src.hostvm) rq_sizing_param->mpte_group_bytes = 512; else rq_sizing_param->mpte_group_bytes = 2048; @@ -828,28 +828,28 @@ static void get_surf_rq_param(struct display_mode_lib *mode_lib, vp_height, data_pitch, meta_pitch, - pipe_param.src.source_format, - pipe_param.src.sw_mode, - pipe_param.src.macro_tile_size, - pipe_param.src.source_scan, - pipe_param.src.hostvm, + pipe_param->src.source_format, + pipe_param->src.sw_mode, + pipe_param->src.macro_tile_size, + pipe_param->src.source_scan, + pipe_param->src.hostvm, is_chroma, surface_height); }
static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, - const display_pipe_params_st pipe_param) + const display_pipe_params_st *pipe_param) { // get param for luma surface - rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 - || pipe_param.src.source_format == dm_420_10 - || pipe_param.src.source_format == dm_rgbe_alpha - || pipe_param.src.source_format == dm_420_12; + rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 + || pipe_param->src.source_format == dm_420_10 + || pipe_param->src.source_format == dm_rgbe_alpha + || pipe_param->src.source_format == dm_420_12;
- rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10;
- rq_param->rgbe_alpha = (pipe_param.src.source_format == dm_rgbe_alpha)?1:0; + rq_param->rgbe_alpha = (pipe_param->src.source_format == dm_rgbe_alpha)?1:0;
get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), @@ -859,7 +859,7 @@ static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, 0, 0);
- if (is_dual_plane((enum source_format_class)(pipe_param.src.source_format))) { + if (is_dual_plane((enum source_format_class)(pipe_param->src.source_format))) { // get param for chroma surface get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), @@ -871,13 +871,13 @@ static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, }
// calculate how to split the det buffer space between luma and chroma - handle_det_buf_split(mode_lib, rq_param, pipe_param.src); + handle_det_buf_split(mode_lib, rq_param, pipe_param->src); print__rq_params_st(mode_lib, *rq_param); }
void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param) + const display_pipe_params_st *pipe_param) { display_rq_params_st rq_param = { 0 };
@@ -1831,7 +1831,7 @@ static void dml_rq_dlg_get_dlg_params(struct display_mode_lib *mode_lib, void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, @@ -1866,7 +1866,7 @@ void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, // system parameter calculation done
dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); - dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe); + dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); dml_rq_dlg_get_dlg_params(mode_lib, e2e_pipe_param, num_pipes, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h index c04965cceff35..625e41f8d5751 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_rq_dlg_calc_30.h @@ -41,7 +41,7 @@ struct display_mode_lib; // See also: <display_rq_regs_st> void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param); + const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg // Calculate and return DLG and TTU register struct given the system setting @@ -57,7 +57,7 @@ void dml30_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, void dml30_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c index c23905bc733ae..57bd4e3f8a823 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c @@ -738,7 +738,7 @@ static void get_surf_rq_param( display_data_rq_sizing_params_st *rq_sizing_param, display_data_rq_dlg_params_st *rq_dlg_param, display_data_rq_misc_params_st *rq_misc_param, - const display_pipe_params_st pipe_param, + const display_pipe_params_st *pipe_param, bool is_chroma, bool is_alpha) { @@ -752,33 +752,33 @@ static void get_surf_rq_param(
// FIXME check if ppe apply for both luma and chroma in 422 case if (is_chroma | is_alpha) { - vp_width = pipe_param.src.viewport_width_c / ppe; - vp_height = pipe_param.src.viewport_height_c; - data_pitch = pipe_param.src.data_pitch_c; - meta_pitch = pipe_param.src.meta_pitch_c; - surface_height = pipe_param.src.surface_height_y / 2.0; + vp_width = pipe_param->src.viewport_width_c / ppe; + vp_height = pipe_param->src.viewport_height_c; + data_pitch = pipe_param->src.data_pitch_c; + meta_pitch = pipe_param->src.meta_pitch_c; + surface_height = pipe_param->src.surface_height_y / 2.0; } else { - vp_width = pipe_param.src.viewport_width / ppe; - vp_height = pipe_param.src.viewport_height; - data_pitch = pipe_param.src.data_pitch; - meta_pitch = pipe_param.src.meta_pitch; - surface_height = pipe_param.src.surface_height_y; + vp_width = pipe_param->src.viewport_width / ppe; + vp_height = pipe_param->src.viewport_height; + data_pitch = pipe_param->src.data_pitch; + meta_pitch = pipe_param->src.meta_pitch; + surface_height = pipe_param->src.surface_height_y; }
- if (pipe_param.dest.odm_combine) { + if (pipe_param->dest.odm_combine) { unsigned int access_dir; unsigned int full_src_vp_width; unsigned int hactive_odm; unsigned int src_hactive_odm;
- access_dir = (pipe_param.src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed - hactive_odm = pipe_param.dest.hactive / ((unsigned int) pipe_param.dest.odm_combine * 2); + access_dir = (pipe_param->src.source_scan == dm_vert); // vp access direction: horizontal or vertical accessed + hactive_odm = pipe_param->dest.hactive / ((unsigned int) pipe_param->dest.odm_combine * 2); if (is_chroma) { - full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio_c * pipe_param.dest.full_recout_width; - src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio_c * hactive_odm; + full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio_c * pipe_param->dest.full_recout_width; + src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio_c * hactive_odm; } else { - full_src_vp_width = pipe_param.scale_ratio_depth.hscl_ratio * pipe_param.dest.full_recout_width; - src_hactive_odm = pipe_param.scale_ratio_depth.hscl_ratio * hactive_odm; + full_src_vp_width = pipe_param->scale_ratio_depth.hscl_ratio * pipe_param->dest.full_recout_width; + src_hactive_odm = pipe_param->scale_ratio_depth.hscl_ratio * hactive_odm; }
if (access_dir == 0) { @@ -808,7 +808,7 @@ static void get_surf_rq_param( rq_sizing_param->meta_chunk_bytes = 2048; rq_sizing_param->min_meta_chunk_bytes = 256;
- if (pipe_param.src.hostvm) + if (pipe_param->src.hostvm) rq_sizing_param->mpte_group_bytes = 512; else rq_sizing_param->mpte_group_bytes = 2048; @@ -822,38 +822,38 @@ static void get_surf_rq_param( vp_height, data_pitch, meta_pitch, - pipe_param.src.source_format, - pipe_param.src.sw_mode, - pipe_param.src.macro_tile_size, - pipe_param.src.source_scan, - pipe_param.src.hostvm, + pipe_param->src.source_format, + pipe_param->src.sw_mode, + pipe_param->src.macro_tile_size, + pipe_param->src.source_scan, + pipe_param->src.hostvm, is_chroma, surface_height); }
-static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_params_st pipe_param) +static void dml_rq_dlg_get_rq_params(struct display_mode_lib *mode_lib, display_rq_params_st *rq_param, const display_pipe_params_st *pipe_param) { // get param for luma surface - rq_param->yuv420 = pipe_param.src.source_format == dm_420_8 || pipe_param.src.source_format == dm_420_10 || pipe_param.src.source_format == dm_rgbe_alpha - || pipe_param.src.source_format == dm_420_12; + rq_param->yuv420 = pipe_param->src.source_format == dm_420_8 || pipe_param->src.source_format == dm_420_10 || pipe_param->src.source_format == dm_rgbe_alpha + || pipe_param->src.source_format == dm_420_12;
- rq_param->yuv420_10bpc = pipe_param.src.source_format == dm_420_10; + rq_param->yuv420_10bpc = pipe_param->src.source_format == dm_420_10;
- rq_param->rgbe_alpha = (pipe_param.src.source_format == dm_rgbe_alpha) ? 1 : 0; + rq_param->rgbe_alpha = (pipe_param->src.source_format == dm_rgbe_alpha) ? 1 : 0;
get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_l), &(rq_param->dlg.rq_l), &(rq_param->misc.rq_l), pipe_param, 0, 0);
- if (is_dual_plane((enum source_format_class) (pipe_param.src.source_format))) { + if (is_dual_plane((enum source_format_class) (pipe_param->src.source_format))) { // get param for chroma surface get_surf_rq_param(mode_lib, &(rq_param->sizing.rq_c), &(rq_param->dlg.rq_c), &(rq_param->misc.rq_c), pipe_param, 1, rq_param->rgbe_alpha); }
// calculate how to split the det buffer space between luma and chroma - handle_det_buf_split(mode_lib, rq_param, pipe_param.src); + handle_det_buf_split(mode_lib, rq_param, pipe_param->src); print__rq_params_st(mode_lib, *rq_param); }
-void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_pipe_params_st pipe_param) +void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, const display_pipe_params_st *pipe_param) { display_rq_params_st rq_param = {0};
@@ -1677,7 +1677,7 @@ void dml31_rq_dlg_get_dlg_reg( struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, @@ -1704,7 +1704,7 @@ void dml31_rq_dlg_get_dlg_reg( // system parameter calculation done
dml_print("DML_DLG: Calculation for pipe[%d] start\n\n", pipe_idx); - dml_rq_dlg_get_rq_params(mode_lib, &rq_param, e2e_pipe_param[pipe_idx].pipe); + dml_rq_dlg_get_rq_params(mode_lib, &rq_param, &e2e_pipe_param[pipe_idx].pipe); dml_rq_dlg_get_dlg_params( mode_lib, e2e_pipe_param, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h index adf8518f761f9..8ee991351699d 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.h @@ -41,7 +41,7 @@ struct display_mode_lib; // See also: <display_rq_regs_st> void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param); + const display_pipe_params_st *pipe_param);
// Function: dml_rq_dlg_get_dlg_reg // Calculate and return DLG and TTU register struct given the system setting @@ -57,7 +57,7 @@ void dml31_rq_dlg_get_rq_reg(struct display_mode_lib *mode_lib, void dml31_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, diff --git a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h index d42a0aeca6be2..72b1957022aa2 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h +++ b/drivers/gpu/drm/amd/display/dc/dml/display_mode_lib.h @@ -49,7 +49,7 @@ struct dml_funcs { struct display_mode_lib *mode_lib, display_dlg_regs_st *dlg_regs, display_ttu_regs_st *ttu_regs, - display_e2e_pipe_params_st *e2e_pipe_param, + const display_e2e_pipe_params_st *e2e_pipe_param, const unsigned int num_pipes, const unsigned int pipe_idx, const bool cstate_en, @@ -60,7 +60,7 @@ struct dml_funcs { void (*rq_dlg_get_rq_reg)( struct display_mode_lib *mode_lib, display_rq_regs_st *rq_regs, - const display_pipe_params_st pipe_param); + const display_pipe_params_st *pipe_param); void (*recalculate)(struct display_mode_lib *mode_lib); void (*validate)(struct display_mode_lib *mode_lib); };
From: Guchun Chen guchun.chen@amd.com
[ Upstream commit 6effad8abe0ba4db3d9c58ed585127858a990f35 ]
adev->rmmio is set to be NULL in amdgpu_device_unmap_mmio to prevent access after pci_remove, however, in SRIOV case, amdgpu_virt_release_full_gpu will still use adev->rmmio for access after amdgpu_device_unmap_mmio. The patch is to move such SRIOV calling earlier to fini_early stage.
Fixes: 07775fc13878 ("drm/amdgpu: Unmap all MMIO mappings") Cc: Andrey Grodzovsky andrey.grodzovsky@amd.com Signed-off-by: Leslie Shi Yuliang.Shi@amd.com Signed-off-by: Guchun Chen guchun.chen@amd.com Reviewed-by: Andrey Grodzovsky andrey.grodzovsky@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5b88c873c8a89..f7a98e9e68d88 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2745,6 +2745,11 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev) adev->ip_blocks[i].status.hw = false; }
+ if (amdgpu_sriov_vf(adev)) { + if (amdgpu_virt_release_full_gpu(adev, false)) + DRM_ERROR("failed to release exclusive mode on fini\n"); + } + return 0; }
@@ -2805,10 +2810,6 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
amdgpu_ras_fini(adev);
- if (amdgpu_sriov_vf(adev)) - if (amdgpu_virt_release_full_gpu(adev, false)) - DRM_ERROR("failed to release exclusive mode on fini\n"); - return 0; }
From: Michael Walle michael@walle.cc
[ Upstream commit f20311cc9c58052e0b215013046cbf390937910c ]
On newer CAAM versions, not all accelerators are disabled if the SoC is a non-E variant. While the driver checks most of the modules for availability, there is one - PKHA - which sticks out. On non-E variants it is still reported as available, that is the number of instances is non-zero, but it has limited functionality. In particular it doesn't support encryption and decryption, but just signing and verifying. This is indicated by a bit in the PKHA_MISC field. Take this bit into account if we are checking for availability.
This will the following error: [ 8.167817] caam_jr 8020000.jr: 20000b0f: CCB: desc idx 11: : Invalid CHA selected.
Tested on an NXP LS1028A (non-E) SoC.
Fixes: d239b10d4ceb ("crypto: caam - add register map changes cf. Era 10") Signed-off-by: Michael Walle michael@walle.cc Reviewed-by: Horia Geantă horia.geanta@nxp.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/caam/caampkc.c | 19 +++++++++++++++---- drivers/crypto/caam/regs.h | 3 +++ 2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c index e313233ec6de7..bf6275ffc4aad 100644 --- a/drivers/crypto/caam/caampkc.c +++ b/drivers/crypto/caam/caampkc.c @@ -1153,16 +1153,27 @@ static struct caam_akcipher_alg caam_rsa = { int caam_pkc_init(struct device *ctrldev) { struct caam_drv_private *priv = dev_get_drvdata(ctrldev); - u32 pk_inst; + u32 pk_inst, pkha; int err; init_done = false;
/* Determine public key hardware accelerator presence. */ - if (priv->era < 10) + if (priv->era < 10) { pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; - else - pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK; + } else { + pkha = rd_reg32(&priv->ctrl->vreg.pkha); + pk_inst = pkha & CHA_VER_NUM_MASK; + + /* + * Newer CAAMs support partially disabled functionality. If this is the + * case, the number is non-zero, but this bit is set to indicate that + * no encryption or decryption is supported. Only signing and verifying + * is supported. + */ + if (pkha & CHA_VER_MISC_PKHA_NO_CRYPT) + pk_inst = 0; + }
/* Do not register algorithms if PKHA is not present. */ if (!pk_inst) diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index af61f3a2c0d46..3738625c02509 100644 --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h @@ -322,6 +322,9 @@ struct version_regs { /* CHA Miscellaneous Information - AESA_MISC specific */ #define CHA_VER_MISC_AES_GCM BIT(1 + CHA_VER_MISC_SHIFT)
+/* CHA Miscellaneous Information - PKHA_MISC specific */ +#define CHA_VER_MISC_PKHA_NO_CRYPT BIT(7 + CHA_VER_MISC_SHIFT) + /* * caam_perfmon - Performance Monitor/Secure Memory Status/ * CAAM Global Status/Component Version IDs
From: Giovanni Cabiddu giovanni.cabiddu@intel.com
[ Upstream commit ca605f97dae4bf070b7c584aec23c1c922e4d823 ]
After reset or boot, QAT 4xxx devices are inactive and require to be explicitly activated. This is done by writing the DRV_ACTIVE bit in the PM_INTERRUPT register and polling the PM_INIT_STATE to make sure that the transaction has completed properly.
If this is not done, the driver will fail the initialization sequence reporting the following message: [ 22.081193] 4xxx 0000:f7:00.0: enabling device (0140 -> 0142) [ 22.720285] QAT: AE0 is inactive!! [ 22.720287] QAT: failed to get device out of reset [ 22.720288] 4xxx 0000:f7:00.0: qat_hal_clr_reset error [ 22.720290] 4xxx 0000:f7:00.0: Failed to init the AEs [ 22.720290] 4xxx 0000:f7:00.0: Failed to initialise Acceleration Engine [ 22.720789] 4xxx 0000:f7:00.0: Resetting device qat_dev0 [ 22.825099] 4xxx: probe of 0000:f7:00.0 failed with error -14
The patch also temporarily disables the power management source of interrupt, to avoid possible spurious interrupts as the power management feature is not fully supported.
The device init function has been added to adf_dev_init(), and not in the probe of 4xxx to make sure that the device is re-enabled in case of reset.
Note that the error code reported by hw_data->init_device() in adf_dev_init() has been shadowed for consistency with the other calls in the same function.
Fixes: 8c8268166e83 ("crypto: qat - add qat_4xxx driver") Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Wojciech Ziemba wojciech.ziemba@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 31 +++++++++++++++++++ .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 10 ++++++ .../crypto/qat/qat_common/adf_accel_devices.h | 1 + drivers/crypto/qat/qat_common/adf_init.c | 5 +++ 4 files changed, 47 insertions(+)
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c index 33d8e50dcbdac..88c0ded411f15 100644 --- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c +++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2020 Intel Corporation */ +#include <linux/iopoll.h> #include <adf_accel_devices.h> #include <adf_common_drv.h> #include <adf_pf2vf_msg.h> @@ -161,6 +162,35 @@ static void adf_enable_ints(struct adf_accel_dev *accel_dev) ADF_CSR_WR(addr, ADF_4XXX_SMIAPF_MASK_OFFSET, 0); }
+static int adf_init_device(struct adf_accel_dev *accel_dev) +{ + void __iomem *addr; + u32 status; + u32 csr; + int ret; + + addr = (&GET_BARS(accel_dev)[ADF_4XXX_PMISC_BAR])->virt_addr; + + /* Temporarily mask PM interrupt */ + csr = ADF_CSR_RD(addr, ADF_4XXX_ERRMSK2); + csr |= ADF_4XXX_PM_SOU; + ADF_CSR_WR(addr, ADF_4XXX_ERRMSK2, csr); + + /* Set DRV_ACTIVE bit to power up the device */ + ADF_CSR_WR(addr, ADF_4XXX_PM_INTERRUPT, ADF_4XXX_PM_DRV_ACTIVE); + + /* Poll status register to make sure the device is powered up */ + ret = read_poll_timeout(ADF_CSR_RD, status, + status & ADF_4XXX_PM_INIT_STATE, + ADF_4XXX_PM_POLL_DELAY_US, + ADF_4XXX_PM_POLL_TIMEOUT_US, true, addr, + ADF_4XXX_PM_STATUS); + if (ret) + dev_err(&GET_DEV(accel_dev), "Failed to power up the device\n"); + + return ret; +} + static int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev) { return 0; @@ -215,6 +245,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) hw_data->exit_arb = adf_exit_arb; hw_data->get_arb_mapping = adf_get_arbiter_mapping; hw_data->enable_ints = adf_enable_ints; + hw_data->init_device = adf_init_device; hw_data->reset_device = adf_reset_flr; hw_data->admin_ae_mask = ADF_4XXX_ADMIN_AE_MASK; hw_data->uof_get_num_objs = uof_get_num_objs; diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h index 4fe2a776293c2..924bac6feb372 100644 --- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h +++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h @@ -62,6 +62,16 @@ #define ADF_4XXX_ADMINMSGLR_OFFSET (0x500578) #define ADF_4XXX_MAILBOX_BASE_OFFSET (0x600970)
+/* Power management */ +#define ADF_4XXX_PM_POLL_DELAY_US 20 +#define ADF_4XXX_PM_POLL_TIMEOUT_US USEC_PER_SEC +#define ADF_4XXX_PM_STATUS (0x50A00C) +#define ADF_4XXX_PM_INTERRUPT (0x50A028) +#define ADF_4XXX_PM_DRV_ACTIVE BIT(20) +#define ADF_4XXX_PM_INIT_STATE BIT(21) +/* Power management source in ERRSOU2 and ERRMSK2 */ +#define ADF_4XXX_PM_SOU BIT(18) + /* Firmware Binaries */ #define ADF_4XXX_FW "qat_4xxx.bin" #define ADF_4XXX_MMP "qat_4xxx_mmp.bin" diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h index 38c0af6d4e43e..580566cfcb04c 100644 --- a/drivers/crypto/qat/qat_common/adf_accel_devices.h +++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h @@ -166,6 +166,7 @@ struct adf_hw_device_data { int (*init_arb)(struct adf_accel_dev *accel_dev); void (*exit_arb)(struct adf_accel_dev *accel_dev); const u32 *(*get_arb_mapping)(void); + int (*init_device)(struct adf_accel_dev *accel_dev); void (*disable_iov)(struct adf_accel_dev *accel_dev); void (*configure_iov_threads)(struct adf_accel_dev *accel_dev, bool enable); diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c index 60bc7b991d351..e3749e5817d94 100644 --- a/drivers/crypto/qat/qat_common/adf_init.c +++ b/drivers/crypto/qat/qat_common/adf_init.c @@ -79,6 +79,11 @@ int adf_dev_init(struct adf_accel_dev *accel_dev) return -EFAULT; }
+ if (hw_data->init_device && hw_data->init_device(accel_dev)) { + dev_err(&GET_DEV(accel_dev), "Failed to initialize device\n"); + return -EFAULT; + } + if (hw_data->init_admin_comms && hw_data->init_admin_comms(accel_dev)) { dev_err(&GET_DEV(accel_dev), "Failed initialize admin comms\n"); return -EFAULT;
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 9a9023f314873241a43b5a2b96e9c0caaa958433 ]
The recently added H5_WAKEUP_DISABLE h5->flags flag gets checked in h5_btrtl_open(), but it gets set in h5_serdev_probe() *after* calling hci_uart_register_device() and thus after h5_btrtl_open() is called, set this flag earlier.
Also on devices where suspend/resume involves fully re-probing the HCI, runtime-pm suspend should not be used, make the runtime-pm setup conditional on the H5_WAKEUP_DISABLE flag too.
This fixes the HCI being removed and then re-added every 10 seconds because it was being reprobed as soon as it was runtime-suspended.
Fixes: 66f077dde749 ("Bluetooth: hci_h5: add WAKEUP_DISABLE flag") Fixes: d9dd833cf6d2 ("Bluetooth: hci_h5: Add runtime suspend") Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Archie Pusaka apusaka@chromium.org Signed-off-by: Marcel Holtmann marcel@holtmann.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bluetooth/hci_h5.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index eb0099a212888..d49a39d17d7dc 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -848,6 +848,8 @@ static int h5_serdev_probe(struct serdev_device *serdev) h5->vnd = data->vnd; }
+ if (data->driver_info & H5_INFO_WAKEUP_DISABLE) + set_bit(H5_WAKEUP_DISABLE, &h5->flags);
h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(h5->enable_gpio)) @@ -862,9 +864,6 @@ static int h5_serdev_probe(struct serdev_device *serdev) if (err) return err;
- if (data->driver_info & H5_INFO_WAKEUP_DISABLE) - set_bit(H5_WAKEUP_DISABLE, &h5->flags); - return 0; }
@@ -964,11 +963,13 @@ static void h5_btrtl_open(struct h5 *h5) serdev_device_set_parity(h5->hu->serdev, SERDEV_PARITY_EVEN); serdev_device_set_baudrate(h5->hu->serdev, 115200);
- pm_runtime_set_active(&h5->hu->serdev->dev); - pm_runtime_use_autosuspend(&h5->hu->serdev->dev); - pm_runtime_set_autosuspend_delay(&h5->hu->serdev->dev, - SUSPEND_TIMEOUT_MS); - pm_runtime_enable(&h5->hu->serdev->dev); + if (!test_bit(H5_WAKEUP_DISABLE, &h5->flags)) { + pm_runtime_set_active(&h5->hu->serdev->dev); + pm_runtime_use_autosuspend(&h5->hu->serdev->dev); + pm_runtime_set_autosuspend_delay(&h5->hu->serdev->dev, + SUSPEND_TIMEOUT_MS); + pm_runtime_enable(&h5->hu->serdev->dev); + }
/* The controller needs up to 500ms to wakeup */ gpiod_set_value_cansleep(h5->enable_gpio, 1); @@ -978,7 +979,8 @@ static void h5_btrtl_open(struct h5 *h5)
static void h5_btrtl_close(struct h5 *h5) { - pm_runtime_disable(&h5->hu->serdev->dev); + if (!test_bit(H5_WAKEUP_DISABLE, &h5->flags)) + pm_runtime_disable(&h5->hu->serdev->dev);
gpiod_set_value_cansleep(h5->device_wake_gpio, 0); gpiod_set_value_cansleep(h5->enable_gpio, 0);
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit e624c70e1131e145bd0510b8a700b5e2d112e377 ]
devlink is a software interface that doesn't depend on any hardware capabilities. The failure in SW means memory issues, wrong parameters, programmer error e.t.c.
Like any other such interface in the kernel, the returned status of devlink APIs should be checked and propagated further and not ignored.
Fixes: 4ab0c6a8ffd7 ("bnxt_en: add support to enable VF-representors") Signed-off-by: Leon Romanovsky leonro@nvidia.com Reviewed-by: Edwin Peer edwin.peer@broadcom.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 ++++- drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 13 ++++++------- drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h | 13 ------------- 3 files changed, 10 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 62f84cc91e4d1..0fba01db336cc 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -13370,7 +13370,9 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) }
bnxt_inv_fw_health_reg(bp); - bnxt_dl_register(bp); + rc = bnxt_dl_register(bp); + if (rc) + goto init_err_dl;
rc = register_netdev(dev); if (rc) @@ -13390,6 +13392,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
init_err_cleanup: bnxt_dl_unregister(bp); +init_err_dl: bnxt_shutdown_tc(bp); bnxt_clear_int_mode(bp);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index 9576547df4aba..2a80882971e3d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -134,7 +134,7 @@ void bnxt_dl_fw_reporters_create(struct bnxt *bp) { struct bnxt_fw_health *health = bp->fw_health;
- if (!bp->dl || !health) + if (!health) return;
if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) || health->fw_reset_reporter) @@ -188,7 +188,7 @@ void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all) { struct bnxt_fw_health *health = bp->fw_health;
- if (!bp->dl || !health) + if (!health) return;
if ((all || !(bp->fw_cap & BNXT_FW_CAP_HOT_RESET)) && @@ -781,6 +781,7 @@ int bnxt_dl_register(struct bnxt *bp) { const struct devlink_ops *devlink_ops; struct devlink_port_attrs attrs = {}; + struct bnxt_dl *bp_dl; struct devlink *dl; int rc;
@@ -795,7 +796,9 @@ int bnxt_dl_register(struct bnxt *bp) return -ENOMEM; }
- bnxt_link_bp_to_dl(bp, dl); + bp->dl = dl; + bp_dl = devlink_priv(dl); + bp_dl->bp = bp;
/* Add switchdev eswitch mode setting, if SRIOV supported */ if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV) && @@ -833,7 +836,6 @@ err_dl_port_unreg: err_dl_unreg: devlink_unregister(dl); err_dl_free: - bnxt_link_bp_to_dl(bp, NULL); devlink_free(dl); return rc; } @@ -842,9 +844,6 @@ void bnxt_dl_unregister(struct bnxt *bp) { struct devlink *dl = bp->dl;
- if (!dl) - return; - if (BNXT_PF(bp)) { bnxt_dl_params_unregister(bp); devlink_port_unregister(&bp->dl_port); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h index d889f240da2b2..406dc655a5fc9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h @@ -20,19 +20,6 @@ static inline struct bnxt *bnxt_get_bp_from_dl(struct devlink *dl) return ((struct bnxt_dl *)devlink_priv(dl))->bp; }
-/* To clear devlink pointer from bp, pass NULL dl */ -static inline void bnxt_link_bp_to_dl(struct bnxt *bp, struct devlink *dl) -{ - bp->dl = dl; - - /* add a back pointer in dl to bp */ - if (dl) { - struct bnxt_dl *bp_dl = devlink_priv(dl); - - bp_dl->bp = bp; - } -} - #define NVM_OFF_MSIX_VEC_PER_PF_MAX 108 #define NVM_OFF_MSIX_VEC_PER_PF_MIN 114 #define NVM_OFF_IGNORE_ARI 164
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit e6a54d6f221301347aaf9d83bb1f23129325c1c5 ]
devlink is a software interface that doesn't depend on any hardware capabilities. The failure in SW means memory issues, wrong parameters, programmer error e.t.c.
Like any other such interface in the kernel, the returned status of devlink APIs should be checked and propagated further and not ignored.
Fixes: 755f982bb1ff ("qed/qede: make devlink survive recovery") Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/qlogic/qede/qede_main.c | 12 +++++------- drivers/scsi/qedf/qedf_main.c | 2 ++ 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 9837bdb89cd40..ee4c3bd28a934 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -1176,19 +1176,17 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level, edev->devlink = qed_ops->common->devlink_register(cdev); if (IS_ERR(edev->devlink)) { DP_NOTICE(edev, "Cannot register devlink\n"); + rc = PTR_ERR(edev->devlink); edev->devlink = NULL; - /* Go on, we can live without devlink */ + goto err3; } } else { struct net_device *ndev = pci_get_drvdata(pdev); + struct qed_devlink *qdl;
edev = netdev_priv(ndev); - - if (edev->devlink) { - struct qed_devlink *qdl = devlink_priv(edev->devlink); - - qdl->cdev = cdev; - } + qdl = devlink_priv(edev->devlink); + qdl->cdev = cdev; edev->cdev = cdev; memset(&edev->stats, 0, sizeof(edev->stats)); memcpy(&edev->dev_info, &dev_info, sizeof(dev_info)); diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 42d0d941dba5c..94ee08fab46a5 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3416,7 +3416,9 @@ retry_probe: qedf->devlink = qed_ops->common->devlink_register(qedf->cdev); if (IS_ERR(qedf->devlink)) { QEDF_ERR(&qedf->dbg_ctx, "Cannot register devlink\n"); + rc = PTR_ERR(qedf->devlink); qedf->devlink = NULL; + goto err2; } }
From: Jiasheng Jiang jiasheng@iscas.ac.cn
[ Upstream commit acde891c243c1ed85b19d4d5042bdf00914f5739 ]
Directly using _usecs_to_jiffies() might be unsafe, so it's better to use usecs_to_jiffies() instead. Because we can see that the result of _usecs_to_jiffies() could be larger than MAX_JIFFY_OFFSET values without the check of the input.
Fixes: c410bf01933e ("Fix the excessive initial retransmission timeout") Signed-off-by: Jiasheng Jiang jiasheng@iscas.ac.cn Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/rxrpc/rtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/rxrpc/rtt.c b/net/rxrpc/rtt.c index 4e565eeab4260..be61d6f5be8d1 100644 --- a/net/rxrpc/rtt.c +++ b/net/rxrpc/rtt.c @@ -22,7 +22,7 @@ static u32 rxrpc_rto_min_us(struct rxrpc_peer *peer)
static u32 __rxrpc_set_rto(const struct rxrpc_peer *peer) { - return _usecs_to_jiffies((peer->srtt_us >> 3) + peer->rttvar_us); + return usecs_to_jiffies((peer->srtt_us >> 3) + peer->rttvar_us); }
static u32 rxrpc_bound_rto(u32 rto)
From: Florian Westphal fw@strlen.de
[ Upstream commit 0d199e4363b482badcedba764e2aceab53a4a10a ]
When recovering after a link failure, snd_nxt should not be set to a lower value. Else, update of snd_nxt is broken because:
msk->snd_nxt += ret; (where ret is number of bytes sent)
assumes that snd_nxt always moves forward. After reduction, its possible that snd_nxt update gets out of sync: dfrag we just sent might have had a data sequence number even past recovery_snd_nxt.
This change factors the common msk state update to a helper and updates snd_nxt based on the current dfrag data sequence number.
The conditional is required for the recovery phase where we may re-transmit old dfrags that are before current snd_nxt.
After this change, snd_nxt only moves forward and covers all in-sequence data that was transmitted.
recovery_snd_nxt is retained to detect when recovery has completed.
Fixes: 1e1d9d6f119c5 ("mptcp: handle pending data on closed subflow") Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Mat Martineau mathew.j.martineau@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/options.c | 8 +++----- net/mptcp/protocol.c | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c index f0f22eb4fd5f7..350348f070700 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -1019,11 +1019,9 @@ static void ack_update_msk(struct mptcp_sock *msk, old_snd_una = msk->snd_una; new_snd_una = mptcp_expand_seq(old_snd_una, mp_opt->data_ack, mp_opt->ack64);
- /* ACK for data not even sent yet and even above recovery bound? Ignore.*/ - if (unlikely(after64(new_snd_una, snd_nxt))) { - if (!msk->recovery || after64(new_snd_una, msk->recovery_snd_nxt)) - new_snd_una = old_snd_una; - } + /* ACK for data not even sent yet? Ignore.*/ + if (unlikely(after64(new_snd_una, snd_nxt))) + new_snd_una = old_snd_una;
new_wnd_end = new_snd_una + tcp_sk(ssk)->snd_wnd;
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index d073b21113828..4379d69aead7e 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1505,6 +1505,32 @@ static void mptcp_push_release(struct sock *sk, struct sock *ssk, release_sock(ssk); }
+static void mptcp_update_post_push(struct mptcp_sock *msk, + struct mptcp_data_frag *dfrag, + u32 sent) +{ + u64 snd_nxt_new = dfrag->data_seq; + + dfrag->already_sent += sent; + + msk->snd_burst -= sent; + msk->tx_pending_data -= sent; + + snd_nxt_new += dfrag->already_sent; + + /* snd_nxt_new can be smaller than snd_nxt in case mptcp + * is recovering after a failover. In that event, this re-sends + * old segments. + * + * Thus compute snd_nxt_new candidate based on + * the dfrag->data_seq that was sent and the data + * that has been handed to the subflow for transmission + * and skip update in case it was old dfrag. + */ + if (likely(after64(snd_nxt_new, msk->snd_nxt))) + msk->snd_nxt = snd_nxt_new; +} + void __mptcp_push_pending(struct sock *sk, unsigned int flags) { struct sock *prev_ssk = NULL, *ssk = NULL; @@ -1548,12 +1574,10 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) }
info.sent += ret; - dfrag->already_sent += ret; - msk->snd_nxt += ret; - msk->snd_burst -= ret; - msk->tx_pending_data -= ret; copied += ret; len -= ret; + + mptcp_update_post_push(msk, dfrag, ret); } WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); } @@ -1606,13 +1630,11 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk) goto out;
info.sent += ret; - dfrag->already_sent += ret; - msk->snd_nxt += ret; - msk->snd_burst -= ret; - msk->tx_pending_data -= ret; copied += ret; len -= ret; first = false; + + mptcp_update_post_push(msk, dfrag, ret); } WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); } @@ -2183,15 +2205,12 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) return false; }
- /* will accept ack for reijected data before re-sending them */ - if (!msk->recovery || after64(msk->snd_nxt, msk->recovery_snd_nxt)) - msk->recovery_snd_nxt = msk->snd_nxt; + msk->recovery_snd_nxt = msk->snd_nxt; msk->recovery = true; mptcp_data_unlock(sk);
msk->first_pending = rtx_head; msk->tx_pending_data += msk->snd_nxt - rtx_head->data_seq; - msk->snd_nxt = rtx_head->data_seq; msk->snd_burst = 0;
/* be sure to clear the "sent status" on all re-injected fragments */
From: Kees Cook keescook@chromium.org
[ Upstream commit 072af0c638dc8a5c7db2edc4dddbd6d44bee3bdb ]
The implementation for intra-object overflow in str*-family functions accidentally dropped compile-time write overflow checking in strcpy(), leaving it entirely to run-time. Add back the intended check.
Fixes: 6a39e62abbaf ("lib: string.h: detect intra-object overflow in fortified string functions") Cc: Daniel Axtens dja@axtens.net Cc: Francis Laniel laniel_francis@privacyrequired.com Signed-off-by: Kees Cook keescook@chromium.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/fortify-string.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index c1be37437e778..0c70febd03e95 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -280,7 +280,10 @@ __FORTIFY_INLINE char *strcpy(char *p, const char *q) if (p_size == (size_t)-1 && q_size == (size_t)-1) return __underlying_strcpy(p, q); size = strlen(q) + 1; - /* test here to use the more stringent object size */ + /* Compile-time check for const size overflow. */ + if (__builtin_constant_p(size) && p_size < size) + __write_overflow(); + /* Run-time check for dynamic size overflow. */ if (p_size < size) fortify_panic(__func__); memcpy(p, q, size);
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 7ff379ba2d4b7b205240e666601fe302207d73f8 ]
Since we're pointing into a frame, the pointer to the twt_agrt->req_type struct member is potentially not aligned properly. Open-code le16p_replace_bits() to avoid passing an unaligned pointer.
Reported-by: kernel test robot lkp@intel.com Fixes: f5a4c24e689f ("mac80211: introduce individual TWT support in AP mode") Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20210927115124.e1208694f37b.Ie3de9bcc5dde5a79e3ac8... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/s1g.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/s1g.c b/net/mac80211/s1g.c index 7e35ab5b61664..4141bc80cdfd6 100644 --- a/net/mac80211/s1g.c +++ b/net/mac80211/s1g.c @@ -104,9 +104,11 @@ ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
/* broadcast TWT not supported yet */ if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) { - le16p_replace_bits(&twt_agrt->req_type, - TWT_SETUP_CMD_REJECT, - IEEE80211_TWT_REQTYPE_SETUP_CMD); + twt_agrt->req_type &= + ~cpu_to_le16(IEEE80211_TWT_REQTYPE_SETUP_CMD); + twt_agrt->req_type |= + le16_encode_bits(TWT_SETUP_CMD_REJECT, + IEEE80211_TWT_REQTYPE_SETUP_CMD); goto out; }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit e53e9828a8d2c6545e01ff9711f1221f2fd199ce ]
In the (somewhat unlikely) event that we allocate a wiphy, then add a regdomain to it, and then fail registration, we leak the regdomain. Fix this by just always freeing it at the end, in the normal cases we'll free (and NULL) it during wiphy_unregister(). This happened when the wiphy settings were bad, and since they can be controlled by userspace with hwsim, syzbot was able to find this issue.
Reported-by: syzbot+1638e7c770eef6b6c0d0@syzkaller.appspotmail.com Fixes: 3e0c3ff36c4c ("cfg80211: allow multiple driver regulatory_hints()") Signed-off-by: Johannes Berg johannes.berg@intel.com Link: https://lore.kernel.org/r/20210927131105.68b70cef4674.I4b9f0aa08c2af28555963... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/wireless/core.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/net/wireless/core.c b/net/wireless/core.c index aaba847d79eb2..eb297e1015e05 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1081,6 +1081,16 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) cfg80211_put_bss(&rdev->wiphy, &scan->pub); mutex_destroy(&rdev->wiphy.mtx); + + /* + * The 'regd' can only be non-NULL if we never finished + * initializing the wiphy and thus never went through the + * unregister path - e.g. in failure scenarios. Thus, it + * cannot have been visible to anyone if non-NULL, so we + * can just free it here. + */ + kfree(rcu_dereference_raw(rdev->wiphy.regd)); + kfree(rdev); }
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit 64ea2d0e7263b67d8efc93fa1baace041ed36d1e ]
The change of devlink_alloc() to accept device makes sure that device is fully initialized and device_register() does nothing except allowing users to use that devlink instance.
Such change ensures that no user input will be usable till that point and it eliminates the need to worry about internal locking as long as devlink_register is called last since all accesses to the devlink are during initialization.
This change fixes the following lockdep warning.
====================================================== WARNING: possible circular locking dependency detected 5.14.0-rc2+ #27 Not tainted ------------------------------------------------------ devlink/265 is trying to acquire lock: ffff8880133c2bc0 (&dev->intf_state_mutex){+.+.}-{3:3}, at: mlx5_unload_one+0x1e/0xa0 [mlx5_core] but task is already holding lock: ffffffff8362b468 (devlink_mutex){+.+.}-{3:3}, at: devlink_nl_pre_doit+0x2b/0x8d0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is:
-> #1 (devlink_mutex){+.+.}-{3:3}: __mutex_lock+0x149/0x1310 devlink_register+0xe7/0x280 mlx5_devlink_register+0x118/0x480 [mlx5_core] mlx5_init_one+0x34b/0x440 [mlx5_core] probe_one+0x480/0x6e0 [mlx5_core] pci_device_probe+0x2a0/0x4a0 really_probe+0x1cb/0xba0 __driver_probe_device+0x18f/0x470 driver_probe_device+0x49/0x120 __driver_attach+0x1ce/0x400 bus_for_each_dev+0x11e/0x1a0 bus_add_driver+0x309/0x570 driver_register+0x20f/0x390 0xffffffffa04a0062 do_one_initcall+0xd5/0x400 do_init_module+0x1c8/0x760 load_module+0x7d9d/0xa4b0 __do_sys_finit_module+0x118/0x1a0 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
-> #0 (&dev->intf_state_mutex){+.+.}-{3:3}: __lock_acquire+0x2999/0x5a40 lock_acquire+0x1a9/0x4a0 __mutex_lock+0x149/0x1310 mlx5_unload_one+0x1e/0xa0 [mlx5_core] mlx5_devlink_reload_down+0x185/0x2b0 [mlx5_core] devlink_reload+0x1f2/0x640 devlink_nl_cmd_reload+0x6c3/0x10d0 genl_family_rcv_msg_doit+0x1e9/0x2f0 genl_rcv_msg+0x27f/0x4a0 netlink_rcv_skb+0x11e/0x340 genl_rcv+0x24/0x40 netlink_unicast+0x433/0x700 netlink_sendmsg+0x6fb/0xbe0 sock_sendmsg+0xb0/0xe0 __sys_sendto+0x192/0x240 __x64_sys_sendto+0xdc/0x1b0 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(devlink_mutex); lock(&dev->intf_state_mutex); lock(devlink_mutex); lock(&dev->intf_state_mutex);
*** DEADLOCK ***
3 locks held by devlink/265: #0: ffffffff836371d0 (cb_lock){++++}-{3:3}, at: genl_rcv+0x15/0x40 #1: ffffffff83637288 (genl_mutex){+.+.}-{3:3}, at: genl_rcv_msg+0x31a/0x4a0 #2: ffffffff8362b468 (devlink_mutex){+.+.}-{3:3}, at: devlink_nl_pre_doit+0x2b/0x8d0
stack backtrace: CPU: 0 PID: 265 Comm: devlink Not tainted 5.14.0-rc2+ #27 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 check_noncircular+0x268/0x310 ? print_circular_bug+0x460/0x460 ? __kernel_text_address+0xe/0x30 ? alloc_chain_hlocks+0x1e6/0x5a0 __lock_acquire+0x2999/0x5a40 ? lockdep_hardirqs_on_prepare+0x3e0/0x3e0 ? add_lock_to_list.constprop.0+0x6c/0x530 lock_acquire+0x1a9/0x4a0 ? mlx5_unload_one+0x1e/0xa0 [mlx5_core] ? lock_release+0x6c0/0x6c0 ? lockdep_hardirqs_on_prepare+0x3e0/0x3e0 ? lock_is_held_type+0x98/0x110 __mutex_lock+0x149/0x1310 ? mlx5_unload_one+0x1e/0xa0 [mlx5_core] ? lock_is_held_type+0x98/0x110 ? mlx5_unload_one+0x1e/0xa0 [mlx5_core] ? find_held_lock+0x2d/0x110 ? mutex_lock_io_nested+0x1160/0x1160 ? mlx5_lag_is_active+0x72/0x90 [mlx5_core] ? lock_downgrade+0x6d0/0x6d0 ? do_raw_spin_lock+0x12e/0x270 ? rwlock_bug.part.0+0x90/0x90 ? mlx5_unload_one+0x1e/0xa0 [mlx5_core] mlx5_unload_one+0x1e/0xa0 [mlx5_core] mlx5_devlink_reload_down+0x185/0x2b0 [mlx5_core] ? netlink_broadcast_filtered+0x308/0xac0 ? mlx5_devlink_info_get+0x1f0/0x1f0 [mlx5_core] ? __build_skb_around+0x110/0x2b0 ? __alloc_skb+0x113/0x2b0 devlink_reload+0x1f2/0x640 ? devlink_unregister+0x1e0/0x1e0 ? security_capable+0x51/0x90 devlink_nl_cmd_reload+0x6c3/0x10d0 ? devlink_nl_cmd_get_doit+0x1e0/0x1e0 ? devlink_nl_pre_doit+0x72/0x8d0 genl_family_rcv_msg_doit+0x1e9/0x2f0 ? __lock_acquire+0x15e2/0x5a40 ? genl_family_rcv_msg_attrs_parse.constprop.0+0x240/0x240 ? mutex_lock_io_nested+0x1160/0x1160 ? security_capable+0x51/0x90 genl_rcv_msg+0x27f/0x4a0 ? genl_get_cmd+0x3c0/0x3c0 ? lock_acquire+0x1a9/0x4a0 ? devlink_nl_cmd_get_doit+0x1e0/0x1e0 ? lock_release+0x6c0/0x6c0 netlink_rcv_skb+0x11e/0x340 ? genl_get_cmd+0x3c0/0x3c0 ? netlink_ack+0x930/0x930 genl_rcv+0x24/0x40 netlink_unicast+0x433/0x700 ? netlink_attachskb+0x750/0x750 ? __alloc_skb+0x113/0x2b0 netlink_sendmsg+0x6fb/0xbe0 ? netlink_unicast+0x700/0x700 ? netlink_unicast+0x700/0x700 sock_sendmsg+0xb0/0xe0 __sys_sendto+0x192/0x240 ? __x64_sys_getpeername+0xb0/0xb0 ? do_sys_openat2+0x10a/0x370 ? down_write_nested+0x150/0x150 ? do_user_addr_fault+0x215/0xd50 ? __x64_sys_openat+0x11f/0x1d0 ? __x64_sys_open+0x1a0/0x1a0 __x64_sys_sendto+0xdc/0x1b0 ? syscall_enter_from_user_mode+0x1d/0x50 do_syscall_64+0x3d/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f50b50b6b3a Code: d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 f3 0f 1e fa 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 76 c3 0f 1f 44 00 00 55 48 83 ec 30 44 89 4c RSP: 002b:00007fff6c0d3f38 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007f50b50b6b3a RDX: 0000000000000038 RSI: 000055763ac08440 RDI: 0000000000000003 RBP: 000055763ac08410 R08: 00007f50b5192200 R09: 000000000000000c R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 000055763ac08410 R15: 000055763ac08440 mlx5_core 0000:00:09.0: firmware version: 4.8.9999 mlx5_core 0000:00:09.0: 0.000 Gb/s available PCIe bandwidth (8.0 GT/s PCIe x255 link) mlx5_core 0000:00:09.0 eth1: Link up
Fixes: a6f3b62386a0 ("net/mlx5: Move devlink registration before interfaces load") Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 12 ++---------- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 ++ .../net/ethernet/mellanox/mlx5/core/sf/dev/driver.c | 2 ++ 3 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index 7d56a927081d0..d7576b6fa43b7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -793,14 +793,11 @@ int mlx5_devlink_register(struct devlink *devlink) { int err;
- err = devlink_register(devlink); - if (err) - return err; - err = devlink_params_register(devlink, mlx5_devlink_params, ARRAY_SIZE(mlx5_devlink_params)); if (err) - goto params_reg_err; + return err; + mlx5_devlink_set_params_init_values(devlink);
err = mlx5_devlink_auxdev_params_register(devlink); @@ -811,7 +808,6 @@ int mlx5_devlink_register(struct devlink *devlink) if (err) goto traps_reg_err;
- devlink_params_publish(devlink); return 0;
traps_reg_err: @@ -819,17 +815,13 @@ traps_reg_err: auxdev_reg_err: devlink_params_unregister(devlink, mlx5_devlink_params, ARRAY_SIZE(mlx5_devlink_params)); -params_reg_err: - devlink_unregister(devlink); return err; }
void mlx5_devlink_unregister(struct devlink *devlink) { - devlink_params_unpublish(devlink); mlx5_devlink_traps_unregister(devlink); mlx5_devlink_auxdev_params_unregister(devlink); devlink_params_unregister(devlink, mlx5_devlink_params, ARRAY_SIZE(mlx5_devlink_params)); - devlink_unregister(devlink); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 79482824c64ff..92b08fa07efae 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1537,6 +1537,7 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id) dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err);
pci_save_state(pdev); + devlink_register(devlink); if (!mlx5_core_is_mp_slave(dev)) devlink_reload_enable(devlink); return 0; @@ -1559,6 +1560,7 @@ static void remove_one(struct pci_dev *pdev) struct devlink *devlink = priv_to_devlink(dev);
devlink_reload_disable(devlink); + devlink_unregister(devlink); mlx5_crdump_disable(dev); mlx5_drain_health_wq(dev); mlx5_uninit_one(dev); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c index 052f48068dc16..3cf272fa21646 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c @@ -46,6 +46,7 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia mlx5_core_warn(mdev, "mlx5_init_one err=%d\n", err); goto init_one_err; } + devlink_register(devlink); devlink_reload_enable(devlink); return 0;
@@ -65,6 +66,7 @@ static void mlx5_sf_dev_remove(struct auxiliary_device *adev)
devlink = priv_to_devlink(sf_dev->mdev); devlink_reload_disable(devlink); + devlink_unregister(devlink); mlx5_uninit_one(sf_dev->mdev); iounmap(sf_dev->mdev->iseg); mlx5_mdev_uninit(sf_dev->mdev);
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit 5f5f12f5d4b108399130bb5c11f07765851d9cdb ]
The max VLAN number with non-4K VLAN activated is 15, and the range is 0..15. Not 16.
The impact should be low since we by default have 4K VLAN and thus have 4095 VLANs to play with in this switch. There will not be a problem unless the code is rewritten to only use 16 VLANs.
Fixes: d8652956cf37 ("net: dsa: realtek-smi: Add Realtek SMI driver") Cc: Mauri Sandberg sandberg@mailfence.com Cc: DENG Qingfang dqfext@gmail.com Cc: Florian Fainelli f.fainelli@gmail.com Reviewed-by: Alvin Šipraga alsi@bang-olufsen.dk Reviewed-by: Vladimir Oltean olteanv@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/rtl8366rb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dsa/rtl8366rb.c b/drivers/net/dsa/rtl8366rb.c index a89093bc6c6ad..9e3b572ed999e 100644 --- a/drivers/net/dsa/rtl8366rb.c +++ b/drivers/net/dsa/rtl8366rb.c @@ -1350,7 +1350,7 @@ static int rtl8366rb_set_mc_index(struct realtek_smi *smi, int port, int index)
static bool rtl8366rb_is_vlan_valid(struct realtek_smi *smi, unsigned int vlan) { - unsigned int max = RTL8366RB_NUM_VLANS; + unsigned int max = RTL8366RB_NUM_VLANS - 1;
if (smi->vlan4k_enabled) max = RTL8366RB_NUM_VIDS - 1;
From: Linus Walleij linus.walleij@linaro.org
[ Upstream commit d8251b9db34a2cbc5619b610e7e8aad1d165c531 ]
We were checking that the MC (member config) was != 0 for some reason, all we need to check is that the config has no ports, i.e. no members. Then it can be recycled. This must be some misunderstanding.
Fixes: 4ddcaf1ebb5e ("net: dsa: rtl8366: Properly clear member config") Cc: Mauri Sandberg sandberg@mailfence.com Cc: DENG Qingfang dqfext@gmail.com Reviewed-by: Alvin Šipraga alsi@bang-olufsen.dk Reviewed-by: Vladimir Oltean olteanv@gmail.com Reviewed-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/rtl8366.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dsa/rtl8366.c b/drivers/net/dsa/rtl8366.c index 75897a3690969..ffbe5b6b2655b 100644 --- a/drivers/net/dsa/rtl8366.c +++ b/drivers/net/dsa/rtl8366.c @@ -457,7 +457,7 @@ int rtl8366_vlan_del(struct dsa_switch *ds, int port, * anymore then clear the whole member * config so it can be reused. */ - if (!vlanmc.member && vlanmc.untag) { + if (!vlanmc.member) { vlanmc.vid = 0; vlanmc.priority = 0; vlanmc.fid = 0;
From: Johan Almbladh johan.almbladh@anyfinetworks.com
[ Upstream commit 18935a72eb25525b655262579e1652362a3b29bb ]
This patch fixes an error in the tail call limit test that caused the test to fail on for x86-64 JIT. Previously, the register R0 was used to report the total number of tail calls made. However, after a tail call fall-through, the value of the R0 register is undefined. Now, all tail call error path tests instead use context state to store the count.
Fixes: 874be05f525e ("bpf, tests: Add tail call test suite") Reported-by: Paul Chaignon paul@cilium.io Reported-by: Tiezhu Yang yangtiezhu@loongson.cn Signed-off-by: Johan Almbladh johan.almbladh@anyfinetworks.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Tested-by: Tiezhu Yang yangtiezhu@loongson.cn Link: https://lore.kernel.org/bpf/20210914091842.4186267-14-johan.almbladh@anyfine... Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_bpf.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/lib/test_bpf.c b/lib/test_bpf.c index 830a18ecffc88..68d125b409f20 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -8992,10 +8992,15 @@ static __init int test_bpf(void) struct tail_call_test { const char *descr; struct bpf_insn insns[MAX_INSNS]; + int flags; int result; int stack_depth; };
+/* Flags that can be passed to tail call test cases */ +#define FLAG_NEED_STATE BIT(0) +#define FLAG_RESULT_IN_STATE BIT(1) + /* * Magic marker used in test snippets for tail calls below. * BPF_LD/MOV to R2 and R2 with this immediate value is replaced @@ -9065,32 +9070,38 @@ static struct tail_call_test tail_call_tests[] = { { "Tail call error path, max count reached", .insns = { - BPF_ALU64_IMM(BPF_ADD, R1, 1), - BPF_ALU64_REG(BPF_MOV, R0, R1), + BPF_LDX_MEM(BPF_W, R2, R1, 0), + BPF_ALU64_IMM(BPF_ADD, R2, 1), + BPF_STX_MEM(BPF_W, R1, R2, 0), TAIL_CALL(0), BPF_EXIT_INSN(), }, - .result = MAX_TAIL_CALL_CNT + 1, + .flags = FLAG_NEED_STATE | FLAG_RESULT_IN_STATE, + .result = (MAX_TAIL_CALL_CNT + 1 + 1) * MAX_TESTRUNS, }, { "Tail call error path, NULL target", .insns = { - BPF_ALU64_IMM(BPF_MOV, R0, -1), + BPF_LDX_MEM(BPF_W, R2, R1, 0), + BPF_ALU64_IMM(BPF_ADD, R2, 1), + BPF_STX_MEM(BPF_W, R1, R2, 0), TAIL_CALL(TAIL_CALL_NULL), - BPF_ALU64_IMM(BPF_MOV, R0, 1), BPF_EXIT_INSN(), }, - .result = 1, + .flags = FLAG_NEED_STATE | FLAG_RESULT_IN_STATE, + .result = MAX_TESTRUNS, }, { "Tail call error path, index out of range", .insns = { - BPF_ALU64_IMM(BPF_MOV, R0, -1), + BPF_LDX_MEM(BPF_W, R2, R1, 0), + BPF_ALU64_IMM(BPF_ADD, R2, 1), + BPF_STX_MEM(BPF_W, R1, R2, 0), TAIL_CALL(TAIL_CALL_INVALID), - BPF_ALU64_IMM(BPF_MOV, R0, 1), BPF_EXIT_INSN(), }, - .result = 1, + .flags = FLAG_NEED_STATE | FLAG_RESULT_IN_STATE, + .result = MAX_TESTRUNS, }, };
@@ -9196,6 +9207,8 @@ static __init int test_tail_calls(struct bpf_array *progs) for (i = 0; i < ARRAY_SIZE(tail_call_tests); i++) { struct tail_call_test *test = &tail_call_tests[i]; struct bpf_prog *fp = progs->ptrs[i]; + int *data = NULL; + int state = 0; u64 duration; int ret;
@@ -9212,7 +9225,11 @@ static __init int test_tail_calls(struct bpf_array *progs) if (fp->jited) jit_cnt++;
- ret = __run_one(fp, NULL, MAX_TESTRUNS, &duration); + if (test->flags & FLAG_NEED_STATE) + data = &state; + ret = __run_one(fp, data, MAX_TESTRUNS, &duration); + if (test->flags & FLAG_RESULT_IN_STATE) + ret = state; if (ret == test->result) { pr_cont("%lld PASS", duration); pass_cnt++;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit aadf7c81a0771b8f1c97dabca6a48bae1b387779 ]
The ath11k_dbring_bufs_replenish() and ath11k_dbring_fill_bufs() take a "gfp" parameter but they since they take spinlocks, the allocations they do have to be atomic. This causes a bug because ath11k_dbring_buf_setup passes GFP_KERNEL for the gfp flags.
The fix is to use GFP_ATOMIC and remove the unused parameters.
Fixes: bd6478559e27 ("ath11k: Add direct buffer ring support") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210812070434.GE31863@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/dbring.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c index 5e1f5437b4185..fd98ba5b1130b 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.c +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -8,8 +8,7 @@
static int ath11k_dbring_bufs_replenish(struct ath11k *ar, struct ath11k_dbring *ring, - struct ath11k_dbring_element *buff, - gfp_t gfp) + struct ath11k_dbring_element *buff) { struct ath11k_base *ab = ar->ab; struct hal_srng *srng; @@ -35,7 +34,7 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar, goto err;
spin_lock_bh(&ring->idr_lock); - buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, gfp); + buf_id = idr_alloc(&ring->bufs_idr, buff, 0, ring->bufs_max, GFP_ATOMIC); spin_unlock_bh(&ring->idr_lock); if (buf_id < 0) { ret = -ENOBUFS; @@ -72,8 +71,7 @@ err: }
static int ath11k_dbring_fill_bufs(struct ath11k *ar, - struct ath11k_dbring *ring, - gfp_t gfp) + struct ath11k_dbring *ring) { struct ath11k_dbring_element *buff; struct hal_srng *srng; @@ -92,11 +90,11 @@ static int ath11k_dbring_fill_bufs(struct ath11k *ar, size = sizeof(*buff) + ring->buf_sz + align - 1;
while (num_remain > 0) { - buff = kzalloc(size, gfp); + buff = kzalloc(size, GFP_ATOMIC); if (!buff) break;
- ret = ath11k_dbring_bufs_replenish(ar, ring, buff, gfp); + ret = ath11k_dbring_bufs_replenish(ar, ring, buff); if (ret) { ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n", num_remain, req_entries); @@ -176,7 +174,7 @@ int ath11k_dbring_buf_setup(struct ath11k *ar, ring->hp_addr = ath11k_hal_srng_get_hp_addr(ar->ab, srng); ring->tp_addr = ath11k_hal_srng_get_tp_addr(ar->ab, srng);
- ret = ath11k_dbring_fill_bufs(ar, ring, GFP_KERNEL); + ret = ath11k_dbring_fill_bufs(ar, ring);
return ret; } @@ -322,7 +320,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab, }
memset(buff, 0, size); - ath11k_dbring_bufs_replenish(ar, ring, buff, GFP_ATOMIC); + ath11k_dbring_bufs_replenish(ar, ring, buff); }
spin_unlock_bh(&srng->lock);
From: Sriram R srirrama@codeaurora.org
[ Upstream commit 1db2b0d0a39102238fcbf9092cefa65a710642e9 ]
Whenever ath11k is bootup with a user country already set, cfg80211 notifies this country info to ath11k soon after registration, where the notification is sent to the firmware for fetching the rules of this user country input.
Multiple race conditions could be seen in this scenario where a new request is either lost as pointed in [1] or a new regd overwrites the default regd provided by the firmware during bootup. Note that, the default regd is used for intersection purpose and hence it should not be overwritten.
The main reason as pointed by [1] is the usage of ATH11K_FLAG_REGISTERED flag which is updated after completion of core registration, whereas the reg notification from cfg80211 and wmi events for the corresponding request can happen much before that. Since the ATH11K_FLAG_REGISTERED is currently used to determine if the event containing reg rules belong to default regd or for user request, there is a possibility of the default regd getting overwritten.
Since the default reg rules will be received only once per pdev on firmware load, the above flag based check can be replaced with a check to see if default_regd is already set, so that we can now always update the new_regd. Also if the new_regd is set, this will be always used to update the reg rules for the registered phy.
[1] https://patchwork.kernel.org/project/linux-wireless/patch/1829665.1PRlr7bOQj...
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01460-QCAHKSWPL_SILICONZ-1 Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Sriram R srirrama@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210721212029.142388-4-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/mac.c | 2 +- drivers/net/wireless/ath/ath11k/reg.c | 11 ++++++----- drivers/net/wireless/ath/ath11k/reg.h | 2 +- drivers/net/wireless/ath/ath11k/wmi.c | 16 ++++++---------- 4 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index e9b3689331ec2..89a64ebd620f3 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6590,7 +6590,7 @@ static int __ath11k_mac_register(struct ath11k *ar) ar->hw->wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MONITOR);
/* Apply the regd received during initialization */ - ret = ath11k_regd_update(ar, true); + ret = ath11k_regd_update(ar); if (ret) { ath11k_err(ar->ab, "ath11k regd update failed: %d\n", ret); goto err_unregister_hw; diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index e1a1df169034b..92c59009a8ac2 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -198,7 +198,7 @@ static void ath11k_copy_regd(struct ieee80211_regdomain *regd_orig, sizeof(struct ieee80211_reg_rule)); }
-int ath11k_regd_update(struct ath11k *ar, bool init) +int ath11k_regd_update(struct ath11k *ar) { struct ieee80211_regdomain *regd, *regd_copy = NULL; int ret, regd_len, pdev_id; @@ -209,7 +209,10 @@ int ath11k_regd_update(struct ath11k *ar, bool init)
spin_lock_bh(&ab->base_lock);
- if (init) { + /* Prefer the latest regd update over default if it's available */ + if (ab->new_regd[pdev_id]) { + regd = ab->new_regd[pdev_id]; + } else { /* Apply the regd received during init through * WMI_REG_CHAN_LIST_CC event. In case of failure to * receive the regd, initialize with a default world @@ -222,8 +225,6 @@ int ath11k_regd_update(struct ath11k *ar, bool init) "failed to receive default regd during init\n"); regd = (struct ieee80211_regdomain *)&ath11k_world_regd; } - } else { - regd = ab->new_regd[pdev_id]; }
if (!regd) { @@ -683,7 +684,7 @@ void ath11k_regd_update_work(struct work_struct *work) regd_update_work); int ret;
- ret = ath11k_regd_update(ar, false); + ret = ath11k_regd_update(ar); if (ret) { /* Firmware has already moved to the new regd. We need * to maintain channel consistency across FW, Host driver diff --git a/drivers/net/wireless/ath/ath11k/reg.h b/drivers/net/wireless/ath/ath11k/reg.h index 65d56d44796f6..5fb9dc03a74e8 100644 --- a/drivers/net/wireless/ath/ath11k/reg.h +++ b/drivers/net/wireless/ath/ath11k/reg.h @@ -31,6 +31,6 @@ void ath11k_regd_update_work(struct work_struct *work); struct ieee80211_regdomain * ath11k_reg_build_regd(struct ath11k_base *ab, struct cur_regulatory_info *reg_info, bool intersect); -int ath11k_regd_update(struct ath11k *ar, bool init); +int ath11k_regd_update(struct ath11k *ar); int ath11k_reg_update_chan_list(struct ath11k *ar); #endif diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 72da1283f2ccb..a53eef8e2631c 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5841,10 +5841,10 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk }
spin_lock(&ab->base_lock); - if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { - /* Once mac is registered, ar is valid and all CC events from - * fw is considered to be received due to user requests - * currently. + if (ab->default_regd[pdev_idx]) { + /* The initial rules from FW after WMI Init is to build + * the default regd. From then on, any rules updated for + * the pdev could be due to user reg changes. * Free previously built regd before assigning the newly * generated regd to ar. NULL pointer handling will be * taken care by kfree itself. @@ -5854,13 +5854,9 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk ab->new_regd[pdev_idx] = regd; ieee80211_queue_work(ar->hw, &ar->regd_update_work); } else { - /* Multiple events for the same *ar is not expected. But we - * can still clear any previously stored default_regd if we - * are receiving this event for the same radio by mistake. - * NULL pointer handling will be taken care by kfree itself. + /* This regd would be applied during mac registration and is + * held constant throughout for regd intersection purpose */ - kfree(ab->default_regd[pdev_idx]); - /* This regd would be applied during mac registration */ ab->default_regd[pdev_idx] = regd; } ab->dfs_region = reg_info->dfs_region;
From: Pradeep Kumar Chitrapu pradeepc@codeaurora.org
[ Upstream commit 9d6ae1f5cf733c0e8d7f904c501fd015c4b9f0f4 ]
Frequency in rx status is being filled incorrectly in the 6 GHz band as channel number received is invalid in this case which is causing packet drops. So fix that.
Fixes: 5dcf42f8b79d ("ath11k: Use freq instead of channel number in rx path") Signed-off-by: Pradeep Kumar Chitrapu pradeepc@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210722102054.43419-2-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/dp_rx.c | 9 ++++++--- drivers/net/wireless/ath/ath11k/wmi.c | 10 +++++++--- 2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index af0a600ea067c..0ae6bebff801d 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -2337,8 +2337,10 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, channel_num = meta_data; center_freq = meta_data >> 16;
- if (center_freq >= 5935 && center_freq <= 7105) { + if (center_freq >= ATH11K_MIN_6G_FREQ && + center_freq <= ATH11K_MAX_6G_FREQ) { rx_status->band = NL80211_BAND_6GHZ; + rx_status->freq = center_freq; } else if (channel_num >= 1 && channel_num <= 14) { rx_status->band = NL80211_BAND_2GHZ; } else if (channel_num >= 36 && channel_num <= 173) { @@ -2356,8 +2358,9 @@ static void ath11k_dp_rx_h_ppdu(struct ath11k *ar, struct hal_rx_desc *rx_desc, rx_desc, sizeof(struct hal_rx_desc)); }
- rx_status->freq = ieee80211_channel_to_frequency(channel_num, - rx_status->band); + if (rx_status->band != NL80211_BAND_6GHZ) + rx_status->freq = ieee80211_channel_to_frequency(channel_num, + rx_status->band);
ath11k_dp_rx_h_rate(ar, rx_desc, rx_status); } diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index a53eef8e2631c..99c0b81e496bf 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -6127,8 +6127,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb) if (rx_ev.status & WMI_RX_STATUS_ERR_MIC) status->flag |= RX_FLAG_MMIC_ERROR;
- if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ) { + if (rx_ev.chan_freq >= ATH11K_MIN_6G_FREQ && + rx_ev.chan_freq <= ATH11K_MAX_6G_FREQ) { status->band = NL80211_BAND_6GHZ; + status->freq = rx_ev.chan_freq; } else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) { status->band = NL80211_BAND_2GHZ; } else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH11K_MAX_5G_CHAN) { @@ -6149,8 +6151,10 @@ static void ath11k_mgmt_rx_event(struct ath11k_base *ab, struct sk_buff *skb)
sband = &ar->mac.sbands[status->band];
- status->freq = ieee80211_channel_to_frequency(rx_ev.channel, - status->band); + if (status->band != NL80211_BAND_6GHZ) + status->freq = ieee80211_channel_to_frequency(rx_ev.channel, + status->band); + status->signal = rx_ev.snr + ATH11K_DEFAULT_NOISE_FLOOR; status->rate_idx = ath11k_mac_bitrate_to_idx(sband, rx_ev.rate / 100);
From: Baochen Qiang bqiang@codeaurora.org
[ Upstream commit 72de799aa9e3e064b35238ef053d2f0a49db055a ]
The buffer pointed to by event is not freed in case ATH11K_FLAG_UNREGISTERING bit is set, resulting in memory leak, so fix it.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-01720.1-QCAHSPSWPL_V1_V2_SILICONZ_LITE-1
Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") Signed-off-by: Baochen Qiang bqiang@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210913180246.193388-4-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/qmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index b5e34d670715e..4c5071b7d11dc 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -2707,8 +2707,10 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work) list_del(&event->list); spin_unlock(&qmi->event_lock);
- if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) + if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) { + kfree(event); return; + }
switch (event->type) { case ATH11K_QMI_EVENT_SERVER_ARRIVE:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 1e0083bd0777e4a418a6710d9ee04b979cdbe5cc ]
The use of dma_unmap_addr()/dma_unmap_len() in the driver causes multiple warnings when these macros are defined as empty, e.g. in an ARCH=i386 allmodconfig build:
drivers/net/ethernet/google/gve/gve_tx_dqo.c: In function 'gve_tx_add_skb_no_copy_dqo': drivers/net/ethernet/google/gve/gve_tx_dqo.c:494:40: error: unused variable 'buf' [-Werror=unused-variable] 494 | struct gve_tx_dma_buf *buf =
This is not how the NEED_DMA_MAP_STATE macros are meant to work, as they rely on never using local variables or a temporary structure like gve_tx_dma_buf.
Remote the gve_tx_dma_buf definition and open-code the contents in all places to avoid the warning. This causes some rather long lines but otherwise ends up making the driver slightly smaller.
Fixes: a57e5de476be ("gve: DQO: Add TX path") Link: https://lore.kernel.org/netdev/20210723231957.1113800-1-bcf@google.com/ Link: https://lore.kernel.org/netdev/20210721151100.2042139-1-arnd@kernel.org/ Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/google/gve/gve.h | 13 ++- drivers/net/ethernet/google/gve/gve_tx.c | 23 +++--- drivers/net/ethernet/google/gve/gve_tx_dqo.c | 84 +++++++++----------- 3 files changed, 54 insertions(+), 66 deletions(-)
diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h index 92dc18a4bcc41..2f93ed4705905 100644 --- a/drivers/net/ethernet/google/gve/gve.h +++ b/drivers/net/ethernet/google/gve/gve.h @@ -224,11 +224,6 @@ struct gve_tx_iovec { u32 iov_padding; /* padding associated with this segment */ };
-struct gve_tx_dma_buf { - DEFINE_DMA_UNMAP_ADDR(dma); - DEFINE_DMA_UNMAP_LEN(len); -}; - /* Tracks the memory in the fifo occupied by the skb. Mapped 1:1 to a desc * ring entry but only used for a pkt_desc not a seg_desc */ @@ -236,7 +231,10 @@ struct gve_tx_buffer_state { struct sk_buff *skb; /* skb for this pkt */ union { struct gve_tx_iovec iov[GVE_TX_MAX_IOVEC]; /* segments of this pkt */ - struct gve_tx_dma_buf buf; + struct { + DEFINE_DMA_UNMAP_ADDR(dma); + DEFINE_DMA_UNMAP_LEN(len); + }; }; };
@@ -280,7 +278,8 @@ struct gve_tx_pending_packet_dqo { * All others correspond to `skb`'s frags and should be unmapped with * `dma_unmap_page`. */ - struct gve_tx_dma_buf bufs[MAX_SKB_FRAGS + 1]; + DEFINE_DMA_UNMAP_ADDR(dma[MAX_SKB_FRAGS + 1]); + DEFINE_DMA_UNMAP_LEN(len[MAX_SKB_FRAGS + 1]); u16 num_bufs;
/* Linked list index to next element in the list, or -1 if none */ diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c index 665ac795a1adf..9922ce46a6351 100644 --- a/drivers/net/ethernet/google/gve/gve_tx.c +++ b/drivers/net/ethernet/google/gve/gve_tx.c @@ -303,15 +303,15 @@ static inline int gve_skb_fifo_bytes_required(struct gve_tx_ring *tx, static void gve_tx_unmap_buf(struct device *dev, struct gve_tx_buffer_state *info) { if (info->skb) { - dma_unmap_single(dev, dma_unmap_addr(&info->buf, dma), - dma_unmap_len(&info->buf, len), + dma_unmap_single(dev, dma_unmap_addr(info, dma), + dma_unmap_len(info, len), DMA_TO_DEVICE); - dma_unmap_len_set(&info->buf, len, 0); + dma_unmap_len_set(info, len, 0); } else { - dma_unmap_page(dev, dma_unmap_addr(&info->buf, dma), - dma_unmap_len(&info->buf, len), + dma_unmap_page(dev, dma_unmap_addr(info, dma), + dma_unmap_len(info, len), DMA_TO_DEVICE); - dma_unmap_len_set(&info->buf, len, 0); + dma_unmap_len_set(info, len, 0); } }
@@ -491,7 +491,6 @@ static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx, struct gve_tx_buffer_state *info; bool is_gso = skb_is_gso(skb); u32 idx = tx->req & tx->mask; - struct gve_tx_dma_buf *buf; u64 addr; u32 len; int i; @@ -515,9 +514,8 @@ static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx, tx->dma_mapping_error++; goto drop; } - buf = &info->buf; - dma_unmap_len_set(buf, len, len); - dma_unmap_addr_set(buf, dma, addr); + dma_unmap_len_set(info, len, len); + dma_unmap_addr_set(info, dma, addr);
payload_nfrags = shinfo->nr_frags; if (hlen < len) { @@ -549,10 +547,9 @@ static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx, tx->dma_mapping_error++; goto unmap_drop; } - buf = &tx->info[idx].buf; tx->info[idx].skb = NULL; - dma_unmap_len_set(buf, len, len); - dma_unmap_addr_set(buf, dma, addr); + dma_unmap_len_set(&tx->info[idx], len, len); + dma_unmap_addr_set(&tx->info[idx], dma, addr);
gve_tx_fill_seg_desc(seg_desc, skb, is_gso, len, addr); } diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c index 05ddb6a75c38f..ec394d9916681 100644 --- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c @@ -85,18 +85,16 @@ static void gve_tx_clean_pending_packets(struct gve_tx_ring *tx) int j;
for (j = 0; j < cur_state->num_bufs; j++) { - struct gve_tx_dma_buf *buf = &cur_state->bufs[j]; - if (j == 0) { dma_unmap_single(tx->dev, - dma_unmap_addr(buf, dma), - dma_unmap_len(buf, len), - DMA_TO_DEVICE); + dma_unmap_addr(cur_state, dma[j]), + dma_unmap_len(cur_state, len[j]), + DMA_TO_DEVICE); } else { dma_unmap_page(tx->dev, - dma_unmap_addr(buf, dma), - dma_unmap_len(buf, len), - DMA_TO_DEVICE); + dma_unmap_addr(cur_state, dma[j]), + dma_unmap_len(cur_state, len[j]), + DMA_TO_DEVICE); } } if (cur_state->skb) { @@ -457,15 +455,15 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, const bool is_gso = skb_is_gso(skb); u32 desc_idx = tx->dqo_tx.tail;
- struct gve_tx_pending_packet_dqo *pending_packet; + struct gve_tx_pending_packet_dqo *pkt; struct gve_tx_metadata_dqo metadata; s16 completion_tag; int i;
- pending_packet = gve_alloc_pending_packet(tx); - pending_packet->skb = skb; - pending_packet->num_bufs = 0; - completion_tag = pending_packet - tx->dqo.pending_packets; + pkt = gve_alloc_pending_packet(tx); + pkt->skb = skb; + pkt->num_bufs = 0; + completion_tag = pkt - tx->dqo.pending_packets;
gve_extract_tx_metadata_dqo(skb, &metadata); if (is_gso) { @@ -493,8 +491,6 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx,
/* Map the linear portion of skb */ { - struct gve_tx_dma_buf *buf = - &pending_packet->bufs[pending_packet->num_bufs]; u32 len = skb_headlen(skb); dma_addr_t addr;
@@ -502,9 +498,9 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, if (unlikely(dma_mapping_error(tx->dev, addr))) goto err;
- dma_unmap_len_set(buf, len, len); - dma_unmap_addr_set(buf, dma, addr); - ++pending_packet->num_bufs; + dma_unmap_len_set(pkt, len[pkt->num_bufs], len); + dma_unmap_addr_set(pkt, dma[pkt->num_bufs], addr); + ++pkt->num_bufs;
gve_tx_fill_pkt_desc_dqo(tx, &desc_idx, skb, len, addr, completion_tag, @@ -512,8 +508,6 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, }
for (i = 0; i < shinfo->nr_frags; i++) { - struct gve_tx_dma_buf *buf = - &pending_packet->bufs[pending_packet->num_bufs]; const skb_frag_t *frag = &shinfo->frags[i]; bool is_eop = i == (shinfo->nr_frags - 1); u32 len = skb_frag_size(frag); @@ -523,9 +517,9 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, if (unlikely(dma_mapping_error(tx->dev, addr))) goto err;
- dma_unmap_len_set(buf, len, len); - dma_unmap_addr_set(buf, dma, addr); - ++pending_packet->num_bufs; + dma_unmap_len_set(pkt, len[pkt->num_bufs], len); + dma_unmap_addr_set(pkt, dma[pkt->num_bufs], addr); + ++pkt->num_bufs;
gve_tx_fill_pkt_desc_dqo(tx, &desc_idx, skb, len, addr, completion_tag, is_eop, is_gso); @@ -552,22 +546,23 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, return 0;
err: - for (i = 0; i < pending_packet->num_bufs; i++) { - struct gve_tx_dma_buf *buf = &pending_packet->bufs[i]; - + for (i = 0; i < pkt->num_bufs; i++) { if (i == 0) { - dma_unmap_single(tx->dev, dma_unmap_addr(buf, dma), - dma_unmap_len(buf, len), + dma_unmap_single(tx->dev, + dma_unmap_addr(pkt, dma[i]), + dma_unmap_len(pkt, len[i]), DMA_TO_DEVICE); } else { - dma_unmap_page(tx->dev, dma_unmap_addr(buf, dma), - dma_unmap_len(buf, len), DMA_TO_DEVICE); + dma_unmap_page(tx->dev, + dma_unmap_addr(pkt, dma[i]), + dma_unmap_len(pkt, len[i]), + DMA_TO_DEVICE); } }
- pending_packet->skb = NULL; - pending_packet->num_bufs = 0; - gve_free_pending_packet(tx, pending_packet); + pkt->skb = NULL; + pkt->num_bufs = 0; + gve_free_pending_packet(tx, pkt);
return -1; } @@ -725,12 +720,12 @@ static void add_to_list(struct gve_tx_ring *tx, struct gve_index_list *list,
static void remove_from_list(struct gve_tx_ring *tx, struct gve_index_list *list, - struct gve_tx_pending_packet_dqo *pending_packet) + struct gve_tx_pending_packet_dqo *pkt) { s16 prev_index, next_index;
- prev_index = pending_packet->prev; - next_index = pending_packet->next; + prev_index = pkt->prev; + next_index = pkt->next;
if (prev_index == -1) { /* Node is head */ @@ -747,21 +742,18 @@ static void remove_from_list(struct gve_tx_ring *tx, }
static void gve_unmap_packet(struct device *dev, - struct gve_tx_pending_packet_dqo *pending_packet) + struct gve_tx_pending_packet_dqo *pkt) { - struct gve_tx_dma_buf *buf; int i;
/* SKB linear portion is guaranteed to be mapped */ - buf = &pending_packet->bufs[0]; - dma_unmap_single(dev, dma_unmap_addr(buf, dma), - dma_unmap_len(buf, len), DMA_TO_DEVICE); - for (i = 1; i < pending_packet->num_bufs; i++) { - buf = &pending_packet->bufs[i]; - dma_unmap_page(dev, dma_unmap_addr(buf, dma), - dma_unmap_len(buf, len), DMA_TO_DEVICE); + dma_unmap_single(dev, dma_unmap_addr(pkt, dma[0]), + dma_unmap_len(pkt, len[0]), DMA_TO_DEVICE); + for (i = 1; i < pkt->num_bufs; i++) { + dma_unmap_page(dev, dma_unmap_addr(pkt, dma[i]), + dma_unmap_len(pkt, len[i]), DMA_TO_DEVICE); } - pending_packet->num_bufs = 0; + pkt->num_bufs = 0; }
/* Completion types and expected behavior:
From: Loic Poulain loic.poulain@linaro.org
[ Upstream commit e6dfbc3ba90cc2b619229be56b485f085a0a8e1c ]
When receiving a beacon or probe response, we should update the boottime_ns field which is the timestamp the frame was received at. (cf mac80211.h)
This fixes a scanning issue with Android since it relies on this timestamp to determine when the AP has been seen for the last time (via the nl80211 BSS_LAST_SEEN_BOOTTIME parameter).
Fixes: 5e3dd157d7e7 ("ath10k: mac80211 driver for Qualcomm Atheros 802.11ac CQA98xx devices") Signed-off-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1629811733-7927-1-git-send-email-loic.poulain@lina... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/wmi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index b8a4bbfe10b87..7c1c2658cb5f8 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2610,6 +2610,10 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) if (ieee80211_is_beacon(hdr->frame_control)) ath10k_mac_handle_beacon(ar, skb);
+ if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) + status->boottime_ns = ktime_get_boottime_ns(); + ath10k_dbg(ar, ATH10K_DBG_MGMT, "event mgmt rx skb %pK len %d ftype %02x stype %02x\n", skb, skb->len,
From: Fabio Estevam festevam@denx.de
[ Upstream commit 019edd01d174ce4bb2e517dd332922514d176601 ]
On a i.MX-based board with a QCA9377 Wifi chip, the following errors are seen after launching the 'hostapd' application:
hostapd /etc/wifi.conf Configuration file: /etc/wifi.conf wlan0: interface state UNINITIALIZED->COUNTRY_UPDATE NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! Using interface wlan0 with hwaddr 00:1f:7b:31:04:a0 and ssid "thessid" IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready wlan0: interface state COUNTRY_UPDATE->ENABLED wlan0: AP-ENABLED NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! ...
Fix this problem by adding the BH locking around napi-schedule(), in the same way it was done in commit e63052a5dd3c ("mlx5e: add add missing BH locking around napi_schdule()").
Its commit log provides the following explanation:
"It's not correct to call napi_schedule() in pure process context. Because we use __raise_softirq_irqoff() we require callers to be in a context which will eventually lead to softirq handling (hardirq, bh disabled, etc.).
With code as is users will see:
NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!! "
Fixes: cfee8793a74d ("ath10k: enable napi on RX path for sdio") Signed-off-by: Fabio Estevam festevam@denx.de Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210824144339.2796122-1-festevam@denx.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/sdio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index b746052737e0b..eb705214f3f0a 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -1363,8 +1363,11 @@ static void ath10k_rx_indication_async_work(struct work_struct *work) ep->ep_ops.ep_rx_complete(ar, skb); }
- if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) + if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) { + local_bh_disable(); napi_schedule(&ar->napi); + local_bh_enable(); + } }
static int ath10k_sdio_read_rtc_state(struct ath10k_sdio *ar_sdio, unsigned char *state)
From: Matthew Auld matthew.auld@intel.com
[ Upstream commit f5d28856b89baab4232a9f841e565763fcebcdf9 ]
In commit:
commit 09ac4fcb3f255e9225967c75f5893325c116cdbe Author: Felix Kuehling Felix.Kuehling@amd.com Date: Thu Jul 13 17:01:16 2017 -0400
drm/ttm: Implement vm_operations_struct.access v2
we added the vm_access hook, where we also directly call tt_swapin for some reason. If something is swapped-out then the ttm_tt must also be unpopulated, and since access_kmap should also call tt_populate, if needed, then swapping-in will already be handled there.
If anything, calling tt_swapin directly here would likely always fail since the tt->pages won't yet be populated, or worse since the tt->pages array is never actually cleared in unpopulate this might lead to a nasty uaf.
Fixes: 09ac4fcb3f25 ("drm/ttm: Implement vm_operations_struct.access v2") Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Thomas Hellström thomas.hellstrom@linux.intel.com Cc: Christian König christian.koenig@amd.com Reviewed-by: Thomas Hellström thomas.hellstrom@linux.intel.com Reviewed-by: Christian König christian.koenig@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20210927114114.152310-1-matthe... Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/ttm/ttm_bo_vm.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index f56be5bc0861e..5b9b7fd01a692 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -519,11 +519,6 @@ int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,
switch (bo->resource->mem_type) { case TTM_PL_SYSTEM: - if (unlikely(bo->ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)) { - ret = ttm_tt_swapin(bo->ttm); - if (unlikely(ret != 0)) - return ret; - } fallthrough; case TTM_PL_TT: ret = ttm_bo_vm_access_kmap(bo, offset, buf, len, write);
From: Sudarshan Rajagopalan quic_sudaraja@quicinc.com
[ Upstream commit 8fac67ca236b961b573355e203dbaf62a706a2e5 ]
After new memory blocks have been hotplugged, max_pfn and max_low_pfn needs updating to reflect on new PFNs being hot added to system. Without this patch, debug-related functions that use max_pfn such as get_max_dump_pfn() or read_page_owner() will not work with any page in memory that is hot-added after boot.
Fixes: 4ab215061554 ("arm64: Add memory hotplug support") Signed-off-by: Sudarshan Rajagopalan quic_sudaraja@quicinc.com Signed-off-by: Chris Goldsworthy quic_cgoldswo@quicinc.com Acked-by: David Hildenbrand david@redhat.com Cc: Florian Fainelli f.fainelli@gmail.com Cc: Georgi Djakov quic_c_gdjako@quicinc.com Tested-by: Georgi Djakov quic_c_gdjako@quicinc.com Link: https://lore.kernel.org/r/a51a27ee7be66024b5ce626310d673f24107bcb8.163285377... Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/mm/mmu.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index cfd9deb347c38..fd85b51b9d50f 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1499,6 +1499,11 @@ int arch_add_memory(int nid, u64 start, u64 size, if (ret) __remove_pgd_mapping(swapper_pg_dir, __phys_to_virt(start), size); + else { + max_pfn = PFN_UP(start + size); + max_low_pfn = max_pfn; + } + return ret; }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 335aea75b0d95518951cad7c4c676e6f1c02c150 ]
The overflow check in amdgpu_bo_list_create() causes a warning with clang-14 on 64-bit architectures, since the limit can never be exceeded.
drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c:74:18: error: result of comparison of constant 256204778801521549 with expression of type 'unsigned int' is always false [-Werror,-Wtautological-constant-out-of-range-compare] if (num_entries > (SIZE_MAX - sizeof(struct amdgpu_bo_list)) ~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The check remains useful for 32-bit architectures, so just avoid the warning by using size_t as the type for the count.
Fixes: 920990cb080a ("drm/amdgpu: allocate the bo_list array after the list") Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 15c45b2a39835..714178f1b6c6e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -61,7 +61,7 @@ static void amdgpu_bo_list_free(struct kref *ref)
int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, - unsigned num_entries, struct amdgpu_bo_list **result) + size_t num_entries, struct amdgpu_bo_list **result) { unsigned last_entry = 0, first_userptr = num_entries; struct amdgpu_bo_list_entry *array; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h index c905a4cfc173d..044b41f0bfd9c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h @@ -61,7 +61,7 @@ int amdgpu_bo_create_list_entry_array(struct drm_amdgpu_bo_list_in *in, int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, - unsigned num_entries, + size_t num_entries, struct amdgpu_bo_list **list);
static inline struct amdgpu_bo_list_entry *
From: Kumar Kartikeya Dwivedi memxor@gmail.com
[ Upstream commit e68ac0082787f4e8ee6ae5b19076ec7709ce715b ]
When the loader indicates an internal error (result of a checked bpf system call), it returns the result in attr.test.retval. However, tests that rely on ASSERT_OK_PTR on NULL (returned from light skeleton) may miss that NULL denotes an error if errno is set to 0. This would result in skel pointer being NULL, while ASSERT_OK_PTR returning 1, leading to a SEGV on dereference of skel, because libbpf_get_error relies on the assumption that errno is always set in case of error for ptr == NULL.
In particular, this was observed for the ksyms_module test. When executed using `./test_progs -t ksyms`, prior tests manipulated errno and the test didn't crash when it failed at ksyms_module load, while using `./test_progs -t ksyms_module` crashed due to errno being untouched.
Fixes: 67234743736a (libbpf: Generate loader program out of BPF ELF file.) Signed-off-by: Kumar Kartikeya Dwivedi memxor@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20210927145941.1383001-11-memxor@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/skel_internal.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/skel_internal.h b/tools/lib/bpf/skel_internal.h index b22b50c1b173e..9cf66702fa8dd 100644 --- a/tools/lib/bpf/skel_internal.h +++ b/tools/lib/bpf/skel_internal.h @@ -105,10 +105,12 @@ static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts) err = skel_sys_bpf(BPF_PROG_RUN, &attr, sizeof(attr)); if (err < 0 || (int)attr.test.retval < 0) { opts->errstr = "failed to execute loader prog"; - if (err < 0) + if (err < 0) { err = -errno; - else + } else { err = (int)attr.test.retval; + errno = -err; + } goto out; } err = 0;
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit 2c98b8a3458df03abdc6945bbef67ef91d181938 ]
If em28xx dev has ->dev_next pointer, we need to delete ->dev_next list node from em28xx_extension_devlist on disconnect to avoid UAF bugs and corrupted list bugs, since driver frees this pointer on disconnect.
Reported-and-tested-by: syzbot+a6969ef522a36d3344c9@syzkaller.appspotmail.com
Fixes: 1a23f81b7dc3 ("V4L/DVB (9979): em28xx: move usb probe code to a proper place") Signed-off-by: Pavel Skripkin paskripkin@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/em28xx/em28xx-cards.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index c1e0dccb74088..948e22e29b42a 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -4139,8 +4139,11 @@ static void em28xx_usb_disconnect(struct usb_interface *intf)
em28xx_close_extension(dev);
- if (dev->dev_next) + if (dev->dev_next) { + em28xx_close_extension(dev->dev_next); em28xx_release_resources(dev->dev_next); + } + em28xx_release_resources(dev);
if (dev->dev_next) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 4b9e3e8af4b336eefca1f1ee535bc4b6734ed6aa ]
There is likely a typo here. To be consistent, we should compare 'fmt.height' with 'ctx->out.pix_fmt.height', not 'ctx->out.pix_fmt.width'.
Instead of fixing the test, just remove it and copy 'fmt' unconditionally.
Fixes: 59a635327ca7 ("media: meson: Add M2M driver for the Amlogic GE2D Accelerator Unit") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Acked-by: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/meson/ge2d/ge2d.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/media/platform/meson/ge2d/ge2d.c b/drivers/media/platform/meson/ge2d/ge2d.c index a1393fefa8aea..9b1e973e78da3 100644 --- a/drivers/media/platform/meson/ge2d/ge2d.c +++ b/drivers/media/platform/meson/ge2d/ge2d.c @@ -779,11 +779,7 @@ static int ge2d_s_ctrl(struct v4l2_ctrl *ctrl) * If the rotation parameter changes the OUTPUT frames * parameters, take them in account */ - if (fmt.width != ctx->out.pix_fmt.width || - fmt.height != ctx->out.pix_fmt.width || - fmt.bytesperline > ctx->out.pix_fmt.bytesperline || - fmt.sizeimage > ctx->out.pix_fmt.sizeimage) - ctx->out.pix_fmt = fmt; + ctx->out.pix_fmt = fmt;
break; }
From: Colin Ian King colin.king@canonical.com
[ Upstream commit 11b982e950d2138e90bd120501df10a439006ff8 ]
Currently the null pointer check on dvb_spi->vcc_supply is inverted and this leads to only null values of the dvb_spi->vcc_supply being passed to the call of regulator_disable causing null pointer dereferences. Fix this by only calling regulator_disable if dvb_spi->vcc_supply is not null.
Addresses-Coverity: ("Dereference after null check")
Fixes: dcb014582101 ("media: cxd2880-spi: Fix an error handling path") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/spi/cxd2880-spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c index b91a1e845b972..506f52c1af101 100644 --- a/drivers/media/spi/cxd2880-spi.c +++ b/drivers/media/spi/cxd2880-spi.c @@ -618,7 +618,7 @@ fail_frontend: fail_attach: dvb_unregister_adapter(&dvb_spi->adapter); fail_adapter: - if (!dvb_spi->vcc_supply) + if (dvb_spi->vcc_supply) regulator_disable(dvb_spi->vcc_supply); fail_regulator: kfree(dvb_spi);
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 36b9d695aa6fb8e9a312db21af41f90824d16ab4 ]
ttusb_dec_send_command() invokes mutex_lock_interruptible() that can fail but then it releases the non-acquired mutex. The patch fixes that.
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: dba328bab4c6 ("media: ttusb-dec: cleanup an error handling logic") Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/ttusb-dec/ttusb_dec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index bfda46a36dc50..38822cedd93a9 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -327,7 +327,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, result = mutex_lock_interruptible(&dec->usb_mutex); if (result) { printk("%s: Failed to lock usb mutex.\n", __func__); - goto err; + goto err_free; }
b[0] = 0xaa; @@ -349,7 +349,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: command bulk message failed: error %d\n", __func__, result); - goto err; + goto err_mutex_unlock; }
result = usb_bulk_msg(dec->udev, dec->result_pipe, b, @@ -358,7 +358,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, if (result) { printk("%s: result bulk message failed: error %d\n", __func__, result); - goto err; + goto err_mutex_unlock; } else { if (debug) { printk(KERN_DEBUG "%s: result: %*ph\n", @@ -371,9 +371,9 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, memcpy(cmd_result, &b[4], b[3]); }
-err: +err_mutex_unlock: mutex_unlock(&dec->usb_mutex); - +err_free: kfree(b); return result; }
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit afae4ef7d5ad913cab1316137854a36bea6268a5 ]
Syzbot reported ununit-value bug in az6027_rc_query(). The problem was in missing state pointer initialization. Since this function does nothing we can simply initialize state to REMOTE_NO_KEY_PRESSED.
Reported-and-tested-by: syzbot+2cd8c5db4a85f0a04142@syzkaller.appspotmail.com
Fixes: 76f9a820c867 ("V4L/DVB: AZ6027: Initial import of the driver") Signed-off-by: Pavel Skripkin paskripkin@gmail.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/dvb-usb/az6027.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index 1c39b61cde29b..86788771175b7 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -391,6 +391,7 @@ static struct rc_map_table rc_map_az6027_table[] = { /* remote control stuff (does not work with my box) */ static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { + *state = REMOTE_NO_KEY_PRESSED; return 0; }
From: Sakari Ailus sakari.ailus@linux.intel.com
[ Upstream commit d170b0ea1760989fe8ac053bef83e61f3bf87992 ]
Obtain the clock frequency by reading the clock-frequency property if there's no clock.
Fixes: 9fda25332c4b ("media: i2c: imx258: get clock from device properties and enable it via runtime PM") Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx258.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index 81cdf37216ca7..c249507aa2dbc 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -1260,18 +1260,18 @@ static int imx258_probe(struct i2c_client *client) return -ENOMEM;
imx258->clk = devm_clk_get_optional(&client->dev, NULL); + if (IS_ERR(imx258->clk)) + return dev_err_probe(&client->dev, PTR_ERR(imx258->clk), + "error getting clock\n"); if (!imx258->clk) { dev_dbg(&client->dev, "no clock provided, using clock-frequency property\n");
device_property_read_u32(&client->dev, "clock-frequency", &val); - if (val != IMX258_INPUT_CLOCK_FREQ) - return -EINVAL; - } else if (IS_ERR(imx258->clk)) { - return dev_err_probe(&client->dev, PTR_ERR(imx258->clk), - "error getting clock\n"); + } else { + val = clk_get_rate(imx258->clk); } - if (clk_get_rate(imx258->clk) != IMX258_INPUT_CLOCK_FREQ) { + if (val != IMX258_INPUT_CLOCK_FREQ) { dev_err(&client->dev, "input clock frequency not supported\n"); return -EINVAL; }
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit c87ed93574e3cd8346c05bd934c617596c12541b ]
If the driver does not implement s_ctrl, but it does implement s_ext_ctrls, we convert the call.
When that happens we have also to convert back the response from s_ext_ctrls.
Fixes v4l2_compliance: Control ioctls (Input 0): fail: v4l2-test-controls.cpp(411): returned control value out of range fail: v4l2-test-controls.cpp(507): invalid control 00980900 test VIDIOC_G/S_CTRL: FAIL
Fixes: 35ea11ff8471 ("V4L/DVB (8430): videodev: move some functions from v4l2-dev.h to v4l2-common.h or v4l2-ioctl.h") Reviewed-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/v4l2-core/v4l2-ioctl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index da5b4002a466a..f4f67b385d00a 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2224,6 +2224,7 @@ static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; struct v4l2_ext_controls ctrls; struct v4l2_ext_control ctrl; + int ret;
if (vfh && vfh->ctrl_handler) return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); @@ -2239,9 +2240,11 @@ static int v4l_s_ctrl(const struct v4l2_ioctl_ops *ops, ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) - return ops->vidioc_s_ext_ctrls(file, fh, &ctrls); - return -EINVAL; + if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) + return -EINVAL; + ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); + p->value = ctrl.value; + return ret; }
static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
From: Dafna Hirschfeld dafna.hirschfeld@collabora.com
[ Upstream commit 065a7c66bd8b21db212fa86187ff12f0cac6ea6d ]
In case vb2ops_venc_start_streaming fails, the error value is overwritten by the ret value of pm_runtime_put which might be 0. Fix it.
Fixes: 985c73693fe5a (" media: mtk-vcodec: Separating mtk encoder driver") Signed-off-by: Dafna Hirschfeld dafna.hirschfeld@collabora.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c index 416f356af363d..d97a6765693f1 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -793,7 +793,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) { struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q); struct venc_enc_param param; - int ret; + int ret, pm_ret; int i;
/* Once state turn into MTK_STATE_ABORT, we need stop_streaming @@ -845,9 +845,9 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count) return 0;
err_set_param: - ret = pm_runtime_put(&ctx->dev->plat_dev->dev); - if (ret < 0) - mtk_v4l2_err("pm_runtime_put fail %d", ret); + pm_ret = pm_runtime_put(&ctx->dev->plat_dev->dev); + if (pm_ret < 0) + mtk_v4l2_err("pm_runtime_put fail %d", pm_ret);
err_start_stream: for (i = 0; i < q->num_buffers; ++i) {
From: Tom Rix trix@redhat.com
[ Upstream commit 48d219f9cc667bc6fbc3e3af0b1bfd75db94fce4 ]
Static analysis reports this representative problem
tda1997x.c:1939: warning: 7th function call argument is an uninitialized value
The 7th argument is buffer[0], which is set in the earlier call to io_readn(). When io_readn() call to io_read() fails with the first read, buffer[0] is not set and 0 is returned and stored in len.
The later call to hdmi_infoframe_unpack()'s size parameter is the static size of buffer, always 40, so a short read is not caught in hdmi_infoframe_unpacks()'s checking. The variable len should be used instead.
Zero initialize buffer to 0 so it is in a known start state.
Fixes: 9ac0038db9a7 ("media: i2c: Add TDA1997x HDMI receiver driver") Signed-off-by: Tom Rix trix@redhat.com Reviewed-by: Tim Harvey tharvey@gateworks.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/tda1997x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 6070aaf0b32ea..4dafa9f1cf522 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -1248,13 +1248,13 @@ tda1997x_parse_infoframe(struct tda1997x_state *state, u16 addr) { struct v4l2_subdev *sd = &state->sd; union hdmi_infoframe frame; - u8 buffer[40]; + u8 buffer[40] = { 0 }; u8 reg; int len, err;
/* read data */ len = io_readn(sd, addr, sizeof(buffer), buffer); - err = hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)); + err = hdmi_infoframe_unpack(&frame, buffer, len); if (err) { v4l_err(state->client, "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", @@ -1928,13 +1928,13 @@ static int tda1997x_log_infoframe(struct v4l2_subdev *sd, int addr) { struct tda1997x_state *state = to_state(sd); union hdmi_infoframe frame; - u8 buffer[40]; + u8 buffer[40] = { 0 }; int len, err;
/* read data */ len = io_readn(sd, addr, sizeof(buffer), buffer); v4l2_dbg(1, debug, sd, "infoframe: addr=%d len=%d\n", addr, len); - err = hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)); + err = hdmi_infoframe_unpack(&frame, buffer, len); if (err) { v4l_err(state->client, "failed parsing %d byte infoframe: 0x%04x/0x%02x\n",
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 2143ad413c05c7be24c3a92760e367b7f6aaac92 ]
A successful 'clk_prepare()' call should be balanced by a corresponding 'clk_unprepare()' call in the error handling path of the probe, as already done in the remove function.
Update the error handling path accordingly.
Fixes: 3003a180ef6b ("[media] VPU: mediatek: support Mediatek VPU") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Houlong Wei houlong.wei@mediatek.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/mtk-vpu/mtk_vpu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c index ec290dde59cfd..7f1647da0ade0 100644 --- a/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -848,7 +848,8 @@ static int mtk_vpu_probe(struct platform_device *pdev) vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt"); if (!vpu->wdt.wq) { dev_err(dev, "initialize wdt workqueue failed\n"); - return -ENOMEM; + ret = -ENOMEM; + goto clk_unprepare; } INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func); mutex_init(&vpu->vpu_mutex); @@ -942,6 +943,8 @@ disable_vpu_clk: vpu_clock_disable(vpu); workqueue_destroy: destroy_workqueue(vpu->wdt.wq); +clk_unprepare: + clk_unprepare(vpu->clk);
return ret; }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 5c47dc6657543b3c4dffcbe741fb693b9b96796d ]
A successful 'mxc_jpeg_attach_pm_domains()' call should be balanced by a corresponding 'mxc_jpeg_detach_pm_domains()' call in the error handling path of the probe, as already done in the remove function.
Update the error handling path accordingly.
Fixes: 2db16c6ed72c ("media: imx-jpeg: Add V4L2 driver for i.MX8 JPEG Encoder/Decoder") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/imx-jpeg/mxc-jpeg.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c index 33e7604271cdf..fc905ea78b175 100644 --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c @@ -2092,6 +2092,8 @@ err_m2m: v4l2_device_unregister(&jpeg->v4l2_dev);
err_register: + mxc_jpeg_detach_pm_domains(jpeg); + err_irq: return ret; }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit e4625044d656f3c33ece0cc9da22577bc10ca5d3 ]
Fix the build errors reported by the kernel test robot by selecting V4L2_ASYNC:
mips-linux-ld: drivers/media/i2c/ths8200.o: in function `ths8200_remove': ths8200.c:(.text+0x1ec): undefined reference to `v4l2_async_unregister_subdev' mips-linux-ld: drivers/media/i2c/ths8200.o: in function `ths8200_probe': ths8200.c:(.text+0x404): undefined reference to `v4l2_async_register_subdev'
Fixes: ed29f89497006 ("media: i2c: ths8200: support asynchronous probing") Signed-off-by: Randy Dunlap rdunlap@infradead.org Reported-by: kernel test robot lkp@intel.com Reviewed-by: Lad Prabhakar prabhakar.csengg@gmail.com Acked-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 08feb3e8c1bf6..6157e73eef24e 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -597,6 +597,7 @@ config VIDEO_AK881X config VIDEO_THS8200 tristate "Texas Instruments THS8200 video encoder" depends on VIDEO_V4L2 && I2C + select V4L2_ASYNC help Support for the Texas Instruments THS8200 video encoder.
From: Ondrej Jirman megous@megous.com
[ Upstream commit 8ed852834683ebe064157e069af8dfb41cad6403 ]
Previously it was possible, but a recent fix for uninitialized `ret` variable broke this behavior.
v4l2_fh_is_singular_file() check is there just to determine whether the power needs to be enabled, and it's not a failure if it returns false.
Fixes: ba9139116bc0 ("media: sun6i-csi: add a missing return code") Signed-off-by: Ondrej Jirman megous@megous.com Reviewed-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c index 07b2161392d21..5ba3e29f794fd 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -467,7 +467,7 @@ static const struct v4l2_ioctl_ops sun6i_video_ioctl_ops = { static int sun6i_video_open(struct file *file) { struct sun6i_video *video = video_drvdata(file); - int ret; + int ret = 0;
if (mutex_lock_interruptible(&video->lock)) return -ERESTARTSYS; @@ -481,10 +481,8 @@ static int sun6i_video_open(struct file *file) goto fh_release;
/* check if already powered */ - if (!v4l2_fh_is_singular_file(file)) { - ret = -EBUSY; + if (!v4l2_fh_is_singular_file(file)) goto unlock; - }
ret = sun6i_csi_set_power(video->csi, true); if (ret < 0)
From: Kees Cook keescook@chromium.org
[ Upstream commit dfadec236aa99f6086141949c9dc3ec50f3ff20d ]
The "card" string only holds 31 characters (and the terminating NUL). In order to avoid truncation, use a shorter card description instead of the current result, "Texas Instruments Wl1273 FM Rad".
Suggested-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: 87d1a50ce451 ("[media] V4L2: WL1273 FM Radio: TI WL1273 FM radio driver") Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/radio/radio-wl1273.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index 1123768731676..484046471c03f 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -1279,7 +1279,7 @@ static int wl1273_fm_vidioc_querycap(struct file *file, void *priv,
strscpy(capability->driver, WL1273_FM_DRIVER_NAME, sizeof(capability->driver)); - strscpy(capability->card, "Texas Instruments Wl1273 FM Radio", + strscpy(capability->card, "TI Wl1273 FM Radio", sizeof(capability->card)); strscpy(capability->bus_info, radio->bus_type, sizeof(capability->bus_info));
From: Kees Cook keescook@chromium.org
[ Upstream commit 2908249f3878a591f7918368fdf0b7b0a6c3158c ]
The "card" string only holds 31 characters (and the terminating NUL). In order to avoid truncation, use a shorter card description instead of the current result, "Silicon Labs Si470x FM Radio Re".
Suggested-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: 78656acdcf48 ("V4L/DVB (7038): USB radio driver for Silicon Labs Si470x FM Radio Receivers") Fixes: cc35bbddfe10 ("V4L/DVB (12416): radio-si470x: add i2c driver for si470x") Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/radio/si470x/radio-si470x-i2c.c | 2 +- drivers/media/radio/si470x/radio-si470x-usb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index f491420d7b538..a972c0705ac79 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -11,7 +11,7 @@
/* driver definitions */ #define DRIVER_AUTHOR "Joonyoung Shim jy0922.shim@samsung.com"; -#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" +#define DRIVER_CARD "Silicon Labs Si470x FM Radio" #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers" #define DRIVER_VERSION "1.0.2"
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index fedff68d8c496..3f8634a465730 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -16,7 +16,7 @@
/* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz tobias.lorenz@gmx.net" -#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" +#define DRIVER_CARD "Silicon Labs Si470x FM Radio" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" #define DRIVER_VERSION "1.0.10"
From: Kees Cook keescook@chromium.org
[ Upstream commit 42bb98e420d454fef3614b70ea11cc59068395f6 ]
The "card" string only holds 31 characters (and the terminating NUL). In order to avoid truncation, use a shorter card description instead of the current result, "Trident TVMaster TM5600/6000/60".
Suggested-by: Hans Verkuil hverkuil-cisco@xs4all.nl Fixes: e28f49b0b2a8 ("V4L/DVB: tm6000: fix some info messages") Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/tm6000/tm6000-video.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 3f650ede0c3dc..e293f6f3d1bc9 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -852,8 +852,7 @@ static int vidioc_querycap(struct file *file, void *priv, struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
strscpy(cap->driver, "tm6000", sizeof(cap->driver)); - strscpy(cap->card, "Trident TVMaster TM5600/6000/6010", - sizeof(cap->card)); + strscpy(cap->card, "Trident TM5600/6000/6010", sizeof(cap->card)); usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS;
From: Colin Ian King colin.king@canonical.com
[ Upstream commit 7266dda2f1dfe151b12ef0c14eb4d4e622fb211c ]
Currently a call to snd_card_new that fails will set card with a NULL pointer, this causes a null pointer dereference on the error cleanup path when card it passed to snd_card_free. Fix this by adding a new error exit path that does not call snd_card_free and exiting via this new path.
Addresses-Coverity: ("Explicit null dereference")
Fixes: 9e44d63246a9 ("[media] cx23885: Add ALSA support") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/cx23885/cx23885-alsa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index ab14d35214aa8..25dc8d4dc5b73 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -550,7 +550,7 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev) SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, THIS_MODULE, sizeof(struct cx23885_audio_dev), &card); if (err < 0) - goto error; + goto error_msg;
chip = (struct cx23885_audio_dev *) card->private_data; chip->dev = dev; @@ -576,6 +576,7 @@ struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev)
error: snd_card_free(card); +error_msg: pr_err("%s(): Failed to register analog audio adapter\n", __func__);
From: Eugen Hristev eugen.hristev@microchip.com
[ Upstream commit d7f26849ed7cc875d0ff7480c2efebeeccea2bad ]
The runtime enabling of the ISPCK (internally clocks the pipeline inside the ISC) has to be done after the pm_runtime for the ISC dev has been started.
After the commit by Mauro: the ISC failed to probe with the error:
atmel-sama5d2-isc f0008000.isc: failed to enable ispck: -13 atmel-sama5d2-isc: probe of f0008000.isc failed with error -13
This is because the enabling of the ispck is done too early in the probe, and the PM runtime returns invalid request. Thus, moved this clock enabling after pm_runtime_idle is called.
The ISPCK is required only for sama5d2 type of ISC. Thus, add a bool inside the isc struct that is platform dependent. For the sama7g5-isc, the enabling of the ISPCK is wrong and does not make sense. Removed it from the sama7g5 probe. In sama7g5-isc, there is only one clock, the MCK, which also clocks the internal pipeline of the ISC.
Adapted the clk_prepare and clk_unprepare to request the runtime PM for both clocks (MCK and ISPCK) in case of sama5d2-isc, and the single clock (MCK) in case of sama7g5-isc.
Fixes: dd97908ee350 ("media: atmel: properly get pm_runtime") Signed-off-by: Eugen Hristev eugen.hristev@microchip.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/atmel/atmel-isc-base.c | 25 ++++++------ drivers/media/platform/atmel/atmel-isc.h | 2 + .../media/platform/atmel/atmel-sama5d2-isc.c | 39 ++++++++++--------- .../media/platform/atmel/atmel-sama7g5-isc.c | 22 ++--------- 4 files changed, 38 insertions(+), 50 deletions(-)
diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 136ab7cf36edc..ebf264b980f91 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -123,11 +123,9 @@ static int isc_clk_prepare(struct clk_hw *hw) struct isc_clk *isc_clk = to_isc_clk(hw); int ret;
- if (isc_clk->id == ISC_ISPCK) { - ret = pm_runtime_resume_and_get(isc_clk->dev); - if (ret < 0) - return ret; - } + ret = pm_runtime_resume_and_get(isc_clk->dev); + if (ret < 0) + return ret;
return isc_wait_clk_stable(hw); } @@ -138,8 +136,7 @@ static void isc_clk_unprepare(struct clk_hw *hw)
isc_wait_clk_stable(hw);
- if (isc_clk->id == ISC_ISPCK) - pm_runtime_put_sync(isc_clk->dev); + pm_runtime_put_sync(isc_clk->dev); }
static int isc_clk_enable(struct clk_hw *hw) @@ -186,16 +183,13 @@ static int isc_clk_is_enabled(struct clk_hw *hw) u32 status; int ret;
- if (isc_clk->id == ISC_ISPCK) { - ret = pm_runtime_resume_and_get(isc_clk->dev); - if (ret < 0) - return 0; - } + ret = pm_runtime_resume_and_get(isc_clk->dev); + if (ret < 0) + return 0;
regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
- if (isc_clk->id == ISC_ISPCK) - pm_runtime_put_sync(isc_clk->dev); + pm_runtime_put_sync(isc_clk->dev);
return status & ISC_CLK(isc_clk->id) ? 1 : 0; } @@ -325,6 +319,9 @@ static int isc_clk_register(struct isc_device *isc, unsigned int id) const char *parent_names[3]; int num_parents;
+ if (id == ISC_ISPCK && !isc->ispck_required) + return 0; + num_parents = of_clk_get_parent_count(np); if (num_parents < 1 || num_parents > 3) return -EINVAL; diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h index 19cc60dfcbe0f..2bfcb135ef13b 100644 --- a/drivers/media/platform/atmel/atmel-isc.h +++ b/drivers/media/platform/atmel/atmel-isc.h @@ -178,6 +178,7 @@ struct isc_reg_offsets { * @hclock: Hclock clock input (refer datasheet) * @ispck: iscpck clock (refer datasheet) * @isc_clks: ISC clocks + * @ispck_required: ISC requires ISP Clock initialization * @dcfg: DMA master configuration, architecture dependent * * @dev: Registered device driver @@ -252,6 +253,7 @@ struct isc_device { struct clk *hclock; struct clk *ispck; struct isc_clk isc_clks[2]; + bool ispck_required; u32 dcfg;
struct device *dev; diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index b66f1d174e9d7..e29a9193bac81 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -454,6 +454,9 @@ static int atmel_isc_probe(struct platform_device *pdev) /* sama5d2-isc - 8 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8;
+ /* sama5d2-isc : ISPCK is required and mandatory */ + isc->ispck_required = true; + ret = isc_pipeline_init(isc); if (ret) return ret; @@ -476,22 +479,6 @@ static int atmel_isc_probe(struct platform_device *pdev) dev_err(dev, "failed to init isc clock: %d\n", ret); goto unprepare_hclk; } - - isc->ispck = isc->isc_clks[ISC_ISPCK].clk; - - ret = clk_prepare_enable(isc->ispck); - if (ret) { - dev_err(dev, "failed to enable ispck: %d\n", ret); - goto unprepare_hclk; - } - - /* ispck should be greater or equal to hclock */ - ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); - if (ret) { - dev_err(dev, "failed to set ispck rate: %d\n", ret); - goto unprepare_clk; - } - ret = v4l2_device_register(dev, &isc->v4l2_dev); if (ret) { dev_err(dev, "unable to register v4l2 device.\n"); @@ -545,19 +532,35 @@ static int atmel_isc_probe(struct platform_device *pdev) pm_runtime_enable(dev); pm_request_idle(dev);
+ isc->ispck = isc->isc_clks[ISC_ISPCK].clk; + + ret = clk_prepare_enable(isc->ispck); + if (ret) { + dev_err(dev, "failed to enable ispck: %d\n", ret); + goto cleanup_subdev; + } + + /* ispck should be greater or equal to hclock */ + ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); + if (ret) { + dev_err(dev, "failed to set ispck rate: %d\n", ret); + goto unprepare_clk; + } + regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver); dev_info(dev, "Microchip ISC version %x\n", ver);
return 0;
+unprepare_clk: + clk_disable_unprepare(isc->ispck); + cleanup_subdev: isc_subdev_cleanup(isc);
unregister_v4l2_device: v4l2_device_unregister(&isc->v4l2_dev);
-unprepare_clk: - clk_disable_unprepare(isc->ispck); unprepare_hclk: clk_disable_unprepare(isc->hclock);
diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c index f2785131ff569..9c05acafd0724 100644 --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c @@ -447,6 +447,9 @@ static int microchip_xisc_probe(struct platform_device *pdev) /* sama7g5-isc RAM access port is full AXI4 - 32 bits per beat */ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS32 | ISC_DCFG_CMBSIZE_BEATS32;
+ /* sama7g5-isc : ISPCK does not exist, ISC is clocked by MCK */ + isc->ispck_required = false; + ret = isc_pipeline_init(isc); if (ret) return ret; @@ -470,25 +473,10 @@ static int microchip_xisc_probe(struct platform_device *pdev) goto unprepare_hclk; }
- isc->ispck = isc->isc_clks[ISC_ISPCK].clk; - - ret = clk_prepare_enable(isc->ispck); - if (ret) { - dev_err(dev, "failed to enable ispck: %d\n", ret); - goto unprepare_hclk; - } - - /* ispck should be greater or equal to hclock */ - ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); - if (ret) { - dev_err(dev, "failed to set ispck rate: %d\n", ret); - goto unprepare_clk; - } - ret = v4l2_device_register(dev, &isc->v4l2_dev); if (ret) { dev_err(dev, "unable to register v4l2 device.\n"); - goto unprepare_clk; + goto unprepare_hclk; }
ret = xisc_parse_dt(dev, isc); @@ -549,8 +537,6 @@ cleanup_subdev: unregister_v4l2_device: v4l2_device_unregister(&isc->v4l2_dev);
-unprepare_clk: - clk_disable_unprepare(isc->ispck); unprepare_hclk: clk_disable_unprepare(isc->hclock);
From: Yee Lee yee.lee@mediatek.com
[ Upstream commit 528a4ab45300fa6283556d9b48e26b45a8aa15c4 ]
Since scs allocation is moved to vmalloc region, the shadow stack is protected by kasan_posion_vmalloc. However, the vfree_atomic operation needs to access its context for scs_free process and causes kasan error as the dump info below.
This patch Adds kasan_unpoison_vmalloc() before vfree_atomic, which aligns to the prior flow as using kmem_cache. The vmalloc region will go back posioned in the following vumap() operations.
================================================================== BUG: KASAN: vmalloc-out-of-bounds in llist_add_batch+0x60/0xd4 Write of size 8 at addr ffff8000100b9000 by task kthreadd/2
CPU: 0 PID: 2 Comm: kthreadd Not tainted 5.15.0-rc2-11681-g92477dd1faa6-dirty #1 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace+0x0/0x43c show_stack+0x1c/0x2c dump_stack_lvl+0x68/0x84 print_address_description+0x80/0x394 kasan_report+0x180/0x1dc __asan_report_store8_noabort+0x48/0x58 llist_add_batch+0x60/0xd4 vfree_atomic+0x60/0xe0 scs_free+0x1dc/0x1fc scs_release+0xa4/0xd4 free_task+0x30/0xe4 __put_task_struct+0x1ec/0x2e0 delayed_put_task_struct+0x5c/0xa0 rcu_do_batch+0x62c/0x8a0 rcu_core+0x60c/0xc14 rcu_core_si+0x14/0x24 __do_softirq+0x19c/0x68c irq_exit+0x118/0x2dc handle_domain_irq+0xcc/0x134 gic_handle_irq+0x7c/0x1bc call_on_irq_stack+0x40/0x70 do_interrupt_handler+0x78/0x9c el1_interrupt+0x34/0x60 el1h_64_irq_handler+0x1c/0x2c el1h_64_irq+0x78/0x7c _raw_spin_unlock_irqrestore+0x40/0xcc sched_fork+0x4f0/0xb00 copy_process+0xacc/0x3648 kernel_clone+0x168/0x534 kernel_thread+0x13c/0x1b0 kthreadd+0x2bc/0x400 ret_from_fork+0x10/0x20
Memory state around the buggy address: ffff8000100b8f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffff8000100b8f80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
ffff8000100b9000: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
^ ffff8000100b9080: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ffff8000100b9100: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 ==================================================================
Suggested-by: Kuan-Ying Lee kuan-ying.lee@mediatek.com Acked-by: Will Deacon will@kernel.org Tested-by: Will Deacon will@kernel.org Reviewed-by: Sami Tolvanen samitolvanen@google.com Signed-off-by: Yee Lee yee.lee@mediatek.com Fixes: a2abe7cbd8fe ("scs: switch to vmapped shadow stacks") Link: https://lore.kernel.org/r/20210930081619.30091-1-yee.lee@mediatek.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/scs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/kernel/scs.c b/kernel/scs.c index e2a71fc82fa06..579841be88646 100644 --- a/kernel/scs.c +++ b/kernel/scs.c @@ -78,6 +78,7 @@ void scs_free(void *s) if (this_cpu_cmpxchg(scs_cache[i], 0, s) == NULL) return;
+ kasan_unpoison_vmalloc(s, SCS_SIZE); vfree_atomic(s); }
From: Punit Agrawal punitagrawal@gmail.com
[ Upstream commit 8f7262cd66699a4b02eb7549b35c81b2116aad95 ]
debugfs_create_file() takes a pointer argument that can be used during file operation callbacks (accessible via i_private in the inode structure). An obvious requirement is for the pointer to refer to valid memory when used.
When creating the debugfs file to dynamically enable / disable kprobes, a pointer to local variable is passed to debugfs_create_file(); which will go out of scope when the init function returns. The reason this hasn't triggered random memory corruption is because the pointer is not accessed during the debugfs file callbacks.
Since the enabled state is managed by the kprobes_all_disabled global variable, the local variable is not needed. Fix the incorrect (and unnecessary) usage of local variable during debugfs_file_create() by passing NULL instead.
Link: https://lkml.kernel.org/r/163163031686.489837.4476867635937014973.stgit@devn...
Fixes: bf8f6e5b3e51 ("Kprobes: The ON/OFF knob thru debugfs") Signed-off-by: Punit Agrawal punitagrawal@gmail.com Acked-by: Masami Hiramatsu mhiramat@kernel.org 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/kprobes.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 790a573bbe00c..1cf8bca1ea861 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -2809,13 +2809,12 @@ static const struct file_operations fops_kp = { static int __init debugfs_kprobe_init(void) { struct dentry *dir; - unsigned int value = 1;
dir = debugfs_create_dir("kprobes", NULL);
debugfs_create_file("list", 0400, dir, NULL, &kprobes_fops);
- debugfs_create_file("enabled", 0600, dir, &value, &fops_kp); + debugfs_create_file("enabled", 0600, dir, NULL, &fops_kp);
debugfs_create_file("blacklist", 0400, dir, NULL, &kprobe_blacklist_fops);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 38aa192a05f22f9778f9420e630f0322525ef12e ]
The ecc.c file started out as part of the ECDH algorithm but got moved out into a standalone module later. It does not build without CRYPTO_DEFAULT_RNG, so now that other modules are using it as well we can run into this link error:
aarch64-linux-ld: ecc.c:(.text+0xfc8): undefined reference to `crypto_default_rng' aarch64-linux-ld: ecc.c:(.text+0xff4): undefined reference to `crypto_put_default_rng'
Move the 'select CRYPTO_DEFAULT_RNG' statement into the correct symbol.
Fixes: 0d7a78643f69 ("crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm") Fixes: 4e6602916bc6 ("crypto: ecdsa - Add support for ECDSA signature verification") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Stefan Berger stefanb@linux.ibm.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crypto/Kconfig b/crypto/Kconfig index 536df4b6b825c..285f82647d2b7 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -233,12 +233,12 @@ config CRYPTO_DH
config CRYPTO_ECC tristate + select CRYPTO_RNG_DEFAULT
config CRYPTO_ECDH tristate "ECDH algorithm" select CRYPTO_ECC select CRYPTO_KPP - select CRYPTO_RNG_DEFAULT help Generic implementation of the ECDH algorithm
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 606b102876e3741851dfb09d53f3ee57f650a52c ]
With CONFIG_FB=m and CONFIG_DRM=y, we get a link error in the fb helper:
aarch64-linux-ld: drivers/gpu/drm/drm_fb_helper.o: in function `drm_fb_helper_alloc_fbi': (.text+0x10cc): undefined reference to `framebuffer_alloc'
Tighten the dependency so it is only allowed in the case that DRM can link against FB.
Fixes: f611b1e7624c ("drm: Avoid circular dependencies for CONFIG_FB") Link: https://lore.kernel.org/all/20210721152211.2706171-1-arnd@kernel.org/ Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Kees Cook keescook@chromium.org Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20210927142816.2069269-1-arnd@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index cea777ae7fb92..9199f53861cac 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -103,7 +103,7 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" depends on DRM - depends on FB + depends on FB=y || FB=DRM select DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA
From: Anel Orazgaliyeva anelkz@amazon.de
[ Upstream commit e5f5a66c9aa9c331da5527c2e3fd9394e7091e01 ]
Commit c343bf1ba5ef ("cpuidle: Fix three reference count leaks") fixes the cleanup of kobjects; however, it removes kfree() calls altogether, leading to memory leaks.
Fix those and also defer the initialization of dev->kobj_dev until after the error check, so that we do not end up with a dangling pointer.
Fixes: c343bf1ba5ef ("cpuidle: Fix three reference count leaks") Signed-off-by: Anel Orazgaliyeva anelkz@amazon.de Suggested-by: Aman Priyadarshi apeureka@amazon.de [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpuidle/sysfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 53ec9585ccd44..469e18547d06c 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -488,6 +488,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) &kdev->kobj, "state%d", i); if (ret) { kobject_put(&kobj->kobj); + kfree(kobj); goto error_state; } cpuidle_add_s2idle_attr_group(kobj); @@ -619,6 +620,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) &kdev->kobj, "driver"); if (ret) { kobject_put(&kdrv->kobj); + kfree(kdrv); return ret; }
@@ -705,7 +707,6 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) if (!kdev) return -ENOMEM; kdev->dev = dev; - dev->kobj_dev = kdev;
init_completion(&kdev->kobj_unregister);
@@ -713,9 +714,11 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) "cpuidle"); if (error) { kobject_put(&kdev->kobj); + kfree(kdev); return error; }
+ dev->kobj_dev = kdev; kobject_uevent(&kdev->kobj, KOBJ_ADD);
return 0;
From: Colin Ian King colin.king@canonical.com
[ Upstream commit 51fa3b70d27342baf1ea8aaab3e96e5f4f26d5b2 ]
The call to ops->suspend for the dev->dev_next case can currently trigger a call on a null function pointer if ops->suspend is null. Skip over the use of function ops->suspend if it is null.
Addresses-Coverity: ("Dereference after null check")
Fixes: be7fd3c3a8c5 ("media: em28xx: Hauppauge DualHD second tuner functionality") Signed-off-by: Colin Ian King colin.king@canonical.com Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/em28xx/em28xx-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 584fa400cd7d8..acc0bf7dbe2b1 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -1154,8 +1154,9 @@ int em28xx_suspend_extension(struct em28xx *dev) dev_info(&dev->intf->dev, "Suspending extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { - if (ops->suspend) - ops->suspend(dev); + if (!ops->suspend) + continue; + ops->suspend(dev); if (dev->dev_next) ops->suspend(dev->dev_next); }
From: Stephen Boyd swboyd@chromium.org
[ Upstream commit 747ff7d3d7424876111b7559b7f6704762f89796 ]
When rebooting on sc7180 Trogdor devices I see the following crash from the wifi driver.
ath10k_snoc 18800000.wifi: firmware crashed! (guid 83493570-29a2-4e98-a83e-70048c47669c)
This is because a modem stop event looks just like a firmware crash to the driver, the qmi connection is closed in both cases. Use the qcom ssr notifier block to stop treating the qmi connection close event as a firmware crash signal when the modem hasn't actually crashed. See ath10k_qmi_event_server_exit() for more details.
This silences the crash message seen during every reboot.
Fixes: 3f14b73c3843 ("ath10k: Enable MSA region dump support for WCN3990") Cc: Youghandhar Chintala youghand@codeaurora.org Cc: Abhishek Kumar kuabhs@chromium.org Cc: Steev Klimaszewski steev@kali.org Cc: Matthias Kaehlcke mka@chromium.org Cc: Rakesh Pillai pillair@codeaurora.org Signed-off-by: Stephen Boyd swboyd@chromium.org Reviewed-by: Rakesh Pillai pillair@codeaurora.org Tested-By: Youghandhar Chintala youghand@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210922233341.182624-1-swboyd@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/qmi.c | 3 +- drivers/net/wireless/ath/ath10k/snoc.c | 77 ++++++++++++++++++++++++++ drivers/net/wireless/ath/ath10k/snoc.h | 5 ++ 3 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c index 07e478f9a808c..80fcb917fe4e1 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.c +++ b/drivers/net/wireless/ath/ath10k/qmi.c @@ -864,7 +864,8 @@ static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi)
ath10k_qmi_remove_msa_permission(qmi); ath10k_core_free_board_files(ar); - if (!test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags)) + if (!test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags) && + !test_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags)) ath10k_snoc_fw_crashed_dump(ar);
ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND); diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c index ea00fbb156015..9513ab696fff1 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.c +++ b/drivers/net/wireless/ath/ath10k/snoc.c @@ -12,6 +12,7 @@ #include <linux/platform_device.h> #include <linux/property.h> #include <linux/regulator/consumer.h> +#include <linux/remoteproc/qcom_rproc.h> #include <linux/of_address.h> #include <linux/iommu.h>
@@ -1477,6 +1478,74 @@ void ath10k_snoc_fw_crashed_dump(struct ath10k *ar) mutex_unlock(&ar->dump_mutex); }
+static int ath10k_snoc_modem_notify(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct ath10k_snoc *ar_snoc = container_of(nb, struct ath10k_snoc, nb); + struct ath10k *ar = ar_snoc->ar; + struct qcom_ssr_notify_data *notify_data = data; + + switch (action) { + case QCOM_SSR_BEFORE_POWERUP: + ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem starting event\n"); + clear_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags); + break; + + case QCOM_SSR_AFTER_POWERUP: + ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem running event\n"); + break; + + case QCOM_SSR_BEFORE_SHUTDOWN: + ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem %s event\n", + notify_data->crashed ? "crashed" : "stopping"); + if (!notify_data->crashed) + set_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags); + else + clear_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags); + break; + + case QCOM_SSR_AFTER_SHUTDOWN: + ath10k_dbg(ar, ATH10K_DBG_SNOC, "received modem offline event\n"); + break; + + default: + ath10k_err(ar, "received unrecognized event %lu\n", action); + break; + } + + return NOTIFY_OK; +} + +static int ath10k_modem_init(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + void *notifier; + int ret; + + ar_snoc->nb.notifier_call = ath10k_snoc_modem_notify; + + notifier = qcom_register_ssr_notifier("mpss", &ar_snoc->nb); + if (IS_ERR(notifier)) { + ret = PTR_ERR(notifier); + ath10k_err(ar, "failed to initialize modem notifier: %d\n", ret); + return ret; + } + + ar_snoc->notifier = notifier; + + return 0; +} + +static void ath10k_modem_deinit(struct ath10k *ar) +{ + int ret; + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + + ret = qcom_unregister_ssr_notifier(ar_snoc->notifier, &ar_snoc->nb); + if (ret) + ath10k_err(ar, "error %d unregistering notifier\n", ret); +} + static int ath10k_setup_msa_resources(struct ath10k *ar, u32 msa_size) { struct device *dev = ar->dev; @@ -1740,10 +1809,17 @@ static int ath10k_snoc_probe(struct platform_device *pdev) goto err_fw_deinit; }
+ ret = ath10k_modem_init(ar); + if (ret) + goto err_qmi_deinit; + ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
return 0;
+err_qmi_deinit: + ath10k_qmi_deinit(ar); + err_fw_deinit: ath10k_fw_deinit(ar);
@@ -1771,6 +1847,7 @@ static int ath10k_snoc_free_resources(struct ath10k *ar) ath10k_fw_deinit(ar); ath10k_snoc_free_irq(ar); ath10k_snoc_release_resource(ar); + ath10k_modem_deinit(ar); ath10k_qmi_deinit(ar); ath10k_core_destroy(ar);
diff --git a/drivers/net/wireless/ath/ath10k/snoc.h b/drivers/net/wireless/ath/ath10k/snoc.h index 5095d1893681b..d4bce17076960 100644 --- a/drivers/net/wireless/ath/ath10k/snoc.h +++ b/drivers/net/wireless/ath/ath10k/snoc.h @@ -6,6 +6,8 @@ #ifndef _SNOC_H_ #define _SNOC_H_
+#include <linux/notifier.h> + #include "hw.h" #include "ce.h" #include "qmi.h" @@ -45,6 +47,7 @@ struct ath10k_snoc_ce_irq { enum ath10k_snoc_flags { ATH10K_SNOC_FLAG_REGISTERED, ATH10K_SNOC_FLAG_UNREGISTERING, + ATH10K_SNOC_FLAG_MODEM_STOPPED, ATH10K_SNOC_FLAG_RECOVERY, ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, }; @@ -75,6 +78,8 @@ struct ath10k_snoc { struct clk_bulk_data *clks; size_t num_clks; struct ath10k_qmi *qmi; + struct notifier_block nb; + void *notifier; unsigned long flags; bool xo_cal_supported; u32 xo_cal_data;
From: Linus Lüssing ll@simonwunderlich.de
[ Upstream commit 4925642d541278575ad1948c5924d71ffd57ef14 ]
In tests with two Lima boards from 8devices (QCA4531 based) on OpenWrt 19.07 we could force a silent restart of a device with no serial output when we were sending a high amount of UDP traffic (iperf3 at 80 MBit/s in both directions from external hosts, saturating the wifi and causing a load of about 4.5 to 6) and were then triggering an ath9k_queue_reset().
Further debugging showed that the restart was caused by the ath79 watchdog. With disabled watchdog we could observe that the device was constantly going into ath_isr() interrupt handler and was returning early after the ATH_OP_HW_RESET flag test, without clearing any interrupts. Even though ath9k_queue_reset() calls ath9k_hw_kill_interrupts().
With JTAG we could observe the following race condition:
1) ath9k_queue_reset() ... -> ath9k_hw_kill_interrupts() -> set_bit(ATH_OP_HW_RESET, &common->op_flags); ... <- returns
2) ath9k_tasklet() ... -> ath9k_hw_resume_interrupts() ... <- returns
3) loops around: ... handle_int() -> ath_isr() ... -> if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) return IRQ_HANDLED;
x) ath_reset_internal(): => never reached <=
And in ath_isr() we would typically see the following interrupts / interrupt causes:
* status: 0x00111030 or 0x00110030 * async_cause: 2 (AR_INTR_MAC_IPQ) * sync_cause: 0
So the ath9k_tasklet() reenables the ath9k interrupts through ath9k_hw_resume_interrupts() which ath9k_queue_reset() had just disabled. And ath_isr() then keeps firing because it returns IRQ_HANDLED without actually clearing the interrupt.
To fix this IRQ storm also clear/disable the interrupts again when we are in reset state.
Cc: Sven Eckelmann sven@narfation.org Cc: Simon Wunderlich sw@simonwunderlich.de Cc: Linus Lüssing linus.luessing@c0d3.blue Fixes: 872b5d814f99 ("ath9k: do not access hardware on IRQs during reset") Signed-off-by: Linus Lüssing ll@simonwunderlich.de Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210914192515.9273-3-linus.luessing@c0d3.blue Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath9k/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 139831539da37..98090e40e1cf4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -533,8 +533,10 @@ irqreturn_t ath_isr(int irq, void *dev) ath9k_debug_sync_cause(sc, sync_cause); status &= ah->imask; /* discard unasked-for bits */
- if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) + if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) { + ath9k_hw_kill_interrupts(sc->sc_ah); return IRQ_HANDLED; + }
/* * If there are no status bits set, then this interrupt was not
From: Vincent Donnefort vincent.donnefort@arm.com
[ Upstream commit aa1a43262ad5df010768f69530fa179ff81651d3 ]
Currently, a debug message is printed if an inefficient state is detected in the Energy Model. Unfortunately, it won't detect if the first state is inefficient or if two successive states are. Fix this behavior.
Fixes: 27871f7a8a34 (PM: Introduce an Energy Model management framework) Signed-off-by: Vincent Donnefort vincent.donnefort@arm.com Reviewed-by: Quentin Perret qperret@google.com Reviewed-by: Lukasz Luba lukasz.luba@arm.com Reviewed-by: Matthias Kaehlcke mka@chromium.org Acked-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/power/energy_model.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index a332ccd829e24..97e62469a6b32 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -107,8 +107,7 @@ static void em_debug_remove_pd(struct device *dev) {} static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd, int nr_states, struct em_data_callback *cb) { - unsigned long opp_eff, prev_opp_eff = ULONG_MAX; - unsigned long power, freq, prev_freq = 0; + unsigned long power, freq, prev_freq = 0, prev_cost = ULONG_MAX; struct em_perf_state *table; int i, ret; u64 fmax; @@ -153,27 +152,21 @@ static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
table[i].power = power; table[i].frequency = prev_freq = freq; - - /* - * The hertz/watts efficiency ratio should decrease as the - * frequency grows on sane platforms. But this isn't always - * true in practice so warn the user if a higher OPP is more - * power efficient than a lower one. - */ - opp_eff = freq / power; - if (opp_eff >= prev_opp_eff) - dev_dbg(dev, "EM: hertz/watts ratio non-monotonically decreasing: em_perf_state %d >= em_perf_state%d\n", - i, i - 1); - prev_opp_eff = opp_eff; }
/* Compute the cost of each performance state. */ fmax = (u64) table[nr_states - 1].frequency; - for (i = 0; i < nr_states; i++) { + for (i = nr_states - 1; i >= 0; i--) { unsigned long power_res = em_scale_power(table[i].power);
table[i].cost = div64_u64(fmax * power_res, table[i].frequency); + if (table[i].cost >= prev_cost) { + dev_dbg(dev, "EM: OPP:%lu is inefficient\n", + table[i].frequency); + } else { + prev_cost = table[i].cost; + } }
pd->table = table;
From: Borislav Petkov bp@suse.de
[ Upstream commit f96b4675839b66168f5a07bf964dde6c2f1c4885 ]
Use get_unaligned() instead of memcpy() to access potentially unaligned memory, which, when accessed through a pointer, leads to undefined behavior. get_unaligned() describes much better what is happening there anyway even if memcpy() does the job.
In addition, since perf tool builds with -Werror, it would fire with:
util/intel-pt-decoder/../../../arch/x86/lib/insn.c: In function '__insn_get_emulate_prefix': tools/include/../include/asm-generic/unaligned.h:10:15: error: packed attribute is unnecessary [-Werror=packed] 10 | const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \
because -Werror=packed would complain if the packed attribute would have no effect on the layout of the structure.
In this case, that is intentional so disable the warning only for that compilation unit.
That part is Reported-by: Stephen Rothwell sfr@canb.auug.org.au
No functional changes.
Fixes: 5ba1071f7554 ("x86/insn, tools/x86: Fix undefined behavior due to potential unaligned accesses") Suggested-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Borislav Petkov bp@suse.de Acked-by: Masami Hiramatsu mhiramat@kernel.org Tested-by: Stephen Rothwell sfr@canb.auug.org.au Link: https://lkml.kernel.org/r/YVSsIkj9Z29TyUjE@zn.tnic Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/lib/insn.c | 5 +++-- tools/arch/x86/lib/insn.c | 5 +++-- tools/include/asm-generic/unaligned.h | 23 +++++++++++++++++++++++ tools/perf/util/intel-pt-decoder/Build | 2 ++ 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 tools/include/asm-generic/unaligned.h
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c index c565def611e24..55e371cc69fd5 100644 --- a/arch/x86/lib/insn.c +++ b/arch/x86/lib/insn.c @@ -13,6 +13,7 @@ #endif #include <asm/inat.h> /*__ignore_sync_check__ */ #include <asm/insn.h> /* __ignore_sync_check__ */ +#include <asm/unaligned.h> /* __ignore_sync_check__ */
#include <linux/errno.h> #include <linux/kconfig.h> @@ -37,10 +38,10 @@ ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
#define __get_next(t, insn) \ - ({ t r; memcpy(&r, insn->next_byte, sizeof(t)); insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) + ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); })
#define __peek_nbyte_next(t, insn, n) \ - ({ t r; memcpy(&r, (insn)->next_byte + n, sizeof(t)); leXX_to_cpu(t, r); }) + ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); })
#define get_next(t, insn) \ ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) diff --git a/tools/arch/x86/lib/insn.c b/tools/arch/x86/lib/insn.c index 797699462cd8e..8fd63a067308a 100644 --- a/tools/arch/x86/lib/insn.c +++ b/tools/arch/x86/lib/insn.c @@ -13,6 +13,7 @@ #endif #include "../include/asm/inat.h" /* __ignore_sync_check__ */ #include "../include/asm/insn.h" /* __ignore_sync_check__ */ +#include "../include/asm-generic/unaligned.h" /* __ignore_sync_check__ */
#include <linux/errno.h> #include <linux/kconfig.h> @@ -37,10 +38,10 @@ ((insn)->next_byte + sizeof(t) + n <= (insn)->end_kaddr)
#define __get_next(t, insn) \ - ({ t r; memcpy(&r, insn->next_byte, sizeof(t)); insn->next_byte += sizeof(t); leXX_to_cpu(t, r); }) + ({ t r = get_unaligned((t *)(insn)->next_byte); (insn)->next_byte += sizeof(t); leXX_to_cpu(t, r); })
#define __peek_nbyte_next(t, insn, n) \ - ({ t r; memcpy(&r, (insn)->next_byte + n, sizeof(t)); leXX_to_cpu(t, r); }) + ({ t r = get_unaligned((t *)(insn)->next_byte + n); leXX_to_cpu(t, r); })
#define get_next(t, insn) \ ({ if (unlikely(!validate_next(t, insn, 0))) goto err_out; __get_next(t, insn); }) diff --git a/tools/include/asm-generic/unaligned.h b/tools/include/asm-generic/unaligned.h new file mode 100644 index 0000000000000..47387c607035e --- /dev/null +++ b/tools/include/asm-generic/unaligned.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copied from the kernel sources to tools/perf/: + */ + +#ifndef __TOOLS_LINUX_ASM_GENERIC_UNALIGNED_H +#define __TOOLS_LINUX_ASM_GENERIC_UNALIGNED_H + +#define __get_unaligned_t(type, ptr) ({ \ + const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ + __pptr->x; \ +}) + +#define __put_unaligned_t(type, val, ptr) do { \ + struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \ + __pptr->x = (val); \ +} while (0) + +#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr)) +#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr)) + +#endif /* __TOOLS_LINUX_ASM_GENERIC_UNALIGNED_H */ + diff --git a/tools/perf/util/intel-pt-decoder/Build b/tools/perf/util/intel-pt-decoder/Build index bc629359826fb..b41c2e9c6f887 100644 --- a/tools/perf/util/intel-pt-decoder/Build +++ b/tools/perf/util/intel-pt-decoder/Build @@ -18,3 +18,5 @@ CFLAGS_intel-pt-insn-decoder.o += -I$(OUTPUT)util/intel-pt-decoder ifeq ($(CC_NO_CLANG), 1) CFLAGS_intel-pt-insn-decoder.o += -Wno-override-init endif + +CFLAGS_intel-pt-insn-decoder.o += -Wno-packed
From: Yazen Ghannam yazen.ghannam@amd.com
[ Upstream commit 9f4873fb6af7966de8fcbd95c36b61351c1c4b1f ]
AMD Rome systems and later support interleaving between three identical ranks within a channel.
Check for this mode by counting the number of enabled chip selects and comparing their masks. If there are exactly three enabled chip selects and their masks are identical, then three rank interleaving is enabled.
The size of a rank is determined from its mask value. However, three rank interleaving doesn't follow the method of swapping an interleave bit with the most significant bit. Rather, the interleave bit is flipped and the most significant bit remains the same. There is only a single interleave bit in this case.
Account for this when determining the chip select size by keeping the most significant bit at its original value and ignoring any zero bits. This will return a full bitmask in [MSB:1].
Fixes: e53a3b267fb0 ("EDAC/amd64: Find Chip Select memory size using Address Mask") Signed-off-by: Yazen Ghannam yazen.ghannam@amd.com Signed-off-by: Borislav Petkov bp@suse.de Link: https://lkml.kernel.org/r/20211005154419.2060504-1-yazen.ghannam@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/edac/amd64_edac.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 99b06a3e8fb12..4fce75013674f 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1065,12 +1065,14 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) #define CS_ODD_PRIMARY BIT(1) #define CS_EVEN_SECONDARY BIT(2) #define CS_ODD_SECONDARY BIT(3) +#define CS_3R_INTERLEAVE BIT(4)
#define CS_EVEN (CS_EVEN_PRIMARY | CS_EVEN_SECONDARY) #define CS_ODD (CS_ODD_PRIMARY | CS_ODD_SECONDARY)
static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) { + u8 base, count = 0; int cs_mode = 0;
if (csrow_enabled(2 * dimm, ctrl, pvt)) @@ -1083,6 +1085,20 @@ static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt)) cs_mode |= CS_ODD_SECONDARY;
+ /* + * 3 Rank inteleaving support. + * There should be only three bases enabled and their two masks should + * be equal. + */ + for_each_chip_select(base, ctrl, pvt) + count += csrow_enabled(base, ctrl, pvt); + + if (count == 3 && + pvt->csels[ctrl].csmasks[0] == pvt->csels[ctrl].csmasks[1]) { + edac_dbg(1, "3R interleaving in use.\n"); + cs_mode |= CS_3R_INTERLEAVE; + } + return cs_mode; }
@@ -1891,10 +1907,14 @@ static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, * * The MSB is the number of bits in the full mask because BIT[0] is * always 0. + * + * In the special 3 Rank interleaving case, a single bit is flipped + * without swapping with the most significant bit. This can be handled + * by keeping the MSB where it is and ignoring the single zero bit. */ msb = fls(addr_mask_orig) - 1; weight = hweight_long(addr_mask_orig); - num_zero_bits = msb - weight; + num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE);
/* Take the number of zero bits off from the top of the mask. */ addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1);
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 7663ad9a5dbcc27f3090e6bfd192c7e59222709f ]
RCU managed to grow a few noinstr violations:
vmlinux.o: warning: objtool: rcu_dynticks_eqs_enter()+0x0: call to rcu_dynticks_task_trace_enter() leaves .noinstr.text section vmlinux.o: warning: objtool: rcu_dynticks_eqs_exit()+0xe: call to rcu_dynticks_task_trace_exit() leaves .noinstr.text section
Fix them by adding __always_inline to the relevant trivial functions.
Also replace the noinstr with __always_inline for the existing rcu_dynticks_task_*() functions since noinstr would force noinline them, even when empty, which seems silly.
Fixes: 7d0c9c50c5a1 ("rcu-tasks: Avoid IPIing userspace/idle tasks if kernel is so built") Reported-by: Stephen Rothwell sfr@canb.auug.org.au Reviewed-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tree_plugin.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index d070059163d70..0d21a5cdc7247 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -1480,7 +1480,7 @@ static void rcu_bind_gp_kthread(void) }
/* Record the current task on dyntick-idle entry. */ -static void noinstr rcu_dynticks_task_enter(void) +static __always_inline void rcu_dynticks_task_enter(void) { #if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL) WRITE_ONCE(current->rcu_tasks_idle_cpu, smp_processor_id()); @@ -1488,7 +1488,7 @@ static void noinstr rcu_dynticks_task_enter(void) }
/* Record no current task on dyntick-idle exit. */ -static void noinstr rcu_dynticks_task_exit(void) +static __always_inline void rcu_dynticks_task_exit(void) { #if defined(CONFIG_TASKS_RCU) && defined(CONFIG_NO_HZ_FULL) WRITE_ONCE(current->rcu_tasks_idle_cpu, -1); @@ -1496,7 +1496,7 @@ static void noinstr rcu_dynticks_task_exit(void) }
/* Turn on heavyweight RCU tasks trace readers on idle/user entry. */ -static void rcu_dynticks_task_trace_enter(void) +static __always_inline void rcu_dynticks_task_trace_enter(void) { #ifdef CONFIG_TASKS_TRACE_RCU if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB)) @@ -1505,7 +1505,7 @@ static void rcu_dynticks_task_trace_enter(void) }
/* Turn off heavyweight RCU tasks trace readers on idle/user exit. */ -static void rcu_dynticks_task_trace_exit(void) +static __always_inline void rcu_dynticks_task_trace_exit(void) { #ifdef CONFIG_TASKS_TRACE_RCU if (IS_ENABLED(CONFIG_TASKS_TRACE_RCU_READ_MB))
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 74aece72f95f399dd29363669dc32a1344c8fab4 ]
vmlinux.o: warning: objtool: rcu_nmi_enter()+0x36: call to __kasan_check_read() leaves .noinstr.text section
noinstr cannot have atomic_*() functions in because they're explicitly annotated, use arch_atomic_*().
Fixes: 2be57f732889 ("rcu: Weaken ->dynticks accesses and updates") Reported-by: Stephen Rothwell sfr@canb.auug.org.au Reviewed-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Paul E. McKenney paulmck@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/rcu/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index bce848e50512e..bdd1dc6de71ab 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -327,7 +327,7 @@ static void rcu_dynticks_eqs_online(void) */ static __always_inline bool rcu_dynticks_curr_cpu_in_eqs(void) { - return !(atomic_read(this_cpu_ptr(&rcu_data.dynticks)) & 0x1); + return !(arch_atomic_read(this_cpu_ptr(&rcu_data.dynticks)) & 0x1); }
/*
From: Pablo Neira Ayuso pablo@netfilter.org
[ Upstream commit 7b1394892de8d95748d05e3ee41e85edb4abbfa1 ]
Relax this condition to make add and update commands idempotent for sets with no timeout. The eval function already checks if the set element timeout is available and updates it if the update command is used.
Fixes: 22fe54d5fefc ("netfilter: nf_tables: add support for dynamic set updates") Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nft_dynset.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c index 6ba3256fa8449..87f3af4645d9c 100644 --- a/net/netfilter/nft_dynset.c +++ b/net/netfilter/nft_dynset.c @@ -198,17 +198,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, return -EBUSY;
priv->op = ntohl(nla_get_be32(tb[NFTA_DYNSET_OP])); - switch (priv->op) { - case NFT_DYNSET_OP_ADD: - case NFT_DYNSET_OP_DELETE: - break; - case NFT_DYNSET_OP_UPDATE: - if (!(set->flags & NFT_SET_TIMEOUT)) - return -EOPNOTSUPP; - break; - default: + if (priv->op > NFT_DYNSET_OP_DELETE) return -EOPNOTSUPP; - }
timeout = 0; if (tb[NFTA_DYNSET_TIMEOUT] != NULL) {
From: Mansur Alisha Shaik mansur@codeaurora.org
[ Upstream commit 1444232152ea33f5ae41fc14bade3e74d642b634 ]
In existing video driver implementation vpp frequency calculation in calculate_inst_freq() is always zero because the value of vpp_freq_per_mb is always zero for decoder.
Fixed this by correcting the calculating the vpp frequency calculation for decoder.
Fixes: 3cfe5815ce0e ("media: venus: Enable low power setting for encoder") Signed-off-by: Mansur Alisha Shaik mansur@codeaurora.org Signed-off-by: Stanimir Varbanov stanimir.varbanov@linaro.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/platform/qcom/venus/pm_helpers.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c index 3e2345eb47f7c..e031fd17f4e75 100644 --- a/drivers/media/platform/qcom/venus/pm_helpers.c +++ b/drivers/media/platform/qcom/venus/pm_helpers.c @@ -1085,12 +1085,16 @@ static unsigned long calculate_inst_freq(struct venus_inst *inst, if (inst->state != INST_START) return 0;
- if (inst->session_type == VIDC_SESSION_TYPE_ENC) + if (inst->session_type == VIDC_SESSION_TYPE_ENC) { vpp_freq_per_mb = inst->flags & VENUS_LOW_POWER ? inst->clk_data.low_power_freq : inst->clk_data.vpp_freq;
- vpp_freq = mbs_per_sec * vpp_freq_per_mb; + vpp_freq = mbs_per_sec * vpp_freq_per_mb; + } else { + vpp_freq = mbs_per_sec * inst->clk_data.vpp_freq; + } + /* 21 / 20 is overhead factor */ vpp_freq += vpp_freq / 20; vsp_freq = mbs_per_sec * inst->clk_data.vsp_freq;
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 69a10678e2fba3d182e78ea041f2d1b1a6058764 ]
mn88443x_cmn_power_on() did not handle possible errors of clk_prepare_enable() and always finished successfully so that its caller mn88443x_probe() did not care about failed preparing/enabling of clocks as well.
Add missed error handling in both mn88443x_cmn_power_on() and mn88443x_probe(). This required to change the return value of the former from "void" to "int".
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: 0f408ce8941f ("media: dvb-frontends: add Socionext MN88443x ISDB-S/T demodulator driver") Signed-off-by: Evgeny Novikov novikov@ispras.ru Co-developed-by: Kirill Shilimanov kirill.shilimanov@huawei.com Signed-off-by: Kirill Shilimanov kirill.shilimanov@huawei.com Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/dvb-frontends/mn88443x.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/media/dvb-frontends/mn88443x.c b/drivers/media/dvb-frontends/mn88443x.c index e4528784f8477..fff212c0bf3b5 100644 --- a/drivers/media/dvb-frontends/mn88443x.c +++ b/drivers/media/dvb-frontends/mn88443x.c @@ -204,11 +204,18 @@ struct mn88443x_priv { struct regmap *regmap_t; };
-static void mn88443x_cmn_power_on(struct mn88443x_priv *chip) +static int mn88443x_cmn_power_on(struct mn88443x_priv *chip) { + struct device *dev = &chip->client_s->dev; struct regmap *r_t = chip->regmap_t; + int ret;
- clk_prepare_enable(chip->mclk); + ret = clk_prepare_enable(chip->mclk); + if (ret) { + dev_err(dev, "Failed to prepare and enable mclk: %d\n", + ret); + return ret; + }
gpiod_set_value_cansleep(chip->reset_gpio, 1); usleep_range(100, 1000); @@ -222,6 +229,8 @@ static void mn88443x_cmn_power_on(struct mn88443x_priv *chip) } else { regmap_write(r_t, HIZSET3, 0x8f); } + + return 0; }
static void mn88443x_cmn_power_off(struct mn88443x_priv *chip) @@ -738,7 +747,10 @@ static int mn88443x_probe(struct i2c_client *client, chip->fe.demodulator_priv = chip; i2c_set_clientdata(client, chip);
- mn88443x_cmn_power_on(chip); + ret = mn88443x_cmn_power_on(chip); + if (ret) + goto err_i2c_t; + mn88443x_s_sleep(chip); mn88443x_t_sleep(chip);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit cfd6fb45cfaf46fa9547421d8da387dc9c7997d4 ]
clang points out inconsistencies in the FIELD_PREP() invocation in this driver that result from the 'mask' being a 32-bit value:
drivers/crypto/ccree/cc_driver.c:117:18: error: result of comparison of constant 18446744073709551615 with expression of type 'u32' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare] cache_params |= FIELD_PREP(mask, val); ^~~~~~~~~~~~~~~~~~~~~ include/linux/bitfield.h:94:3: note: expanded from macro 'FIELD_PREP' __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/bitfield.h:52:28: note: expanded from macro '__BF_FIELD_CHECK' BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This does not happen in other places that just pass a constant here.
Work around the warnings by widening the type of the temporary variable.
Fixes: 05c2a705917b ("crypto: ccree - rework cache parameters handling") Signed-off-by: Arnd Bergmann arnd@arndb.de Acked-by: Gilad ben-Yossef gilad@benyossef.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/ccree/cc_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/ccree/cc_driver.c b/drivers/crypto/ccree/cc_driver.c index e599ac6dc162a..790fa9058a36d 100644 --- a/drivers/crypto/ccree/cc_driver.c +++ b/drivers/crypto/ccree/cc_driver.c @@ -103,7 +103,8 @@ MODULE_DEVICE_TABLE(of, arm_ccree_dev_of_match); static void init_cc_cache_params(struct cc_drvdata *drvdata) { struct device *dev = drvdata_to_dev(drvdata); - u32 cache_params, ace_const, val, mask; + u32 cache_params, ace_const, val; + u64 mask;
/* compute CC_AXIM_CACHE_PARAMS */ cache_params = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS));
From: Giovanni Cabiddu giovanni.cabiddu@intel.com
[ Upstream commit 9b768e8a3909ac1ab39ed44a3933716da7761a6f ]
Detect a PFVF collision between the local and the remote function by checking if the message on the PFVF CSR has been overwritten. This is done after the remote function confirms that the message has been received, by clearing the interrupt bit, or the maximum number of attempts (ADF_IOV_MSG_ACK_MAX_RETRY) to check the CSR has been exceeded.
Fixes: ed8ccaef52fa ("crypto: qat - Add support for SRIOV") Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Co-developed-by: Marco Chiappero marco.chiappero@intel.com Signed-off-by: Marco Chiappero marco.chiappero@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c index 976b9ab7617cd..789a4135e28c0 100644 --- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c +++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c @@ -156,6 +156,13 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); } while ((val & int_bit) && (count++ < ADF_IOV_MSG_ACK_MAX_RETRY));
+ if (val != msg) { + dev_dbg(&GET_DEV(accel_dev), + "Collision - PFVF CSR overwritten by remote function\n"); + ret = -EIO; + goto out; + } + if (val & int_bit) { dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n"); val &= ~int_bit;
From: Giovanni Cabiddu giovanni.cabiddu@intel.com
[ Upstream commit 18fcba469ba5359c1de7e3fb16f7b9e8cd1b8e02 ]
Upon receiving a PFVF message, check if the interrupt bit is set in the message. If it is not, that means that the interrupt was probably triggered by a collision. In this case, disregard the message and re-enable the interrupts.
Fixes: ed8ccaef52fa ("crypto: qat - Add support for SRIOV") Signed-off-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Reviewed-by: Marco Chiappero marco.chiappero@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/qat/qat_common/adf_pf2vf_msg.c | 6 ++++++ drivers/crypto/qat/qat_common/adf_vf_isr.c | 6 ++++++ 2 files changed, 12 insertions(+)
diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c index 789a4135e28c0..5a41beb8f20f6 100644 --- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c +++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c @@ -211,6 +211,11 @@ void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info)
/* Read message from the VF */ msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); + if (!(msg & ADF_VF2PF_INT)) { + dev_info(&GET_DEV(accel_dev), + "Spurious VF2PF interrupt, msg %X. Ignored\n", msg); + goto out; + }
/* To ACK, clear the VF2PFINT bit */ msg &= ~ADF_VF2PF_INT; @@ -294,6 +299,7 @@ void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) dev_err(&GET_DEV(accel_dev), "Failed to send response to VF\n");
+out: /* re-enable interrupt on PF from this VF */ adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_nr));
diff --git a/drivers/crypto/qat/qat_common/adf_vf_isr.c b/drivers/crypto/qat/qat_common/adf_vf_isr.c index 7828a6573f3e2..2e300c255ab94 100644 --- a/drivers/crypto/qat/qat_common/adf_vf_isr.c +++ b/drivers/crypto/qat/qat_common/adf_vf_isr.c @@ -101,6 +101,11 @@ static void adf_pf2vf_bh_handler(void *data)
/* Read the message from PF */ msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0)); + if (!(msg & ADF_PF2VF_INT)) { + dev_info(&GET_DEV(accel_dev), + "Spurious PF2VF interrupt, msg %X. Ignored\n", msg); + goto out; + }
if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) /* Ignore legacy non-system (non-kernel) PF2VF messages */ @@ -149,6 +154,7 @@ static void adf_pf2vf_bh_handler(void *data) msg &= ~ADF_PF2VF_INT; ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg);
+out: /* Re-enable PF2VF interrupts */ adf_enable_pf2vf_interrupts(accel_dev); return;
From: Markus Schneider-Pargmann msp@baylibre.com
[ Upstream commit b6f5f0c8f72d348b2d07b20d7b680ef13a7ffe98 ]
Currently mtk_rng_runtime_suspend/resume is called for both runtime pm and system sleep operations.
This is wrong as these should only be runtime ops as the name already suggests. Currently freezing the system will lead to a call to mtk_rng_runtime_suspend even if the device currently isn't active. This leads to a clock warning because it is disabled/unprepared although it isn't enabled/prepared currently.
This patch fixes this by only setting the runtime pm ops and forces to call the runtime pm ops from the system sleep ops as well if active but not otherwise.
Fixes: 81d2b34508c6 ("hwrng: mtk - add runtime PM support") Signed-off-by: Markus Schneider-Pargmann msp@baylibre.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/hw_random/mtk-rng.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c index 8ad7b515a51b8..6c00ea0085553 100644 --- a/drivers/char/hw_random/mtk-rng.c +++ b/drivers/char/hw_random/mtk-rng.c @@ -166,8 +166,13 @@ static int mtk_rng_runtime_resume(struct device *dev) return mtk_rng_init(&priv->rng); }
-static UNIVERSAL_DEV_PM_OPS(mtk_rng_pm_ops, mtk_rng_runtime_suspend, - mtk_rng_runtime_resume, NULL); +static const struct dev_pm_ops mtk_rng_pm_ops = { + SET_RUNTIME_PM_OPS(mtk_rng_runtime_suspend, + mtk_rng_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + #define MTK_RNG_PM_OPS (&mtk_rng_pm_ops) #else /* CONFIG_PM */ #define MTK_RNG_PM_OPS NULL
From: liqiong liqiong@nfschina.com
[ Upstream commit eb0782bbdfd0d7c4786216659277c3fd585afc0e ]
The current IMA ruleset is identified by the variable "ima_rules" that default to "&ima_default_rules". When loading a custom policy for the first time, the variable is updated to "&ima_policy_rules" instead. That update isn't RCU-safe, and deadlocks are possible. Indeed, some functions like ima_match_policy() may loop indefinitely when traversing "ima_default_rules" with list_for_each_entry_rcu().
When iterating over the default ruleset back to head, if the list head is "ima_default_rules", and "ima_rules" have been updated to "&ima_policy_rules", the loop condition (&entry->list != ima_rules) stays always true, traversing won't terminate, causing a soft lockup and RCU stalls.
Introduce a temporary value for "ima_rules" when iterating over the ruleset to avoid the deadlocks.
Signed-off-by: liqiong liqiong@nfschina.com Reviewed-by: THOBY Simon Simon.THOBY@viveris.fr Fixes: 38d859f991f3 ("IMA: policy can now be updated multiple times") Reported-by: kernel test robot lkp@intel.com (Fix sparse: incompatible types in comparison expression.) Signed-off-by: Mimi Zohar zohar@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/integrity/ima/ima_policy.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 87b9b71cb8201..12e8adcd80a2a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -228,7 +228,7 @@ static struct ima_rule_entry *arch_policy_entry __ro_after_init; static LIST_HEAD(ima_default_rules); static LIST_HEAD(ima_policy_rules); static LIST_HEAD(ima_temp_rules); -static struct list_head *ima_rules = &ima_default_rules; +static struct list_head __rcu *ima_rules = (struct list_head __rcu *)(&ima_default_rules);
static int ima_policy __initdata;
@@ -675,12 +675,14 @@ int ima_match_policy(struct user_namespace *mnt_userns, struct inode *inode, { struct ima_rule_entry *entry; int action = 0, actmask = flags | (flags << 1); + struct list_head *ima_rules_tmp;
if (template_desc && !*template_desc) *template_desc = ima_template_desc_current();
rcu_read_lock(); - list_for_each_entry_rcu(entry, ima_rules, list) { + ima_rules_tmp = rcu_dereference(ima_rules); + list_for_each_entry_rcu(entry, ima_rules_tmp, list) {
if (!(entry->action & actmask)) continue; @@ -741,9 +743,11 @@ void ima_update_policy_flags(void) { struct ima_rule_entry *entry; int new_policy_flag = 0; + struct list_head *ima_rules_tmp;
rcu_read_lock(); - list_for_each_entry(entry, ima_rules, list) { + ima_rules_tmp = rcu_dereference(ima_rules); + list_for_each_entry_rcu(entry, ima_rules_tmp, list) { /* * SETXATTR_CHECK rules do not implement a full policy check * because rule checking would probably have an important @@ -968,10 +972,10 @@ void ima_update_policy(void)
list_splice_tail_init_rcu(&ima_temp_rules, policy, synchronize_rcu);
- if (ima_rules != policy) { + if (ima_rules != (struct list_head __rcu *)policy) { ima_policy_flag = 0; - ima_rules = policy;
+ rcu_assign_pointer(ima_rules, policy); /* * IMA architecture specific policy rules are specified * as strings and converted to an array of ima_entry_rules @@ -1061,7 +1065,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry, pr_warn("rule for LSM '%s' is undefined\n", entry->lsm[lsm_rule].args_p);
- if (ima_rules == &ima_default_rules) { + if (ima_rules == (struct list_head __rcu *)(&ima_default_rules)) { kfree(entry->lsm[lsm_rule].args_p); entry->lsm[lsm_rule].args_p = NULL; result = -EINVAL; @@ -1768,9 +1772,11 @@ void *ima_policy_start(struct seq_file *m, loff_t *pos) { loff_t l = *pos; struct ima_rule_entry *entry; + struct list_head *ima_rules_tmp;
rcu_read_lock(); - list_for_each_entry_rcu(entry, ima_rules, list) { + ima_rules_tmp = rcu_dereference(ima_rules); + list_for_each_entry_rcu(entry, ima_rules_tmp, list) { if (!l--) { rcu_read_unlock(); return entry; @@ -1789,7 +1795,8 @@ void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos) rcu_read_unlock(); (*pos)++;
- return (&entry->list == ima_rules) ? NULL : entry; + return (&entry->list == &ima_default_rules || + &entry->list == &ima_policy_rules) ? NULL : entry; }
void ima_policy_stop(struct seq_file *m, void *v) @@ -2014,6 +2021,7 @@ bool ima_appraise_signature(enum kernel_read_file_id id) struct ima_rule_entry *entry; bool found = false; enum ima_hooks func; + struct list_head *ima_rules_tmp;
if (id >= READING_MAX_ID) return false; @@ -2021,7 +2029,8 @@ bool ima_appraise_signature(enum kernel_read_file_id id) func = read_idmap[id] ?: FILE_CHECK;
rcu_read_lock(); - list_for_each_entry_rcu(entry, ima_rules, list) { + ima_rules_tmp = rcu_dereference(ima_rules); + list_for_each_entry_rcu(entry, ima_rules_tmp, list) { if (entry->action != APPRAISE) continue;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit c1c8380b0320ab757e60ed90efc8b1992a943256 ]
The problem is that "channel" is an unsigned int, when it's less 5 the value of "channel - 5" is not a negative number as one would expect but is very high positive value instead.
This means that "start" becomes a very high positive value. The result of that is that we never enter the "for (i = start; i <= end; i++) {" loop. Instead of storing the result from b43legacy_radio_aci_detect() it just uses zero.
Fixes: 75388acd0cd8 ("[B43LEGACY]: add mac80211-based driver for legacy BCM43xx devices") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Michael Büsch m@bues.ch Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211006073542.GD8404@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/b43legacy/radio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43legacy/radio.c b/drivers/net/wireless/broadcom/b43legacy/radio.c index 06891b4f837b9..fdf78c10a05c2 100644 --- a/drivers/net/wireless/broadcom/b43legacy/radio.c +++ b/drivers/net/wireless/broadcom/b43legacy/radio.c @@ -283,7 +283,7 @@ u8 b43legacy_radio_aci_scan(struct b43legacy_wldev *dev) & 0x7FFF); b43legacy_set_all_gains(dev, 3, 8, 1);
- start = (channel - 5 > 0) ? channel - 5 : 1; + start = (channel > 5) ? channel - 5 : 1; end = (channel + 5 < 14) ? channel + 5 : 13;
for (i = start; i <= end; i++) {
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 9b793db5fca44d01f72d3564a168171acf7c4076 ]
The problem is that "channel" is an unsigned int, when it's less 5 the value of "channel - 5" is not a negative number as one would expect but is very high positive value instead.
This means that "start" becomes a very high positive value. The result of that is that we never enter the "for (i = start; i <= end; i++) {" loop. Instead of storing the result from b43legacy_radio_aci_detect() it just uses zero.
Fixes: ef1a628d83fc ("b43: Implement dynamic PHY API") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Michael Büsch m@bues.ch Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211006073621.GE8404@kili Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/broadcom/b43/phy_g.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43/phy_g.c b/drivers/net/wireless/broadcom/b43/phy_g.c index d5a1a5c582366..ac72ca39e409b 100644 --- a/drivers/net/wireless/broadcom/b43/phy_g.c +++ b/drivers/net/wireless/broadcom/b43/phy_g.c @@ -2297,7 +2297,7 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev) b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF); b43_set_all_gains(dev, 3, 8, 1);
- start = (channel - 5 > 0) ? channel - 5 : 1; + start = (channel > 5) ? channel - 5 : 1; end = (channel + 5 < 14) ? channel + 5 : 13;
for (i = start; i <= end; i++) {
From: John Fraker jfraker@google.com
[ Upstream commit 87a7f321bb6a45e54b7d6c90d032ee5636a6ad97 ]
Don't always reset the driver on a TX timeout. Attempt to recover by kicking the queue in case an IRQ was missed.
Fixes: 9e5f7d26a4c08 ("gve: Add workqueue and reset support") Signed-off-by: John Fraker jfraker@google.com Signed-off-by: David Awogbemila awogbemila@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/google/gve/gve.h | 4 +- drivers/net/ethernet/google/gve/gve_adminq.h | 1 + drivers/net/ethernet/google/gve/gve_main.c | 48 +++++++++++++++++++- 3 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h index 2f93ed4705905..c1d4042671f9f 100644 --- a/drivers/net/ethernet/google/gve/gve.h +++ b/drivers/net/ethernet/google/gve/gve.h @@ -30,7 +30,7 @@ #define GVE_MIN_MSIX 3
/* Numbers of gve tx/rx stats in stats report. */ -#define GVE_TX_STATS_REPORT_NUM 5 +#define GVE_TX_STATS_REPORT_NUM 6 #define GVE_RX_STATS_REPORT_NUM 2
/* Interval to schedule a stats report update, 20000ms. */ @@ -413,7 +413,9 @@ struct gve_tx_ring { u32 q_num ____cacheline_aligned; /* queue idx */ u32 stop_queue; /* count of queue stops */ u32 wake_queue; /* count of queue wakes */ + u32 queue_timeout; /* count of queue timeouts */ u32 ntfy_id; /* notification block index */ + u32 last_kick_msec; /* Last time the queue was kicked */ dma_addr_t bus; /* dma address of the descr ring */ dma_addr_t q_resources_bus; /* dma address of the queue resources */ dma_addr_t complq_bus_dqo; /* dma address of the dqo.compl_ring */ diff --git a/drivers/net/ethernet/google/gve/gve_adminq.h b/drivers/net/ethernet/google/gve/gve_adminq.h index 47c3d8f313fcf..3953f6f7a4273 100644 --- a/drivers/net/ethernet/google/gve/gve_adminq.h +++ b/drivers/net/ethernet/google/gve/gve_adminq.h @@ -270,6 +270,7 @@ enum gve_stat_names { TX_LAST_COMPLETION_PROCESSED = 5, RX_NEXT_EXPECTED_SEQUENCE = 6, RX_BUFFERS_POSTED = 7, + TX_TIMEOUT_CNT = 8, // stats from NIC RX_QUEUE_DROP_CNT = 65, RX_NO_BUFFERS_POSTED = 66, diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index bf8a4a7c43f78..8c996e72748d2 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -24,6 +24,9 @@ #define GVE_VERSION "1.0.0" #define GVE_VERSION_PREFIX "GVE-"
+// Minimum amount of time between queue kicks in msec (10 seconds) +#define MIN_TX_TIMEOUT_GAP (1000 * 10) + const char gve_version_str[] = GVE_VERSION; static const char gve_version_prefix[] = GVE_VERSION_PREFIX;
@@ -1116,9 +1119,47 @@ static void gve_turnup(struct gve_priv *priv)
static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue) { - struct gve_priv *priv = netdev_priv(dev); + struct gve_notify_block *block; + struct gve_tx_ring *tx = NULL; + struct gve_priv *priv; + u32 last_nic_done; + u32 current_time; + u32 ntfy_idx; + + netdev_info(dev, "Timeout on tx queue, %d", txqueue); + priv = netdev_priv(dev); + if (txqueue > priv->tx_cfg.num_queues) + goto reset; + + ntfy_idx = gve_tx_idx_to_ntfy(priv, txqueue); + if (ntfy_idx > priv->num_ntfy_blks) + goto reset; + + block = &priv->ntfy_blocks[ntfy_idx]; + tx = block->tx;
+ current_time = jiffies_to_msecs(jiffies); + if (tx->last_kick_msec + MIN_TX_TIMEOUT_GAP > current_time) + goto reset; + + /* Check to see if there are missed completions, which will allow us to + * kick the queue. + */ + last_nic_done = gve_tx_load_event_counter(priv, tx); + if (last_nic_done - tx->done) { + netdev_info(dev, "Kicking queue %d", txqueue); + iowrite32be(GVE_IRQ_MASK, gve_irq_doorbell(priv, block)); + napi_schedule(&block->napi); + tx->last_kick_msec = current_time; + goto out; + } // Else reset. + +reset: gve_schedule_reset(priv); + +out: + if (tx) + tx->queue_timeout++; priv->tx_timeo_cnt++; }
@@ -1247,6 +1288,11 @@ void gve_handle_report_stats(struct gve_priv *priv) .value = cpu_to_be64(last_completion), .queue_id = cpu_to_be32(idx), }; + stats[stats_idx++] = (struct stats) { + .stat_name = cpu_to_be32(TX_TIMEOUT_CNT), + .value = cpu_to_be64(priv->tx[idx].queue_timeout), + .queue_id = cpu_to_be32(idx), + }; } } /* rx stats */
From: Catherine Sullivan csully@google.com
[ Upstream commit 1b4d1c9bab091ac6e20a3ff80c30c5cefe192bf4 ]
The rx_buf_alloc_fail counter wasn't getting updated.
Fixes: 433e274b8f7b0 ("gve: Add stats for gve.") Signed-off-by: Catherine Sullivan csully@google.com Signed-off-by: Jeroen de Borst jeroendb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/google/gve/gve_rx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c index 94941d4e47449..16169f291ad9f 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c @@ -514,8 +514,13 @@ static bool gve_rx_refill_buffers(struct gve_priv *priv, struct gve_rx_ring *rx)
gve_rx_free_buffer(dev, page_info, data_slot); page_info->page = NULL; - if (gve_rx_alloc_buffer(priv, dev, page_info, data_slot)) + if (gve_rx_alloc_buffer(priv, dev, page_info, + data_slot)) { + u64_stats_update_begin(&rx->statss); + rx->rx_buf_alloc_fail++; + u64_stats_update_end(&rx->statss); break; + } } } fill_cnt++;
From: Tony Lindgren tony@atomide.com
[ Upstream commit 8e0e7bd38b1ec7f9e5d18725ad41828be4e09859 ]
If sdhci-omap is configured for an unused device instance and the device is not set as disabled, we can get a NULL pointer dereference:
Unable to handle kernel NULL pointer dereference at virtual address 00000045 ... (regulator_set_voltage) from [<c07d7008>] (mmc_regulator_set_ocr+0x44/0xd0) (mmc_regulator_set_ocr) from [<c07e2d80>] (sdhci_set_ios+0xa4/0x490) (sdhci_set_ios) from [<c07ea690>] (sdhci_omap_set_ios+0x124/0x160) (sdhci_omap_set_ios) from [<c07c8e94>] (mmc_power_up.part.0+0x3c/0x154) (mmc_power_up.part.0) from [<c07c9d20>] (mmc_start_host+0x88/0x9c) (mmc_start_host) from [<c07cad34>] (mmc_add_host+0x58/0x7c) (mmc_add_host) from [<c07e2574>] (__sdhci_add_host+0xf0/0x22c) (__sdhci_add_host) from [<c07eaf68>] (sdhci_omap_probe+0x318/0x72c) (sdhci_omap_probe) from [<c06a39d8>] (platform_probe+0x58/0xb8)
AFAIK we are not seeing this with the devices configured in the mainline kernel but this can cause issues for folks bringing up their boards.
Fixes: 7d326930d352 ("mmc: sdhci-omap: Add OMAP SDHCI driver") Signed-off-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20210921110029.21944-2-tony@atomide.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-omap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 8f4d1f003f656..3ddced779e965 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c @@ -682,7 +682,8 @@ static void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode, { struct mmc_host *mmc = host->mmc;
- mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); + if (!IS_ERR(mmc->supply.vmmc)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); }
static int sdhci_omap_enable_dma(struct sdhci_host *host)
From: Tony Lindgren tony@atomide.com
[ Upstream commit d806e334d0390502cd2a820ad33d65d7f9bba618 ]
We need to restore context in a specified order with HCTL set in two phases. This is similar to what omap_hsmmc_context_restore() is doing. Otherwise SDIO can stop working on resume.
And for PM runtime and SDIO cards, we need to also save SYSCTL, IE and ISE.
This should not be a problem currently, and these patches can be applied whenever suitable.
Fixes: ee0f309263a6 ("mmc: sdhci-omap: Add Support for Suspend/Resume") Signed-off-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20210921110029.21944-3-tony@atomide.com Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-omap.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index 3ddced779e965..fd188b6d88f49 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c @@ -62,6 +62,8 @@ #define SDHCI_OMAP_IE 0x234 #define INT_CC_EN BIT(0)
+#define SDHCI_OMAP_ISE 0x238 + #define SDHCI_OMAP_AC12 0x23c #define AC12_V1V8_SIGEN BIT(19) #define AC12_SCLK_SEL BIT(23) @@ -113,6 +115,8 @@ struct sdhci_omap_host { u32 hctl; u32 sysctl; u32 capa; + u32 ie; + u32 ise; };
static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host); @@ -1245,14 +1249,23 @@ static void sdhci_omap_context_save(struct sdhci_omap_host *omap_host) { omap_host->con = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON); omap_host->hctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL); + omap_host->sysctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL); omap_host->capa = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA); + omap_host->ie = sdhci_omap_readl(omap_host, SDHCI_OMAP_IE); + omap_host->ise = sdhci_omap_readl(omap_host, SDHCI_OMAP_ISE); }
+/* Order matters here, HCTL must be restored in two phases */ static void sdhci_omap_context_restore(struct sdhci_omap_host *omap_host) { - sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, omap_host->con); sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl); sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, omap_host->capa); + sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl); + + sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, omap_host->sysctl); + sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, omap_host->con); + sdhci_omap_writel(omap_host, SDHCI_OMAP_IE, omap_host->ie); + sdhci_omap_writel(omap_host, SDHCI_OMAP_ISE, omap_host->ise); }
static int __maybe_unused sdhci_omap_suspend(struct device *dev)
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 4853396f03c3019eccf5cd113e464231e9ddf0b3 ]
clang-14 complains about a sanity check that always passes when the page size is 64KB or larger:
drivers/memstick/core/ms_block.c:1739:21: error: result of comparison of constant 65536 with expression of type 'unsigned short' is always false [-Werror,-Wtautological-constant-out-of-range-compare] if (msb->page_size > PAGE_SIZE) { ~~~~~~~~~~~~~~ ^ ~~~~~~~~~
This is fine, it will still work on all architectures, so just shut up that warning with a cast.
Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20210927094520.696665-1-arnd@kernel.org Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/core/ms_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index acf36676e388d..487e4cc2951e0 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -1736,7 +1736,7 @@ static int msb_init_card(struct memstick_dev *card) msb->pages_in_block = boot_block->attr.block_size * 2; msb->block_size = msb->page_size * msb->pages_in_block;
- if (msb->page_size > PAGE_SIZE) { + if ((size_t)msb->page_size > PAGE_SIZE) { /* this isn't supported by linux at all, anyway*/ dbg("device page %d size isn't supported", msb->page_size); return -EINVAL;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit beae4a6258e64af609ad5995cc6b6056eb0d898e ]
The "msh" pointer is device managed, meaning that memstick_alloc_host() calls device_initialize() on it. That means that it can't be free using kfree() but must instead be freed with memstick_free_host(). Otherwise it leads to a tiny memory leak of device resources.
Fixes: 60fdd931d577 ("memstick: add support for JMicron jmb38x MemoryStick host controller") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20211011123912.GD15188@kili Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memstick/host/jmb38x_ms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index f9a93b0565e15..435d4c058b20e 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -882,7 +882,7 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
iounmap(host->addr); err_out_free: - kfree(msh); + memstick_free_host(msh); return NULL; }
From: Daniel Borkmann daniel@iogearbox.net
[ Upstream commit e4400bbf5b15750e1b59bf4722d18d99be60c69f ]
The NTF_EXT_LEARNED neigh flag is usually propagated back to user space upon dump of the neighbor table. However, when used in combination with NTF_USE flag this is not the case despite exempting the entry from the garbage collector. This results in inconsistent state since entries are typically marked in neigh->flags with NTF_EXT_LEARNED, but here they are not. Fix it by propagating the creation flag to ___neigh_create().
Before fix:
# ./ip/ip n replace 192.168.178.30 dev enp5s0 use extern_learn # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a REACHABLE [...]
After fix:
# ./ip/ip n replace 192.168.178.30 dev enp5s0 use extern_learn # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a extern_learn REACHABLE [...]
Fixes: 9ce33e46531d ("neighbour: support for NTF_EXT_LEARNED flag") Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Roopa Prabhu roopa@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/neighbour.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2d5bc3a75faec..8457d5f97022b 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -379,7 +379,7 @@ EXPORT_SYMBOL(neigh_ifdown);
static struct neighbour *neigh_alloc(struct neigh_table *tbl, struct net_device *dev, - bool exempt_from_gc) + u8 flags, bool exempt_from_gc) { struct neighbour *n = NULL; unsigned long now = jiffies; @@ -412,6 +412,7 @@ do_alloc: n->updated = n->used = now; n->nud_state = NUD_NONE; n->output = neigh_blackhole; + n->flags = flags; seqlock_init(&n->hh.hh_lock); n->parms = neigh_parms_clone(&tbl->parms); timer_setup(&n->timer, neigh_timer_handler, 0); @@ -575,19 +576,18 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, } EXPORT_SYMBOL(neigh_lookup_nodev);
-static struct neighbour *___neigh_create(struct neigh_table *tbl, - const void *pkey, - struct net_device *dev, - bool exempt_from_gc, bool want_ref) +static struct neighbour * +___neigh_create(struct neigh_table *tbl, const void *pkey, + struct net_device *dev, u8 flags, + bool exempt_from_gc, bool want_ref) { - struct neighbour *n1, *rc, *n = neigh_alloc(tbl, dev, exempt_from_gc); - u32 hash_val; - unsigned int key_len = tbl->key_len; - int error; + u32 hash_val, key_len = tbl->key_len; + struct neighbour *n1, *rc, *n; struct neigh_hash_table *nht; + int error;
+ n = neigh_alloc(tbl, dev, flags, exempt_from_gc); trace_neigh_create(tbl, dev, pkey, n, exempt_from_gc); - if (!n) { rc = ERR_PTR(-ENOBUFS); goto out; @@ -674,7 +674,7 @@ out_neigh_release: struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey, struct net_device *dev, bool want_ref) { - return ___neigh_create(tbl, pkey, dev, false, want_ref); + return ___neigh_create(tbl, pkey, dev, 0, false, want_ref); } EXPORT_SYMBOL(__neigh_create);
@@ -1942,7 +1942,9 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
exempt_from_gc = ndm->ndm_state & NUD_PERMANENT || ndm->ndm_flags & NTF_EXT_LEARNED; - neigh = ___neigh_create(tbl, dst, dev, exempt_from_gc, true); + neigh = ___neigh_create(tbl, dst, dev, + ndm->ndm_flags & NTF_EXT_LEARNED, + exempt_from_gc, true); if (IS_ERR(neigh)) { err = PTR_ERR(neigh); goto out;
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit ada61aa0b1184a8fda1a89a340c7d6cc4e59aee5 ]
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff888102740438 (size 8): comm "27", pid 859, jiffies 4295031351 (age 143.992s) hex dump (first 8 bytes): 68 77 6d 6f 6e 30 00 00 hwmon0.. backtrace: [<00000000544b5996>] __kmalloc_track_caller+0x1a6/0x300 [<00000000df0d62b9>] kvasprintf+0xad/0x140 [<00000000d3d2a3da>] kvasprintf_const+0x62/0x190 [<000000005f8f0f29>] kobject_set_name_vargs+0x56/0x140 [<00000000b739e4b9>] dev_set_name+0xb0/0xe0 [<0000000095b69c25>] __hwmon_device_register+0xf19/0x1e50 [hwmon] [<00000000a7e65b52>] hwmon_device_register_with_info+0xcb/0x110 [hwmon] [<000000006f181e86>] devm_hwmon_device_register_with_info+0x85/0x100 [hwmon] [<0000000081bdc567>] tmp421_probe+0x2d2/0x465 [tmp421] [<00000000502cc3f8>] i2c_device_probe+0x4e1/0xbb0 [<00000000f90bda3b>] really_probe+0x285/0xc30 [<000000007eac7b77>] __driver_probe_device+0x35f/0x4f0 [<000000004953d43d>] driver_probe_device+0x4f/0x140 [<000000002ada2d41>] __device_attach_driver+0x24c/0x330 [<00000000b3977977>] bus_for_each_drv+0x15d/0x1e0 [<000000005bf2a8e3>] __device_attach+0x267/0x410
When device_register() returns an error, the name allocated in dev_set_name() will be leaked, the put_device() should be used instead of calling hwmon_dev_release() to give up the device reference, then the name will be freed in kobject_cleanup().
Reported-by: Hulk Robot hulkci@huawei.com Fixes: bab2243ce189 ("hwmon: Introduce hwmon_device_register_with_groups") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20211012112758.2681084-1-yangyingliang@huawei.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/hwmon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 8d3b1dae31df1..3501a3ead4ba6 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -796,8 +796,10 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, dev_set_drvdata(hdev, drvdata); dev_set_name(hdev, HWMON_ID_FORMAT, id); err = device_register(hdev); - if (err) - goto free_hwmon; + if (err) { + put_device(hdev); + goto ida_remove; + }
INIT_LIST_HEAD(&hwdev->tzdata);
From: Zev Weiss zev@bewilderbeest.net
[ Upstream commit b7931a7b0e0df4d2a25fedd895ad32c746b77bc1 ]
Maintaining this manually is error prone (there are currently only five chips supported, not six); gcc can do it for us automatically.
Signed-off-by: Zev Weiss zev@bewilderbeest.net Fixes: 666c14906b49 ("hwmon: (pmbus/lm25066) Drop support for LM25063") Link: https://lore.kernel.org/r/20210928092242.30036-5-zev@bewilderbeest.net Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/lm25066.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/pmbus/lm25066.c b/drivers/hwmon/pmbus/lm25066.c index 1a660c4cd19f4..66d3e88b54172 100644 --- a/drivers/hwmon/pmbus/lm25066.c +++ b/drivers/hwmon/pmbus/lm25066.c @@ -51,7 +51,7 @@ struct __coeff { #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) #define PSC_POWER_L (PSC_NUM_CLASSES + 1)
-static struct __coeff lm25066_coeff[6][PSC_NUM_CLASSES + 2] = { +static struct __coeff lm25066_coeff[][PSC_NUM_CLASSES + 2] = { [lm25056] = { [PSC_VOLTAGE_IN] = { .m = 16296,
From: Sven Eckelmann seckelmann@datto.com
[ Upstream commit 0a491167fe0cf9f26062462de2a8688b96125d48 ]
Most of the txpower for the ath10k firmware is stored as twicepower (0.5 dB steps). This isn't the case for max_antenna_gain - which is still expected by the firmware as dB.
The firmware is converting it from dB to the internal (twicepower) representation when it calculates the limits of a channel. This can be seen in tpc_stats when configuring "12" as max_antenna_gain. Instead of the expected 12 (6 dB), the tpc_stats shows 24 (12 dB).
Tested on QCA9888 and IPQ4019 with firmware 10.4-3.5.3-00057.
Fixes: 02256930d9b8 ("ath10k: use proper tx power unit") Signed-off-by: Sven Eckelmann seckelmann@datto.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20190611172131.6064-1-sven@narfation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/mac.c | 6 +++--- drivers/net/wireless/ath/ath10k/wmi.h | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 7ca68c81d9b61..5ec19d91cf372 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -1052,7 +1052,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) arg.channel.min_power = 0; arg.channel.max_power = channel->max_power * 2; arg.channel.max_reg_power = channel->max_reg_power * 2; - arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; + arg.channel.max_antenna_gain = channel->max_antenna_gain;
reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); @@ -1498,7 +1498,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, arg.channel.min_power = 0; arg.channel.max_power = chandef->chan->max_power * 2; arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; - arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2; + arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; @@ -3426,7 +3426,7 @@ static int ath10k_update_channel_list(struct ath10k *ar) ch->min_power = 0; ch->max_power = channel->max_power * 2; ch->max_reg_power = channel->max_reg_power * 2; - ch->max_antenna_gain = channel->max_antenna_gain * 2; + ch->max_antenna_gain = channel->max_antenna_gain; ch->reg_class_id = 0; /* FIXME */
/* FIXME: why use only legacy modes, why not any diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 41c1a3d339c25..01bfd09a9d88c 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2066,7 +2066,9 @@ struct wmi_channel { union { __le32 reginfo1; struct { + /* note: power unit is 1 dBm */ u8 antenna_max; + /* note: power unit is 0.5 dBm */ u8 max_tx_power; } __packed; } __packed; @@ -2086,6 +2088,7 @@ struct wmi_channel_arg { u32 min_power; u32 max_power; u32 max_reg_power; + /* note: power unit is 1 dBm */ u32 max_antenna_gain; u32 reg_class_id; enum wmi_phy_mode mode;
From: Zhang Qiao zhangqiao22@huawei.com
[ Upstream commit 4ef0c5c6b5ba1f38f0ea1cedad0cad722f00c14a ]
There is a small race between copy_process() and sched_fork() where child->sched_task_group point to an already freed pointer.
parent doing fork() | someone moving the parent | to another cgroup -------------------------------+------------------------------- copy_process() + dup_task_struct()<1> parent move to another cgroup, and free the old cgroup. <2> + sched_fork() + __set_task_cpu()<3> + task_fork_fair() + sched_slice()<4>
In the worst case, this bug can lead to "use-after-free" and cause panic as shown above:
(1) parent copy its sched_task_group to child at <1>;
(2) someone move the parent to another cgroup and free the old cgroup at <2>;
(3) the sched_task_group and cfs_rq that belong to the old cgroup will be accessed at <3> and <4>, which cause a panic:
[] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 [] PGD 8000001fa0a86067 P4D 8000001fa0a86067 PUD 2029955067 PMD 0 [] Oops: 0000 [#1] SMP PTI [] CPU: 7 PID: 648398 Comm: ebizzy Kdump: loaded Tainted: G OE --------- - - 4.18.0.x86_64+ #1 [] RIP: 0010:sched_slice+0x84/0xc0
[] Call Trace: [] task_fork_fair+0x81/0x120 [] sched_fork+0x132/0x240 [] copy_process.part.5+0x675/0x20e0 [] ? __handle_mm_fault+0x63f/0x690 [] _do_fork+0xcd/0x3b0 [] do_syscall_64+0x5d/0x1d0 [] entry_SYSCALL_64_after_hwframe+0x65/0xca [] RIP: 0033:0x7f04418cd7e1
Between cgroup_can_fork() and cgroup_post_fork(), the cgroup membership and thus sched_task_group can't change. So update child's sched_task_group at sched_post_fork() and move task_fork() and __set_task_cpu() (where accees the sched_task_group) from sched_fork() to sched_post_fork().
Fixes: 8323f26ce342 ("sched: Fix race in task_group") Signed-off-by: Zhang Qiao zhangqiao22@huawei.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Tejun Heo tj@kernel.org Link: https://lkml.kernel.org/r/20210915064030.2231-1-zhangqiao22@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/sched/task.h | 3 ++- kernel/fork.c | 2 +- kernel/sched/core.c | 43 +++++++++++++++++++------------------- 3 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h index ef02be869cf28..ba88a69874004 100644 --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h @@ -54,7 +54,8 @@ extern asmlinkage void schedule_tail(struct task_struct *prev); extern void init_idle(struct task_struct *idle, int cpu);
extern int sched_fork(unsigned long clone_flags, struct task_struct *p); -extern void sched_post_fork(struct task_struct *p); +extern void sched_post_fork(struct task_struct *p, + struct kernel_clone_args *kargs); extern void sched_dead(struct task_struct *p);
void __noreturn do_task_dead(void); diff --git a/kernel/fork.c b/kernel/fork.c index 38681ad44c76b..0e4251dc54361 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -2405,7 +2405,7 @@ static __latent_entropy struct task_struct *copy_process( write_unlock_irq(&tasklist_lock);
proc_fork_connector(p); - sched_post_fork(p); + sched_post_fork(p, args); cgroup_post_fork(p, args); perf_event_fork(p);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f21714ea3db85..aea60eae21a7f 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4328,8 +4328,6 @@ int sysctl_schedstats(struct ctl_table *table, int write, void *buffer, */ int sched_fork(unsigned long clone_flags, struct task_struct *p) { - unsigned long flags; - __sched_fork(clone_flags, p); /* * We mark the process as NEW here. This guarantees that @@ -4375,24 +4373,6 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
init_entity_runnable_average(&p->se);
- /* - * The child is not yet in the pid-hash so no cgroup attach races, - * and the cgroup is pinned to this child due to cgroup_fork() - * is ran before sched_fork(). - * - * Silence PROVE_RCU. - */ - raw_spin_lock_irqsave(&p->pi_lock, flags); - rseq_migrate(p); - /* - * We're setting the CPU for the first time, we don't migrate, - * so use __set_task_cpu(). - */ - __set_task_cpu(p, smp_processor_id()); - if (p->sched_class->task_fork) - p->sched_class->task_fork(p); - raw_spin_unlock_irqrestore(&p->pi_lock, flags); - #ifdef CONFIG_SCHED_INFO if (likely(sched_info_on())) memset(&p->sched_info, 0, sizeof(p->sched_info)); @@ -4408,8 +4388,29 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) return 0; }
-void sched_post_fork(struct task_struct *p) +void sched_post_fork(struct task_struct *p, struct kernel_clone_args *kargs) { + unsigned long flags; +#ifdef CONFIG_CGROUP_SCHED + struct task_group *tg; +#endif + + raw_spin_lock_irqsave(&p->pi_lock, flags); +#ifdef CONFIG_CGROUP_SCHED + tg = container_of(kargs->cset->subsys[cpu_cgrp_id], + struct task_group, css); + p->sched_task_group = autogroup_task_group(p, tg); +#endif + rseq_migrate(p); + /* + * We're setting the CPU for the first time, we don't migrate, + * so use __set_task_cpu(). + */ + __set_task_cpu(p, smp_processor_id()); + if (p->sched_class->task_fork) + p->sched_class->task_fork(p); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); + uclamp_post_fork(p); }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit cd2621d07d517473611b170c69beb6524c677740 ]
On i386, when builtin (not a loadable module), the fealnx driver inspects boot_cpu_data to see what CPU family it is running on, and then acts on that data. The "family" struct member (x86) does not exist when running on UML, so prevent that test and do the default action.
Prevents this build error on UML + i386:
../drivers/net/ethernet/fealnx.c: In function ‘netdev_open’: ../drivers/net/ethernet/fealnx.c:861:19: error: ‘struct cpuinfo_um’ has no member named ‘x86’
Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: linux-um@lists.infradead.org Cc: Jeff Dike jdike@addtoit.com Cc: Richard Weinberger richard@nod.at Cc: Anton Ivanov anton.ivanov@cambridgegreys.com Link: https://lore.kernel.org/r/20211014050500.5620-1-rdunlap@infradead.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/fealnx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c index 25c91b3c5fd30..819266d463b07 100644 --- a/drivers/net/ethernet/fealnx.c +++ b/drivers/net/ethernet/fealnx.c @@ -857,7 +857,7 @@ static int netdev_open(struct net_device *dev) np->bcrvalue |= 0x04; /* big-endian */ #endif
-#if defined(__i386__) && !defined(MODULE) +#if defined(__i386__) && !defined(MODULE) && !defined(CONFIG_UML) if (boot_cpu_data.x86 <= 4) np->crvalue = 0xa00; else
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 523994ba3ad1b7b55abe4a72e156897b5e2db825 ]
On a UML build, the igc_ptp driver uses CONFIG_X86_TSC for timestamp conversion. The function that is used is not available on UML builds, so have the function use the default system_counterval_t timestamp instead for UML builds.
Prevents this build error on UML:
../drivers/net/ethernet/intel/igc/igc_ptp.c: In function ‘igc_device_tstamp_to_system’: ../drivers/net/ethernet/intel/igc/igc_ptp.c:777:9: error: implicit declaration of function ‘convert_art_ns_to_tsc’ [-Werror=implicit-function-declaration] return convert_art_ns_to_tsc(tstamp); ../drivers/net/ethernet/intel/igc/igc_ptp.c:777:9: error: incompatible types when returning type ‘int’ but ‘struct system_counterval_t’ was expected return convert_art_ns_to_tsc(tstamp);
Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: linux-um@lists.infradead.org Cc: Jeff Dike jdike@addtoit.com Cc: Richard Weinberger richard@nod.at Cc: Anton Ivanov anton.ivanov@cambridgegreys.com Cc: Jesse Brandeburg jesse.brandeburg@intel.com Cc: Tony Nguyen anthony.l.nguyen@intel.com Cc: intel-wired-lan@lists.osuosl.org Link: https://lore.kernel.org/r/20211014050516.6846-1-rdunlap@infradead.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/intel/igc/igc_ptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index 0f021909b430a..30568e3544cda 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -773,7 +773,7 @@ static bool igc_is_crosststamp_supported(struct igc_adapter *adapter)
static struct system_counterval_t igc_device_tstamp_to_system(u64 tstamp) { -#if IS_ENABLED(CONFIG_X86_TSC) +#if IS_ENABLED(CONFIG_X86_TSC) && !defined(CONFIG_UML) return convert_art_ns_to_tsc(tstamp); #else return (struct system_counterval_t) { };
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit a3d708925fcca1a2f7219bc9ce93e6341f85c1e0 ]
On i386, when builtin (not a loadable module), the winbond-840 driver inspects boot_cpu_data to see what CPU family it is running on, and then acts on that data. The "family" struct member (x86) does not exist when running on UML, so prevent that test and do the default action.
Prevents this build error on UML + i386:
../drivers/net/ethernet/dec/tulip/winbond-840.c: In function ‘init_registers’: ../drivers/net/ethernet/dec/tulip/winbond-840.c:882:19: error: ‘struct cpuinfo_um’ has no member named ‘x86’ if (boot_cpu_data.x86 <= 4) {
Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: linux-um@lists.infradead.org Cc: Jeff Dike jdike@addtoit.com Cc: Richard Weinberger richard@nod.at Cc: Anton Ivanov anton.ivanov@cambridgegreys.com Link: https://lore.kernel.org/r/20211014050606.7288-1-rdunlap@infradead.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/dec/tulip/winbond-840.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 85b99099c6b94..5babcf05bc2f1 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c @@ -877,7 +877,7 @@ static void init_registers(struct net_device *dev) 8000 16 longwords 0200 2 longwords 2000 32 longwords C000 32 longwords 0400 4 longwords */
-#if defined (__i386__) && !defined(MODULE) +#if defined (__i386__) && !defined(MODULE) && !defined(CONFIG_UML) /* When not a module we can work around broken '486 PCI boards. */ if (boot_cpu_data.x86 <= 4) { i |= 0x4800;
From: Qi Zheng zhengqi.arch@bytedance.com
[ Upstream commit bc9bbb81730ea667c31c5b284f95ee312bab466f ]
Currently, the kernel CONFIG_UNWINDER_ORC option is enabled by default on x86, but the implementation of get_wchan() is still based on the frame pointer unwinder, so the /proc/<pid>/wchan usually returned 0 regardless of whether the task <pid> is running.
Reimplement get_wchan() by calling stack_trace_save_tsk(), which is adapted to the ORC and frame pointer unwinders.
Fixes: ee9f8fce9964 ("x86/unwind: Add the ORC unwinder") Signed-off-by: Qi Zheng zhengqi.arch@bytedance.com Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lkml.kernel.org/r/20211008111626.271115116@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/process.c | 51 +++------------------------------------ 1 file changed, 3 insertions(+), 48 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index f2f733bcb2b95..cd426c3283ee1 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -945,58 +945,13 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) */ unsigned long get_wchan(struct task_struct *p) { - unsigned long start, bottom, top, sp, fp, ip, ret = 0; - int count = 0; + unsigned long entry = 0;
if (p == current || task_is_running(p)) return 0;
- if (!try_get_task_stack(p)) - return 0; - - start = (unsigned long)task_stack_page(p); - if (!start) - goto out; - - /* - * Layout of the stack page: - * - * ----------- topmax = start + THREAD_SIZE - sizeof(unsigned long) - * PADDING - * ----------- top = topmax - TOP_OF_KERNEL_STACK_PADDING - * stack - * ----------- bottom = start - * - * The tasks stack pointer points at the location where the - * framepointer is stored. The data on the stack is: - * ... IP FP ... IP FP - * - * We need to read FP and IP, so we need to adjust the upper - * bound by another unsigned long. - */ - top = start + THREAD_SIZE - TOP_OF_KERNEL_STACK_PADDING; - top -= 2 * sizeof(unsigned long); - bottom = start; - - sp = READ_ONCE(p->thread.sp); - if (sp < bottom || sp > top) - goto out; - - fp = READ_ONCE_NOCHECK(((struct inactive_task_frame *)sp)->bp); - do { - if (fp < bottom || fp > top) - goto out; - ip = READ_ONCE_NOCHECK(*(unsigned long *)(fp + sizeof(unsigned long))); - if (!in_sched_functions(ip)) { - ret = ip; - goto out; - } - fp = READ_ONCE_NOCHECK(*(unsigned long *)fp); - } while (count++ < 16 && !task_is_running(p)); - -out: - put_task_stack(p); - return ret; + stack_trace_save_tsk(p, &entry, 1, 0); + return entry; }
long do_arch_prctl_common(struct task_struct *task, int option,
From: Eric Dumazet edumazet@google.com
[ Upstream commit 19757cebf0c5016a1f36f7fe9810a9f0b33c0832 ]
Use of percpu_counter structure to track count of orphaned sockets is causing problems on modern hosts with 256 cpus or more.
Stefan Bach reported a serious spinlock contention in real workloads, that I was able to reproduce with a netfilter rule dropping incoming FIN packets.
53.56% server [kernel.kallsyms] [k] queued_spin_lock_slowpath | ---queued_spin_lock_slowpath | --53.51%--_raw_spin_lock_irqsave | --53.51%--__percpu_counter_sum tcp_check_oom | |--39.03%--__tcp_close | tcp_close | inet_release | inet6_release | sock_close | __fput | ____fput | task_work_run | exit_to_usermode_loop | do_syscall_64 | entry_SYSCALL_64_after_hwframe | __GI___libc_close | --14.48%--tcp_out_of_resources tcp_write_timeout tcp_retransmit_timer tcp_write_timer_handler tcp_write_timer call_timer_fn expire_timers __run_timers run_timer_softirq __softirqentry_text_start
As explained in commit cf86a086a180 ("net/dst: use a smaller percpu_counter batch for dst entries accounting"), default batch size is too big for the default value of tcp_max_orphans (262144).
But even if we reduce batch sizes, there would still be cases where the estimated count of orphans is beyond the limit, and where tcp_too_many_orphans() has to call the expensive percpu_counter_sum_positive().
One solution is to use plain per-cpu counters, and have a timer to periodically refresh this cache.
Updating this cache every 100ms seems about right, tcp pressure state is not radically changing over shorter periods.
percpu_counter was nice 15 years ago while hosts had less than 16 cpus, not anymore by current standards.
v2: Fix the build issue for CONFIG_CRYPTO_DEV_CHELSIO_TLS=m, reported by kernel test robot lkp@intel.com Remove unused socket argument from tcp_too_many_orphans()
Fixes: dd24c00191d5 ("net: Use a percpu_counter for orphan_count") Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: Stefan Bach sfb@google.com Cc: Neal Cardwell ncardwell@google.com Acked-by: Neal Cardwell ncardwell@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../chelsio/inline_crypto/chtls/chtls_cm.c | 2 +- .../chelsio/inline_crypto/chtls/chtls_cm.h | 2 +- include/net/inet_connection_sock.h | 2 +- include/net/sock.h | 2 +- include/net/tcp.h | 17 ++------- net/dccp/dccp.h | 2 +- net/dccp/proto.c | 14 ++----- net/ipv4/inet_connection_sock.c | 4 +- net/ipv4/inet_hashtables.c | 2 +- net/ipv4/proc.c | 2 +- net/ipv4/tcp.c | 38 ++++++++++++++++--- 11 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c index bcad69c480740..4af5561cbfc54 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c @@ -870,7 +870,7 @@ static void do_abort_syn_rcv(struct sock *child, struct sock *parent) * created only after 3 way handshake is done. */ sock_orphan(child); - percpu_counter_inc((child)->sk_prot->orphan_count); + INC_ORPHAN_COUNT(child); chtls_release_resources(child); chtls_conn_done(child); } else { diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h index b1161bdeda4dc..f61ca657601ca 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h +++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.h @@ -95,7 +95,7 @@ struct deferred_skb_cb { #define WSCALE_OK(tp) ((tp)->rx_opt.wscale_ok) #define TSTAMP_OK(tp) ((tp)->rx_opt.tstamp_ok) #define SACK_OK(tp) ((tp)->rx_opt.sack_ok) -#define INC_ORPHAN_COUNT(sk) percpu_counter_inc((sk)->sk_prot->orphan_count) +#define INC_ORPHAN_COUNT(sk) this_cpu_inc(*(sk)->sk_prot->orphan_count)
/* TLS SKB */ #define skb_ulp_tls_inline(skb) (ULP_SKB_CB(skb)->ulp.tls.ofld) diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index b06c2d02ec84e..fa6a87246a7b8 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -289,7 +289,7 @@ static inline void inet_csk_prepare_for_destroy_sock(struct sock *sk) { /* The below has to be done to allow calling inet_csk_destroy_sock */ sock_set_flag(sk, SOCK_DEAD); - percpu_counter_inc(sk->sk_prot->orphan_count); + this_cpu_inc(*sk->sk_prot->orphan_count); }
void inet_csk_destroy_sock(struct sock *sk); diff --git a/include/net/sock.h b/include/net/sock.h index 463f390d90b3e..7b0c7f5aab676 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1237,7 +1237,7 @@ struct proto { unsigned int useroffset; /* Usercopy region offset */ unsigned int usersize; /* Usercopy region size */
- struct percpu_counter *orphan_count; + unsigned int __percpu *orphan_count;
struct request_sock_ops *rsk_prot; struct timewait_sock_ops *twsk_prot; diff --git a/include/net/tcp.h b/include/net/tcp.h index 60c384569e9cd..31d384c3778a1 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -48,7 +48,9 @@
extern struct inet_hashinfo tcp_hashinfo;
-extern struct percpu_counter tcp_orphan_count; +DECLARE_PER_CPU(unsigned int, tcp_orphan_count); +int tcp_orphan_count_sum(void); + void tcp_time_wait(struct sock *sk, int state, int timeo);
#define MAX_TCP_HEADER L1_CACHE_ALIGN(128 + MAX_HEADER) @@ -290,19 +292,6 @@ static inline bool tcp_out_of_memory(struct sock *sk)
void sk_forced_mem_schedule(struct sock *sk, int size);
-static inline bool tcp_too_many_orphans(struct sock *sk, int shift) -{ - struct percpu_counter *ocp = sk->sk_prot->orphan_count; - int orphans = percpu_counter_read_positive(ocp); - - if (orphans << shift > sysctl_tcp_max_orphans) { - orphans = percpu_counter_sum_positive(ocp); - if (orphans << shift > sysctl_tcp_max_orphans) - return true; - } - return false; -} - bool tcp_check_oom(struct sock *sk, int shift);
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index c5c1d2b8045e8..5183e627468d8 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -48,7 +48,7 @@ extern bool dccp_debug;
extern struct inet_hashinfo dccp_hashinfo;
-extern struct percpu_counter dccp_orphan_count; +DECLARE_PER_CPU(unsigned int, dccp_orphan_count);
void dccp_time_wait(struct sock *sk, int state, int timeo);
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index abb5c596a8176..fc44dadc778bb 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -42,8 +42,8 @@ DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly;
EXPORT_SYMBOL_GPL(dccp_statistics);
-struct percpu_counter dccp_orphan_count; -EXPORT_SYMBOL_GPL(dccp_orphan_count); +DEFINE_PER_CPU(unsigned int, dccp_orphan_count); +EXPORT_PER_CPU_SYMBOL_GPL(dccp_orphan_count);
struct inet_hashinfo dccp_hashinfo; EXPORT_SYMBOL_GPL(dccp_hashinfo); @@ -1055,7 +1055,7 @@ adjudge_to_death: bh_lock_sock(sk); WARN_ON(sock_owned_by_user(sk));
- percpu_counter_inc(sk->sk_prot->orphan_count); + this_cpu_inc(dccp_orphan_count);
/* Have we already been destroyed by a softirq or backlog? */ if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED) @@ -1115,13 +1115,10 @@ static int __init dccp_init(void)
BUILD_BUG_ON(sizeof(struct dccp_skb_cb) > sizeof_field(struct sk_buff, cb)); - rc = percpu_counter_init(&dccp_orphan_count, 0, GFP_KERNEL); - if (rc) - goto out_fail; inet_hashinfo_init(&dccp_hashinfo); rc = inet_hashinfo2_init_mod(&dccp_hashinfo); if (rc) - goto out_free_percpu; + goto out_fail; rc = -ENOBUFS; dccp_hashinfo.bind_bucket_cachep = kmem_cache_create("dccp_bind_bucket", @@ -1226,8 +1223,6 @@ out_free_bind_bucket_cachep: kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); out_free_hashinfo2: inet_hashinfo2_free_mod(&dccp_hashinfo); -out_free_percpu: - percpu_counter_destroy(&dccp_orphan_count); out_fail: dccp_hashinfo.bhash = NULL; dccp_hashinfo.ehash = NULL; @@ -1250,7 +1245,6 @@ static void __exit dccp_fini(void) dccp_ackvec_exit(); dccp_sysctl_exit(); inet_hashinfo2_free_mod(&dccp_hashinfo); - percpu_counter_destroy(&dccp_orphan_count); }
module_init(dccp_init); diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index f25d02ad4a8af..f7fea3a7c5e64 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -1015,7 +1015,7 @@ void inet_csk_destroy_sock(struct sock *sk)
sk_refcnt_debug_release(sk);
- percpu_counter_dec(sk->sk_prot->orphan_count); + this_cpu_dec(*sk->sk_prot->orphan_count);
sock_put(sk); } @@ -1074,7 +1074,7 @@ static void inet_child_forget(struct sock *sk, struct request_sock *req,
sock_orphan(child);
- percpu_counter_inc(sk->sk_prot->orphan_count); + this_cpu_inc(*sk->sk_prot->orphan_count);
if (sk->sk_protocol == IPPROTO_TCP && tcp_rsk(req)->tfo_listener) { BUG_ON(rcu_access_pointer(tcp_sk(child)->fastopen_rsk) != req); diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index bfb522e513461..75737267746f8 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -598,7 +598,7 @@ bool inet_ehash_nolisten(struct sock *sk, struct sock *osk, bool *found_dup_sk) if (ok) { sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); } else { - percpu_counter_inc(sk->sk_prot->orphan_count); + this_cpu_inc(*sk->sk_prot->orphan_count); inet_sk_set_state(sk, TCP_CLOSE); sock_set_flag(sk, SOCK_DEAD); inet_csk_destroy_sock(sk); diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index b0d3a09dc84e7..f30273afb5399 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -53,7 +53,7 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) struct net *net = seq->private; int orphans, sockets;
- orphans = percpu_counter_sum_positive(&tcp_orphan_count); + orphans = tcp_orphan_count_sum(); sockets = proto_sockets_allocated_sum_positive(&tcp_prot);
socket_seq_show(seq); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f5c336f8b0c8e..d13050b68045b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -287,8 +287,8 @@ enum { TCP_CMSG_TS = 2 };
-struct percpu_counter tcp_orphan_count; -EXPORT_SYMBOL_GPL(tcp_orphan_count); +DEFINE_PER_CPU(unsigned int, tcp_orphan_count); +EXPORT_PER_CPU_SYMBOL_GPL(tcp_orphan_count);
long sysctl_tcp_mem[3] __read_mostly; EXPORT_SYMBOL(sysctl_tcp_mem); @@ -2687,11 +2687,36 @@ void tcp_shutdown(struct sock *sk, int how) } EXPORT_SYMBOL(tcp_shutdown);
+int tcp_orphan_count_sum(void) +{ + int i, total = 0; + + for_each_possible_cpu(i) + total += per_cpu(tcp_orphan_count, i); + + return max(total, 0); +} + +static int tcp_orphan_cache; +static struct timer_list tcp_orphan_timer; +#define TCP_ORPHAN_TIMER_PERIOD msecs_to_jiffies(100) + +static void tcp_orphan_update(struct timer_list *unused) +{ + WRITE_ONCE(tcp_orphan_cache, tcp_orphan_count_sum()); + mod_timer(&tcp_orphan_timer, jiffies + TCP_ORPHAN_TIMER_PERIOD); +} + +static bool tcp_too_many_orphans(int shift) +{ + return READ_ONCE(tcp_orphan_cache) << shift > sysctl_tcp_max_orphans; +} + bool tcp_check_oom(struct sock *sk, int shift) { bool too_many_orphans, out_of_socket_memory;
- too_many_orphans = tcp_too_many_orphans(sk, shift); + too_many_orphans = tcp_too_many_orphans(shift); out_of_socket_memory = tcp_out_of_memory(sk);
if (too_many_orphans) @@ -2800,7 +2825,7 @@ adjudge_to_death: /* remove backlog if any, without releasing ownership. */ __release_sock(sk);
- percpu_counter_inc(sk->sk_prot->orphan_count); + this_cpu_inc(tcp_orphan_count);
/* Have we already been destroyed by a softirq or backlog? */ if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE) @@ -4502,7 +4527,10 @@ void __init tcp_init(void) sizeof_field(struct sk_buff, cb));
percpu_counter_init(&tcp_sockets_allocated, 0, GFP_KERNEL); - percpu_counter_init(&tcp_orphan_count, 0, GFP_KERNEL); + + timer_setup(&tcp_orphan_timer, tcp_orphan_update, TIMER_DEFERRABLE); + mod_timer(&tcp_orphan_timer, jiffies + TCP_ORPHAN_TIMER_PERIOD); + inet_hashinfo_init(&tcp_hashinfo); inet_hashinfo2_init(&tcp_hashinfo, "tcp_listen_portaddr_hash", thash_entries, 21, /* one slot per 2 MB*/
From: Ovidiu Panait ovidiu.panait@windriver.com
[ Upstream commit 06f6e365e2ecf799c249bb464aa9d5f055e88b56 ]
Currently, in case of aead fallback, no associated data info is set in the fallback request. To fix this, call aead_request_set_ad() to pass the assoclen.
Fixes: 6f03f0e8b6c8 ("crypto: octeontx2 - register with linux crypto framework") Signed-off-by: Ovidiu Panait ovidiu.panait@windriver.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c index a72723455df72..877a948469bd1 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c @@ -1274,6 +1274,7 @@ static int aead_do_fallback(struct aead_request *req, bool is_enc) req->base.complete, req->base.data); aead_request_set_crypt(&rctx->fbk_req, req->src, req->dst, req->cryptlen, req->iv); + aead_request_set_ad(&rctx->fbk_req, req->assoclen); ret = is_enc ? crypto_aead_encrypt(&rctx->fbk_req) : crypto_aead_decrypt(&rctx->fbk_req); } else {
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit 0a5c26712f963f0500161a23e0ffff8d29f742ab ]
When device_register() return failed, program will goto out_kfree_type to release 'cdev->device' by put_device(). That will call thermal_release() to free 'cdev'. But the follow-up processes access 'cdev' continually. That trggers the UAF bug.
==================================================================== BUG: KASAN: use-after-free in __thermal_cooling_device_register+0x75b/0xa90 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 Call Trace: dump_stack_lvl+0xe2/0x152 print_address_description.constprop.0+0x21/0x140 ? __thermal_cooling_device_register+0x75b/0xa90 kasan_report.cold+0x7f/0x11b ? __thermal_cooling_device_register+0x75b/0xa90 __thermal_cooling_device_register+0x75b/0xa90 ? memset+0x20/0x40 ? __sanitizer_cov_trace_pc+0x1d/0x50 ? __devres_alloc_node+0x130/0x180 devm_thermal_of_cooling_device_register+0x67/0xf0 max6650_probe.cold+0x557/0x6aa ......
Freed by task 258: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 __kasan_slab_free+0x109/0x140 kfree+0x117/0x4c0 thermal_release+0xa0/0x110 device_release+0xa7/0x240 kobject_put+0x1ce/0x540 put_device+0x20/0x30 __thermal_cooling_device_register+0x731/0xa90 devm_thermal_of_cooling_device_register+0x67/0xf0 max6650_probe.cold+0x557/0x6aa [max6650]
Do not use 'cdev' again after put_device() to fix the problem like doing in thermal_zone_device_register().
[dlezcano]: as requested by Rafael, change the affectation into two statements.
Fixes: 584837618100 ("thermal/drivers/core: Use a char pointer for the cooling device name") Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/r/20211015024504.947520-1-william.xuanziyang@huawei.... Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/thermal_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index d094ebbde0ed7..30134f49b037a 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -887,7 +887,7 @@ __thermal_cooling_device_register(struct device_node *np, { struct thermal_cooling_device *cdev; struct thermal_zone_device *pos = NULL; - int ret; + int id, ret;
if (!ops || !ops->get_max_state || !ops->get_cur_state || !ops->set_cur_state) @@ -901,6 +901,7 @@ __thermal_cooling_device_register(struct device_node *np, if (ret < 0) goto out_kfree_cdev; cdev->id = ret; + id = ret;
ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id); if (ret) @@ -944,8 +945,9 @@ __thermal_cooling_device_register(struct device_node *np, out_kfree_type: kfree(cdev->type); put_device(&cdev->device); + cdev = NULL; out_ida_remove: - ida_simple_remove(&thermal_cdev_ida, cdev->id); + ida_simple_remove(&thermal_cdev_ida, id); out_kfree_cdev: kfree(cdev); return ERR_PTR(ret);
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit bf94ec093d05e3ed3142d9291b876eeb9997ba5c ]
The DSI host might be left in some state by the bootloader. If this state generates an IRQ, it might hang the system by holding the interrupt line before the driver sets up the DSI host to the known state.
Move the request_irq into msm_dsi_host_init and pass IRQF_NO_AUTOEN to it. Call enable/disable_irq after msm_dsi_host_power_on/_off() functions, so that we can be sure that the interrupt is delivered when the host is in the known state.
It is not possible to defer the interrupt enablement to a later point, because drm_panel_prepare might need to communicate with the panel over the DSI link and that requires working interrupt.
Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Abhinav Kumar abhinavk@codeaurora.org Link: https://lore.kernel.org/r/20211002010830.647416-1-dmitry.baryshkov@linaro.or... Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/dsi.h | 2 ++ drivers/gpu/drm/msm/dsi/dsi_host.c | 48 +++++++++++++++++---------- drivers/gpu/drm/msm/dsi/dsi_manager.c | 16 +++++++++ 3 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index b50db91cb8a7e..569c8ff062ba4 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -107,6 +107,8 @@ void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 dma_base, u32 len); int msm_dsi_host_enable(struct mipi_dsi_host *host); int msm_dsi_host_disable(struct mipi_dsi_host *host); +void msm_dsi_host_enable_irq(struct mipi_dsi_host *host); +void msm_dsi_host_disable_irq(struct mipi_dsi_host *host); int msm_dsi_host_power_on(struct mipi_dsi_host *host, struct msm_dsi_phy_shared_timings *phy_shared_timings, bool is_bonded_dsi, struct msm_dsi_phy *phy); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index c86b5090fae60..bccd379bdba75 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -1898,6 +1898,23 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi) return ret; }
+ msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + if (msm_host->irq < 0) { + ret = msm_host->irq; + dev_err(&pdev->dev, "failed to get irq: %d\n", ret); + return ret; + } + + /* do not autoenable, will be enabled later */ + ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN, + "dsi_isr", msm_host); + if (ret < 0) { + dev_err(&pdev->dev, "failed to request IRQ%u: %d\n", + msm_host->irq, ret); + return ret; + } + init_completion(&msm_host->dma_comp); init_completion(&msm_host->video_comp); mutex_init(&msm_host->dev_mutex); @@ -1941,25 +1958,8 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; - struct platform_device *pdev = msm_host->pdev; int ret;
- msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - if (msm_host->irq < 0) { - ret = msm_host->irq; - DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); - return ret; - } - - ret = devm_request_irq(&pdev->dev, msm_host->irq, - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "dsi_isr", msm_host); - if (ret < 0) { - DRM_DEV_ERROR(&pdev->dev, "failed to request IRQ%u: %d\n", - msm_host->irq, ret); - return ret; - } - msm_host->dev = dev; ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K); if (ret) { @@ -2315,6 +2315,20 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, clk_req->escclk_rate = msm_host->esc_clk_rate; }
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host) +{ + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + + enable_irq(msm_host->irq); +} + +void msm_dsi_host_disable_irq(struct mipi_dsi_host *host) +{ + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + + disable_irq(msm_host->irq); +} + int msm_dsi_host_enable(struct mipi_dsi_host *host) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index c41d39f5b7cf4..fb4ccffdcfe13 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -377,6 +377,14 @@ static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) } }
+ /* + * Enable before preparing the panel, disable after unpreparing, so + * that the panel can communicate over the DSI link. + */ + msm_dsi_host_enable_irq(host); + if (is_bonded_dsi && msm_dsi1) + msm_dsi_host_enable_irq(msm_dsi1->host); + /* Always call panel functions once, because even for dual panels, * there is only one drm_panel instance. */ @@ -411,6 +419,10 @@ host_en_fail: if (panel) drm_panel_unprepare(panel); panel_prep_fail: + msm_dsi_host_disable_irq(host); + if (is_bonded_dsi && msm_dsi1) + msm_dsi_host_disable_irq(msm_dsi1->host); + if (is_bonded_dsi && msm_dsi1) msm_dsi_host_power_off(msm_dsi1->host); host1_on_fail: @@ -523,6 +535,10 @@ static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) id, ret); }
+ msm_dsi_host_disable_irq(host); + if (is_bonded_dsi && msm_dsi1) + msm_dsi_host_disable_irq(msm_dsi1->host); + /* Save PHY status if it is a clock source */ msm_dsi_phy_pll_save_state(msm_dsi->phy);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 3d91e50ff58364f6572ad268b508175d27800e51 ]
There are two problems here: 1) The "seqptr" is used uninitalized when we free it at the end. 2) The a6xx_gmu_get_mmio() function returns error pointers. It never returns true.
Fixes: 64245fc55172 ("drm/msm/a6xx: use AOP-initialized PDC for a650") Fixes: f8fc924e088e ("drm/msm/a6xx: Fix PDC register overlap") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://lore.kernel.org/r/20211004134530.GB11689@kili Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 8b73f70766a47..4347a104755a9 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -516,11 +516,11 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu) struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; struct platform_device *pdev = to_platform_device(gmu->dev); void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc"); - void __iomem *seqptr; + void __iomem *seqptr = NULL; uint32_t pdc_address_offset; bool pdc_in_aop = false;
- if (!pdcptr) + if (IS_ERR(pdcptr)) goto err;
if (adreno_is_a650(adreno_gpu) || adreno_is_a660_family(adreno_gpu)) @@ -532,7 +532,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
if (!pdc_in_aop) { seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq"); - if (!seqptr) + if (IS_ERR(seqptr)) goto err; }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit b6816441a14bbe356ba8590de79cfea2de6a085c ]
The msm_iommu_new() returns error pointers on failure so check for that to avoid an Oops.
Fixes: ccac7ce373c1 ("drm/msm: Refactor address space initialization") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Abhinav Kumar abhinavk@codeaurora.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Link: https://lore.kernel.org/r/20211004103806.GD25015@kili Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index ae48f41821cfe..ad247c06e198f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -908,6 +908,10 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms) return 0;
mmu = msm_iommu_new(dpu_kms->dev->dev, domain); + if (IS_ERR(mmu)) { + iommu_domain_free(domain); + return PTR_ERR(mmu); + } aspace = msm_gem_address_space_create(mmu, "dpu1", 0x1000, 0x100000000 - 0x1000);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 7425e8167507fe512d8ac0825acda4aebf0a7ca0 ]
Add a missing unlock on the error path if drm_sched_entity_init() fails.
Fixes: 68002469e571 ("drm/msm: One sched entity per process per priority") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20211011124005.GE15188@kili Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_submitqueue.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index b8621c6e05546..7cb158bcbcf67 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -101,6 +101,7 @@ get_sched_entity(struct msm_file_private *ctx, struct msm_ringbuffer *ring,
ret = drm_sched_entity_init(entity, sched_prio, &sched, 1, NULL); if (ret) { + mutex_unlock(&entity_lock); kfree(entity); return ERR_PTR(ret); }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 027d052a36e56789a2134772bacb4fd0860f03a3 ]
The "msm_obj->node" list needs to be initialized earlier so that the list_del() in msm_gem_free_object() doesn't experience a NULL pointer dereference.
Fixes: 6ed0897cd800 ("drm/msm: Fix debugfs deadlock") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20211013081133.GF6010@kili Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_gem.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 22308a1b66fc3..fd398a4eaf46e 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1132,6 +1132,7 @@ static int msm_gem_new_impl(struct drm_device *dev, msm_obj->flags = flags; msm_obj->madv = MSM_MADV_WILLNEED;
+ INIT_LIST_HEAD(&msm_obj->node); INIT_LIST_HEAD(&msm_obj->vmas);
*obj = &msm_obj->base;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 2203bd0e5c12ffc53ffdd4fbd7b12d6ba27e0424 ]
The msm_gem_new_impl() function cleans up after itself so there is no need to call drm_gem_object_put(). Conceptually, it does not make sense to call a kref_put() function until after the reference counting has been initialized which happens immediately after this call in the drm_gem_(private_)object_init() functions.
In the msm_gem_import() function the "obj" pointer is uninitialized, so it will lead to a crash.
Fixes: 05b849111c07 ("drm/msm: prime support") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20211013081315.GG6010@kili Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/msm_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index fd398a4eaf46e..bd6ec04f345e1 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1167,7 +1167,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, uint32_t size, uint32
ret = msm_gem_new_impl(dev, size, flags, &obj); if (ret) - goto fail; + return ERR_PTR(ret);
msm_obj = to_msm_bo(obj);
@@ -1251,7 +1251,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev,
ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj); if (ret) - goto fail; + return ERR_PTR(ret);
drm_gem_private_object_init(dev, obj, size);
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 24bcbe1cc69fa52dc4f7b5b2456678ed464724d8 ]
sk_stream_kill_queues() can be called on close when there are still outstanding skbs to transmit. Those skbs may try to queue notifications to the error queue (e.g. timestamps). If sk_stream_kill_queues() purges the queue without taking its lock the queue may get corrupted, and skbs leaked.
This shows up as a warning about an rmem leak:
WARNING: CPU: 24 PID: 0 at net/ipv4/af_inet.c:154 inet_sock_destruct+0x...
The leak is always a multiple of 0x300 bytes (the value is in %rax on my builds, so RAX: 0000000000000300). 0x300 is truesize of an empty sk_buff. Indeed if we dump the socket state at the time of the warning the sk_error_queue is often (but not always) corrupted. The ->next pointer points back at the list head, but not the ->prev pointer. Indeed we can find the leaked skb by scanning the kernel memory for something that looks like an skb with ->sk = socket in question, and ->truesize = 0x300. The contents of ->cb[] of the skb confirms the suspicion that it is indeed a timestamp notification (as generated in __skb_complete_tx_timestamp()).
Removing purging of sk_error_queue should be okay, since inet_sock_destruct() does it again once all socket refs are gone. Eric suggests this may cause sockets that go thru disconnect() to maintain notifications from the previous incarnations of the socket, but that should be okay since the race was there anyway, and disconnect() is not exactly dependable.
Thanks to Jonathan Lemon and Omar Sandoval for help at various stages of tracing the issue.
Fixes: cb9eff097831 ("net: new user space API for time stamping of incoming and outgoing packets") Signed-off-by: Jakub Kicinski kuba@kernel.org Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/stream.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/net/core/stream.c b/net/core/stream.c index 4f1d4aa5fb38d..a166a32b411fa 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -195,9 +195,6 @@ void sk_stream_kill_queues(struct sock *sk) /* First the read buffer. */ __skb_queue_purge(&sk->sk_receive_queue);
- /* Next, the error queue. */ - __skb_queue_purge(&sk->sk_error_queue); - /* Next, the write queue. */ WARN_ON(!skb_queue_empty(&sk->sk_write_queue));
From: Jackie Liu liuyun01@kylinos.cn
[ Upstream commit 9e5a4fb8423081d0efbf165c71c7f4abdf5f918c ]
Without QCOM_SCM, build failed, avoid like below:
aarch64-linux-gnu-ld: Unexpected GOT/PLT entries detected! aarch64-linux-gnu-ld: Unexpected run-time procedure linkages detected! aarch64-linux-gnu-ld: drivers/thermal/qcom/lmh.o: in function `lmh_probe': /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:141: undefined reference to `qcom_scm_lmh_dcvsh_available' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:144: undefined reference to `qcom_scm_lmh_dcvsh' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:149: undefined reference to `qcom_scm_lmh_dcvsh' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:154: undefined reference to `qcom_scm_lmh_dcvsh' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:159: undefined reference to `qcom_scm_lmh_dcvsh' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:166: undefined reference to `qcom_scm_lmh_profile_change' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:173: undefined reference to `qcom_scm_lmh_dcvsh' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:180: undefined reference to `qcom_scm_lmh_dcvsh' aarch64-linux-gnu-ld: /data/arm/workspace/kernel-build/linux/build/../drivers/thermal/qcom/lmh.c:187: undefined reference to `qcom_scm_lmh_dcvsh' make[1]: *** [/data/arm/workspace/kernel-build/linux/Makefile:1183: vmlinux] Error 1 make[1]: Leaving directory '/data/arm/workspace/kernel-build/linux/build' make: *** [Makefile:219: __sub-make] Error 2 make: Leaving directory '/data/arm/workspace/kernel-build/linux'
Fixes: 53bca371cdf7 ("thermal/drivers/qcom: Add support for LMh driver") Signed-off-by: Jackie Liu liuyun01@kylinos.cn Link: https://lore.kernel.org/r/20211009015853.3509559-1-liu.yun@linux.dev Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/qcom/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig index 7d942f71e5328..bfd889422dd32 100644 --- a/drivers/thermal/qcom/Kconfig +++ b/drivers/thermal/qcom/Kconfig @@ -34,7 +34,7 @@ config QCOM_SPMI_TEMP_ALARM
config QCOM_LMH tristate "Qualcomm Limits Management Hardware" - depends on ARCH_QCOM + depends on ARCH_QCOM && QCOM_SCM help This enables initialization of Qualcomm limits management hardware(LMh). LMh allows for hardware-enforced mitigation for cpus based on
From: jason-jh.lin jason-jh.lin@mediatek.com
[ Upstream commit ce1537fe288469bf68ee0aabdb860a790b4755ef ]
Because mtk_drm_crtc_update_config is not using cmdq_pkt_flush_async, it won't have pkt->async_cb.cb anymore.
So remove the WARN_ON check of pkt->async_cb.cb at cmdq_exec_done.
Fixes: 1b6b0ce2240e ("mailbox: mtk-cmdq: Use mailbox rx_callback") Signed-off-by: jason-jh.lin jason-jh.lin@mediatek.com Reviewed-by: Chun-Kuang Hu chunkuang.hu@kernel.org Tested-by: Enric Balletbo i Serra enric.balletbo@collabora.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mtk-cmdq-mailbox.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 64175a893312e..c591dab9d5a48 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -195,7 +195,6 @@ static void cmdq_task_exec_done(struct cmdq_task *task, int sta) struct cmdq_task_cb *cb = &task->pkt->async_cb; struct cmdq_cb_data data;
- WARN_ON(cb->cb == (cmdq_async_flush_cb)NULL); data.sta = sta; data.data = cb->data; data.pkt = task->pkt;
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 6cb67bea945bdf0ad40e633cd2d9fbeb0855675b ]
Prevent the use of page table macros and types from 2 conflicting places. This fixes multiple build errors and warnings, e.g.:
../arch/x86/include/asm/pgtable_64_types.h:21:34: error: conflicting types for ‘pte_t’ typedef struct { pteval_t pte; } pte_t; ^~~~~ In file included from ../include/linux/mm_types_task.h:16:0, from ../include/linux/mm_types.h:5, from ../include/linux/buildid.h:5, from ../include/linux/module.h:14, from ../drivers/media/pci/ivtv/ivtv-driver.h:40, from ../drivers/media/pci/ivtv/ivtvfb.c:29: ../arch/um/include/asm/page.h:57:39: note: previous declaration of ‘pte_t’ was here typedef struct { unsigned long pte; } pte_t;
../arch/x86/include/asm/pgtable_types.h:284:43: error: expected ‘)’ before ‘prot’ static inline pgprot_t pgprot_nx(pgprot_t prot) ^ ../include/linux/pgtable.h:914:26: note: in definition of macro ‘pgprot_nx’ #define pgprot_nx(prot) (prot) ^~~~ In file included from ../arch/x86/include/asm/memtype.h:6:0, from ../drivers/media/pci/ivtv/ivtvfb.c:40: ../arch/x86/include/asm/pgtable_types.h:288:0: warning: "pgprot_nx" redefined #define pgprot_nx pgprot_nx
../arch/x86/include/asm/page_types.h:11:0: warning: "PAGE_SIZE" redefined #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
In file included from ../include/linux/mm_types_task.h:16:0, from ../include/linux/mm_types.h:5, from ../include/linux/buildid.h:5, from ../include/linux/module.h:14, from ../drivers/media/pci/ivtv/ivtv-driver.h:40, from ../drivers/media/pci/ivtv/ivtvfb.c:29: ../arch/um/include/asm/page.h:14:0: note: this is the location of the previous definition #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
Fixes: 68f5d3f3b654 ("um: add PCI over virtio emulation driver") Signed-off-by: Randy Dunlap rdunlap@infradead.org Cc: Johannes Berg johannes@sipsolutions.net Cc: Andy Walls awalls@md.metrocast.net Cc: linux-um@lists.infradead.org Cc: Richard Weinberger richard@nod.at Signed-off-by: Hans Verkuil hverkuil-cisco@xs4all.nl Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/pci/ivtv/ivtvfb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index e2d56dca5be40..5ad03b2a50bdb 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -36,7 +36,7 @@ #include <linux/fb.h> #include <linux/ivtvfb.h>
-#ifdef CONFIG_X86_64 +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) #include <asm/memtype.h> #endif
@@ -1157,7 +1157,7 @@ static int ivtvfb_init_card(struct ivtv *itv) { int rc;
-#ifdef CONFIG_X86_64 +#if defined(CONFIG_X86_64) && !defined(CONFIG_UML) if (pat_enabled()) { if (ivtvfb_force_pat) { pr_info("PAT is enabled. Write-combined framebuffer caching will be disabled.\n");
From: Sean Young sean@mess.org
[ Upstream commit febfe985fc2ea052a363f6525ff624b8efd5273c ]
commit f0c15b360fb6 ("media: ir_toy: prevent device from hanging during transmit") removed a cpu_to_be16() cast, which causes a sparse warning.
Fixes: f0c15b360fb6 ("media: ir_toy: prevent device from hanging during transmit") Reported-by: Hans Verkuil hverkuil@xs4all.nl Signed-off-by: Sean Young sean@mess.org Signed-off-by: Mauro Carvalho Chehab mchehab+huawei@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/rc/ir_toy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c index 48d52baec1a1c..1aa7989e756cc 100644 --- a/drivers/media/rc/ir_toy.c +++ b/drivers/media/rc/ir_toy.c @@ -310,7 +310,7 @@ static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count) buf[i] = cpu_to_be16(v); }
- buf[count] = 0xffff; + buf[count] = cpu_to_be16(0xffff);
irtoy->tx_buf = buf; irtoy->tx_len = size;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit ce5f6c2c9b0fcb4094f8e162cfd37fb4294204f7 ]
The 'reg_vmmc' regulator is enabled in the probe. It is never disabled. Neither in the error handling path of the probe nor in the remove function.
Register a devm_action to disable it when needed.
Fixes: 4dc5a79f1350 ("mmc: mxs-mmc: enable regulator for mmc slot") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/4aadb3c97835f7b80f00819c3d549e6130384e67.163436515... Signed-off-by: Ulf Hansson ulf.hansson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/mxs-mmc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 947581de78601..8c3655d3be961 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -552,6 +552,11 @@ static const struct of_device_id mxs_mmc_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
+static void mxs_mmc_regulator_disable(void *regulator) +{ + regulator_disable(regulator); +} + static int mxs_mmc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -591,6 +596,11 @@ static int mxs_mmc_probe(struct platform_device *pdev) "Failed to enable vmmc regulator: %d\n", ret); goto out_mmc_free; } + + ret = devm_add_action_or_reset(&pdev->dev, mxs_mmc_regulator_disable, + reg_vmmc); + if (ret) + goto out_mmc_free; }
ssp->clk = devm_clk_get(&pdev->dev, NULL);
From: Bixuan Cui cuibixuan@huawei.com
[ Upstream commit 71e1cef2d794338cc7b979d4c6144e1dc12718b5 ]
While task_work_add() in io_workqueue_create() is true, then duplicate code is executed:
-> clear_bit_unlock(0, &worker->create_state); -> io_worker_release(worker); -> atomic_dec(&acct->nr_running); -> io_worker_ref_put(wq); -> return false;
-> clear_bit_unlock(0, &worker->create_state); // back to io_workqueue_create() -> io_worker_release(worker); -> kfree(worker);
The io_worker_release() and clear_bit_unlock() are executed twice.
Fixes: 3146cba99aa2 ("io-wq: make worker creation resilient against signals") Signed-off-by: Bixuan Cui cuibixuan@huawei.com Link: https://lore.kernel.org/r/20210911085847.34849-1-cuibixuan@huawei.com Reviwed-by: Hao Xu haoxu@linux.alibaba.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/io-wq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/fs/io-wq.c b/fs/io-wq.c index 203c0e2a5dfae..5d189b24a8d4b 100644 --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -359,8 +359,10 @@ static bool io_queue_worker_create(struct io_worker *worker,
init_task_work(&worker->create_work, func); worker->create_index = acct->index; - if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) + if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) { + clear_bit_unlock(0, &worker->create_state); return true; + } clear_bit_unlock(0, &worker->create_state); fail_release: io_worker_release(worker); @@ -765,11 +767,8 @@ static void io_workqueue_create(struct work_struct *work) struct io_worker *worker = container_of(work, struct io_worker, work); struct io_wqe_acct *acct = io_wqe_get_acct(worker);
- if (!io_queue_worker_create(worker, acct, create_worker_cont)) { - clear_bit_unlock(0, &worker->create_state); - io_worker_release(worker); + if (!io_queue_worker_create(worker, acct, create_worker_cont)) kfree(worker); - } }
static bool create_io_worker(struct io_wq *wq, struct io_wqe *wqe, int index)
From: Michael Schmitz schmitzmic@gmail.com
[ Upstream commit 86d46fdaa12ae5befc16b8d73fc85a3ca0399ea6 ]
Refactoring of the Atari floppy driver when converting to blk-mq has broken the state machine in not-so-subtle ways:
finish_fdc() must be called when operations on the floppy device have completed. This is crucial in order to relase the ST-DMA lock, which protects against concurrent access to the ST-DMA controller by other drivers (some DMA related, most just related to device register access - broken beyond compare, I know).
When rewriting the driver's old do_request() function, the fact that finish_fdc() was called only when all queued requests had completed appears to have been overlooked. Instead, the new request function calls finish_fdc() immediately after the last request has been queued. finish_fdc() executes a dummy seek after most requests, and this overwrites the state machine's interrupt hander that was set up to wait for completion of the read/write request just prior. To make matters worse, finish_fdc() is called before device interrupts are re-enabled, making certain that the read/write interupt is missed.
Shifting the finish_fdc() call into the read/write request completion handler ensures the driver waits for the request to actually complete. With a queue depth of 2, we won't see long request sequences, so calling finish_fdc() unconditionally just adds a little overhead for the dummy seeks, and keeps the code simple.
While we're at it, kill ataflop_commit_rqs() which does nothing but run finish_fdc() unconditionally, again likely wiping out an in-flight request.
Signed-off-by: Michael Schmitz schmitzmic@gmail.com Fixes: 6ec3938cff95 ("ataflop: convert to blk-mq") CC: linux-block@vger.kernel.org CC: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Link: https://lore.kernel.org/r/20211019061321.26425-1-schmitzmic@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ataflop.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index a093644ac39fb..bbb64331cf8f4 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -653,9 +653,6 @@ static inline void copy_buffer(void *from, void *to) *p2++ = *p1++; }
- - - /* General Interrupt Handling */
static void (*FloppyIRQHandler)( int status ) = NULL; @@ -1228,6 +1225,7 @@ static void fd_rwsec_done1(int status) } else { /* all sectors finished */ + finish_fdc(); fd_end_request_cur(BLK_STS_OK); } return; @@ -1475,15 +1473,6 @@ static void setup_req_params( int drive ) ReqTrack, ReqSector, (unsigned long)ReqData )); }
-static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx) -{ - spin_lock_irq(&ataflop_lock); - atari_disable_irq(IRQ_MFP_FDC); - finish_fdc(); - atari_enable_irq(IRQ_MFP_FDC); - spin_unlock_irq(&ataflop_lock); -} - static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { @@ -1491,6 +1480,8 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, int drive = floppy - unit; int type = floppy->type;
+ DPRINT(("Queue request: drive %d type %d last %d\n", drive, type, bd->last)); + spin_lock_irq(&ataflop_lock); if (fd_request) { spin_unlock_irq(&ataflop_lock); @@ -1550,8 +1541,6 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, setup_req_params( drive ); do_fd_action( drive );
- if (bd->last) - finish_fdc(); atari_enable_irq( IRQ_MFP_FDC );
out: @@ -1962,7 +1951,6 @@ static const struct block_device_operations floppy_fops = {
static const struct blk_mq_ops ataflop_mq_ops = { .queue_rq = ataflop_queue_rq, - .commit_rqs = ataflop_commit_rqs, };
static int ataflop_alloc_disk(unsigned int drive, unsigned int type)
From: Andrea Righi andrea.righi@canonical.com
[ Upstream commit 480d42dc001bbfe953825a92073012fcd5a99161 ]
The timer callback used to evaluate if the latency is exceeded can be executed after the corresponding disk has been released, causing the following NULL pointer dereference:
[ 119.987108] BUG: kernel NULL pointer dereference, address: 0000000000000098 [ 119.987617] #PF: supervisor read access in kernel mode [ 119.987971] #PF: error_code(0x0000) - not-present page [ 119.988325] PGD 7c4a4067 P4D 7c4a4067 PUD 7bf63067 PMD 0 [ 119.988697] Oops: 0000 [#1] SMP NOPTI [ 119.988959] CPU: 1 PID: 9353 Comm: cloud-init Not tainted 5.15-rc5+arighi #rc5+arighi [ 119.989520] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-2 04/01/2014 [ 119.990055] RIP: 0010:wb_timer_fn+0x44/0x3c0 [ 119.990376] Code: 41 8b 9c 24 98 00 00 00 41 8b 94 24 b8 00 00 00 41 8b 84 24 d8 00 00 00 4d 8b 74 24 28 01 d3 01 c3 49 8b 44 24 60 48 8b 40 78 <4c> 8b b8 98 00 00 00 4d 85 f6 0f 84 c4 00 00 00 49 83 7c 24 30 00 [ 119.991578] RSP: 0000:ffffb5f580957da8 EFLAGS: 00010246 [ 119.991937] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000004 [ 119.992412] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88f476d7f780 [ 119.992895] RBP: ffffb5f580957dd0 R08: 0000000000000000 R09: 0000000000000000 [ 119.993371] R10: 0000000000000004 R11: 0000000000000002 R12: ffff88f476c84500 [ 119.993847] R13: ffff88f4434390c0 R14: 0000000000000000 R15: ffff88f4bdc98c00 [ 119.994323] FS: 00007fb90bcd9c00(0000) GS:ffff88f4bdc80000(0000) knlGS:0000000000000000 [ 119.994952] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 119.995380] CR2: 0000000000000098 CR3: 000000007c0d6000 CR4: 00000000000006e0 [ 119.995906] Call Trace: [ 119.996130] ? blk_stat_free_callback_rcu+0x30/0x30 [ 119.996505] blk_stat_timer_fn+0x138/0x140 [ 119.996830] call_timer_fn+0x2b/0x100 [ 119.997136] __run_timers.part.0+0x1d1/0x240 [ 119.997470] ? kvm_clock_get_cycles+0x11/0x20 [ 119.997826] ? ktime_get+0x3e/0xa0 [ 119.998110] ? native_apic_msr_write+0x2c/0x30 [ 119.998456] ? lapic_next_event+0x20/0x30 [ 119.998779] ? clockevents_program_event+0x94/0xf0 [ 119.999150] run_timer_softirq+0x2a/0x50 [ 119.999465] __do_softirq+0xcb/0x26f [ 119.999764] irq_exit_rcu+0x8c/0xb0 [ 120.000057] sysvec_apic_timer_interrupt+0x43/0x90 [ 120.000429] ? asm_sysvec_apic_timer_interrupt+0xa/0x20 [ 120.000836] asm_sysvec_apic_timer_interrupt+0x12/0x20
In this case simply return from the timer callback (no action required) to prevent the NULL pointer dereference.
BugLink: https://bugs.launchpad.net/bugs/1947557 Link: https://lore.kernel.org/linux-mm/YWRNVTk9N8K0RMst@arighi-desktop/ Fixes: 34dbad5d26e2 ("blk-stat: convert to callback-based statistics reporting") Signed-off-by: Andrea Righi andrea.righi@canonical.com Link: https://lore.kernel.org/r/YW6N2qXpBU3oc50q@arighi-desktop Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-wbt.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/block/blk-wbt.c b/block/blk-wbt.c index 874c1c37bf0c6..0c119be0e8133 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -357,6 +357,9 @@ static void wb_timer_fn(struct blk_stat_callback *cb) unsigned int inflight = wbt_inflight(rwb); int status;
+ if (!rwb->rqos.q->disk) + return; + status = latency_exceeded(rwb, cb->stat);
trace_wbt_timer(rwb->rqos.q->disk->bdi, status, rqd->scale_step,
From: Nathan Chancellor nathan@kernel.org
[ Upstream commit fd96e35ea7b95f1e216277805be89d66e4ae962d ]
A new warning in clang points out a use of bitwise OR with boolean expressions in this driver:
drivers/platform/x86/thinkpad_acpi.c:9061:11: error: use of bitwise '|' with boolean operands [-Werror,-Wbitwise-instead-of-logical] else if ((strlencmp(cmd, "level disengaged") == 0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ || drivers/platform/x86/thinkpad_acpi.c:9061:11: note: cast one or both operands to int to silence this warning 1 error generated.
This should clearly be a logical OR so change it to fix the warning.
Fixes: fe98a52ce754 ("ACPI: thinkpad-acpi: add sysfs support to fan subdriver") Link: https://github.com/ClangBuiltLinux/linux/issues/1476 Reported-by: Tor Vic torvic9@mailbox.org Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Nick Desaulniers ndesaulniers@google.com Link: https://lore.kernel.org/r/20211018182537.2316800-1-nathan@kernel.org 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/thinkpad_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 50ff04c84650c..27595aba214d9 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -9145,7 +9145,7 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
if (strlencmp(cmd, "level auto") == 0) level = TP_EC_FAN_AUTO; - else if ((strlencmp(cmd, "level disengaged") == 0) | + else if ((strlencmp(cmd, "level disengaged") == 0) || (strlencmp(cmd, "level full-speed") == 0)) level = TP_EC_FAN_FULLSPEED; else if (sscanf(cmd, "level %d", &level) != 1)
From: Fei Shao fshao@chromium.org
[ Upstream commit 5c154b6a51c2d2d7f266b3ef49b7dd1dc8cb5b65 ]
of_alias_get_id() may return -ENODEV which leads to illegal access to the cmdq->clocks array. Adding a check over alias_id to prevent the unexpected behavior.
Fixes: 85dfdbfc13ea ("mailbox: cmdq: add multi-gce clocks support for mt8195") Signed-off-by: Fei Shao fshao@chromium.org Reviewed-by: Tzung-Bi Shih tzungbi@google.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mtk-cmdq-mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index c591dab9d5a48..9b0cc3bb5b23a 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -572,7 +572,7 @@ static int cmdq_probe(struct platform_device *pdev) char clk_id[8];
alias_id = of_alias_get_id(node, clk_name); - if (alias_id < cmdq->gce_num) { + if (alias_id >= 0 && alias_id < cmdq->gce_num) { snprintf(clk_id, sizeof(clk_id), "%s%d", clk_name, alias_id); cmdq->clocks[alias_id].id = clk_id; cmdq->clocks[alias_id].clk = of_clk_get(node, 0);
From: Fei Shao fshao@chromium.org
[ Upstream commit 0a5ad4322927ee4aaba6facc0e4faf1ab6c0d48e ]
In the probe function, the clock IDs were pointed to local variables which should only be used in the same code block, and any access to them after the probing stage becomes an use-after-free case.
Since there are only limited variants of the gce clock names so far, we can just declare them as static constants to fix the issue.
Fixes: 85dfdbfc13ea ("mailbox: cmdq: add multi-gce clocks support for mt8195") Signed-off-by: Fei Shao fshao@chromium.org Reviewed-by: Tzung-Bi Shih tzungbi@google.com Signed-off-by: Jassi Brar jaswinder.singh@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mtk-cmdq-mailbox.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 9b0cc3bb5b23a..bb4793c7b38fd 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -531,7 +531,8 @@ static int cmdq_probe(struct platform_device *pdev) struct device_node *phandle = dev->of_node; struct device_node *node; int alias_id = 0; - char clk_name[4] = "gce"; + static const char * const clk_name = "gce"; + static const char * const clk_names[] = { "gce0", "gce1" };
cmdq = devm_kzalloc(dev, sizeof(*cmdq), GFP_KERNEL); if (!cmdq) @@ -569,12 +570,9 @@ static int cmdq_probe(struct platform_device *pdev)
if (cmdq->gce_num > 1) { for_each_child_of_node(phandle->parent, node) { - char clk_id[8]; - alias_id = of_alias_get_id(node, clk_name); if (alias_id >= 0 && alias_id < cmdq->gce_num) { - snprintf(clk_id, sizeof(clk_id), "%s%d", clk_name, alias_id); - cmdq->clocks[alias_id].id = clk_id; + cmdq->clocks[alias_id].id = clk_names[alias_id]; cmdq->clocks[alias_id].clk = of_clk_get(node, 0); if (IS_ERR(cmdq->clocks[alias_id].clk)) { dev_err(dev, "failed to get gce clk: %d\n", alias_id);
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit 7a63296d6f579a02b2675b4b0fe5b1cd3235e8d3 ]
If an ACPI power resource is found to be "on" during the initialization of the list of wakeup power resources of a device, it is reference counted and its wakeup_enabled flag is set, which is problematic if the deivce in question is the only user of the given power resource, it is never runtime-suspended and it is not allowed to wake up the system from sleep, because in that case the given power resource will stay "on" until the system reboots and energy will be wasted.
It is better to simply turn off wakeup power resources that are "on" during the initialization unless their reference counters are not zero, because that may be the only opportunity to prevent them from staying in the "on" state all the time.
Fixes: b5d667eb392e ("ACPI / PM: Take unusual configurations of power resources into account") Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/power.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f0ed4414edb1f..3d34cee0cc101 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -615,20 +615,19 @@ int acpi_power_wakeup_list_init(struct list_head *list, int *system_level_p)
list_for_each_entry(entry, list, node) { struct acpi_power_resource *resource = entry->resource; - int result; u8 state;
mutex_lock(&resource->resource_lock);
- result = acpi_power_get_state(resource, &state); - if (result) { - mutex_unlock(&resource->resource_lock); - return result; - } - if (state == ACPI_POWER_RESOURCE_STATE_ON) { - resource->ref_count++; - resource->wakeup_enabled = true; - } + /* + * Make sure that the power resource state and its reference + * counter value are consistent with each other. + */ + if (!resource->ref_count && + !acpi_power_get_state(resource, &state) && + state == ACPI_POWER_RESOURCE_STATE_ON) + __acpi_power_off(resource); + if (system_level > resource->system_level) system_level = resource->system_level;
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit a2d7b2e004af6b09f21ac3d10f8f4456c16a8ddf ]
If an ACPI wakeup power resource is shared between multiple devices, it may not be managed correctly.
Suppose, for example, that two devices, A and B, share a wakeup power resource P whose wakeup_enabled flag is 0 initially. Next, suppose that wakeup power is enabled for A and B, in this order, and disabled for B. When wakeup power is enabled for A, P will be turned on and its wakeup_enabled flag will be set. Next, when wakeup power is enabled for B, P will not be touched, because its wakeup_enabled flag is set. Now, when wakeup power is disabled for B, P will be turned off which is incorrect, because A will still need P in order to signal wakeup.
Moreover, if wakeup power is enabled for A and then disabled for B, the latter will cause P to be turned off incorrectly (it will be still needed by A), because acpi_disable_wakeup_device_power() is allowed to manipulate power resources when the wakeup.prepare_count counter of the given device is 0.
While the first issue could be addressed by changing the wakeup_enabled power resource flag into a counter, addressing the second one requires modifying acpi_disable_wakeup_device_power() to do nothing when the target device's wakeup.prepare_count reference counter is zero and that would cause the new counter to be redundant. Namely, if acpi_disable_wakeup_device_power() is modified as per the above, every change of the new counter following a wakeup.prepare_count change would be reflected by the analogous change of the main reference counter of the given power resource.
Accordingly, modify acpi_disable_wakeup_device_power() to do nothing when the target device's wakeup.prepare_count reference counter is zero and drop the power resource wakeup_enabled flag altogether.
While at it, ensure that all of the power resources that can be turned off will be turned off when disabling device wakeup due to a power resource manipulation error, to prevent energy from being wasted.
Fixes: b5d667eb392e ("ACPI / PM: Take unusual configurations of power resources into account") Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/power.c | 69 +++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 45 deletions(-)
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 3d34cee0cc101..4b42debeed455 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -52,7 +52,6 @@ struct acpi_power_resource { u32 order; unsigned int ref_count; u8 state; - bool wakeup_enabled; struct mutex resource_lock; struct list_head dependents; }; @@ -710,7 +709,6 @@ int acpi_device_sleep_wake(struct acpi_device *dev, */ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) { - struct acpi_power_resource_entry *entry; int err = 0;
if (!dev || !dev->wakeup.flags.valid) @@ -721,26 +719,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) if (dev->wakeup.prepare_count++) goto out;
- list_for_each_entry(entry, &dev->wakeup.resources, node) { - struct acpi_power_resource *resource = entry->resource; - - mutex_lock(&resource->resource_lock); - - if (!resource->wakeup_enabled) { - err = acpi_power_on_unlocked(resource); - if (!err) - resource->wakeup_enabled = true; - } - - mutex_unlock(&resource->resource_lock); - - if (err) { - dev_err(&dev->dev, - "Cannot turn wakeup power resources on\n"); - dev->wakeup.flags.valid = 0; - goto out; - } + err = acpi_power_on_list(&dev->wakeup.resources); + if (err) { + dev_err(&dev->dev, "Cannot turn on wakeup power resources\n"); + dev->wakeup.flags.valid = 0; + goto out; } + /* * Passing 3 as the third argument below means the device may be * put into arbitrary power state afterward. @@ -770,39 +755,33 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
mutex_lock(&acpi_device_lock);
- if (--dev->wakeup.prepare_count > 0) + if (dev->wakeup.prepare_count > 1) { + dev->wakeup.prepare_count--; goto out; + }
- /* - * Executing the code below even if prepare_count is already zero when - * the function is called may be useful, for example for initialisation. - */ - if (dev->wakeup.prepare_count < 0) - dev->wakeup.prepare_count = 0; + /* Do nothing if wakeup power has not been enabled for this device. */ + if (!dev->wakeup.prepare_count) + goto out;
err = acpi_device_sleep_wake(dev, 0, 0, 0); if (err) goto out;
+ /* + * All of the power resources in the list need to be turned off even if + * there are errors. + */ list_for_each_entry(entry, &dev->wakeup.resources, node) { - struct acpi_power_resource *resource = entry->resource; - - mutex_lock(&resource->resource_lock); - - if (resource->wakeup_enabled) { - err = acpi_power_off_unlocked(resource); - if (!err) - resource->wakeup_enabled = false; - } - - mutex_unlock(&resource->resource_lock); + int ret;
- if (err) { - dev_err(&dev->dev, - "Cannot turn wakeup power resources off\n"); - dev->wakeup.flags.valid = 0; - break; - } + ret = acpi_power_off(entry->resource); + if (ret && !err) + err = ret; + } + if (err) { + dev_err(&dev->dev, "Cannot turn off wakeup power resources\n"); + dev->wakeup.flags.valid = 0; }
out:
From: Lang Yu lang.yu@amd.com
[ Upstream commit 5aeeac6fa38fca450faed9770f75b1470c0e2073 ]
We should unreference a gem object instead of an amdgpu bo here.
Fixes: fd9a9f8801de ("drm/amdgpu: Use GEM obj reference for KFD BOs")
Signed-off-by: Lang Yu lang.yu@amd.com Reviewed-by: Felix Kuehling Felix.Kuehling@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 054c1a224defb..cdf46bd0d8d5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1503,7 +1503,7 @@ allocate_init_user_pages_failed: remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info); drm_vma_node_revoke(&gobj->vma_node, drm_priv); err_node_allow: - amdgpu_bo_unref(&bo); + drm_gem_object_put(gobj); /* Don't unreserve system mem limit twice */ goto err_reserve_limit; err_bo_create:
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit df040215c077de0c13aab12c222bd0360a0d3988 ]
Fix endianness in mt7921_mcu_tx_done_event event reported by the firmware.
Fixes: 3cce2b98e0241 ("mt76: mt7921: introduce mac tx done handling") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 3 ++- drivers/net/wireless/mediatek/mt76/mt7921/mcu.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 9fbaacc67cfad..68840e55ede7a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -532,7 +532,8 @@ mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb) peer.g8 = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); peer.g16 = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); mt7921_mcu_tx_rate_parse(mphy->mt76, &peer, - &msta->stats.tx_rate, event->tx_rate); + &msta->stats.tx_rate, + le16_to_cpu(event->tx_rate));
spin_lock_bh(&dev->sta_poll_lock); break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h index de3c091f67368..42e7271848956 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h @@ -296,11 +296,11 @@ struct mt7921_txpwr_event { struct mt7921_mcu_tx_done_event { u8 pid; u8 status; - u16 seq; + __le16 seq;
u8 wlan_idx; u8 tx_cnt; - u16 tx_rate; + __le16 tx_rate;
u8 flag; u8 tid; @@ -312,9 +312,9 @@ struct mt7921_mcu_tx_done_event { u8 reason; u8 rsv0[1];
- u32 delay; - u32 timestamp; - u32 applied_flag; + __le32 delay; + __le32 timestamp; + __le32 applied_flag;
u8 txs[28];
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 08b3c8da87aed4200dab00906f149d675ca90f23 ]
Fix the following sparse warning in mt7915_mac_add_txs_skb routine:
drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1235:29: warning: cast to restricted __le32 drivers/net/wireless/mediatek/mt76/mt7915/mac.c:1235:23: warning: restricted __le32 degrades to integer
Fixes: 3de4cb1756565 ("mt76: mt7915: add support for tx status reporting") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 2462704094b0a..bbc996f86b5c3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -1232,7 +1232,7 @@ mt7915_mac_add_txs_skb(struct mt7915_dev *dev, struct mt76_wcid *wcid, int pid, goto out;
info = IEEE80211_SKB_CB(skb); - if (!(txs_data[0] & le32_to_cpu(MT_TXS0_ACK_ERROR_MASK))) + if (!(txs_data[0] & cpu_to_le32(MT_TXS0_ACK_ERROR_MASK))) info->flags |= IEEE80211_TX_STAT_ACK;
info->status.ampdu_len = 1;
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 7fc167bbc9296e6aeaaa4063db3639e8a3db75f6 ]
Fix the following sparse warning in mt7921_update_txs routine: drivers/net/wireless/mediatek/mt76/mt7921/mac.c:752:31: warning: cast to restricted __le32 drivers/net/wireless/mediatek/mt76/mt7921/mac.c:752:31: warning: restricted __le32 degrades to integer
Fixes: e5bca8c5d2cd3 ("mt76: mt7921: improve code readability for mt7921_update_txs") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 7fe2e3a50428f..f4714b0f6e5c4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -735,8 +735,9 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, static void mt7921_update_txs(struct mt76_wcid *wcid, __le32 *txwi) { struct mt7921_sta *msta = container_of(wcid, struct mt7921_sta, wcid); - u32 pid, frame_type = FIELD_GET(MT_TXD2_FRAME_TYPE, txwi[2]); + u32 pid, frame_type;
+ frame_type = FIELD_GET(MT_TXD2_FRAME_TYPE, le32_to_cpu(txwi[2])); if (!(frame_type & (IEEE80211_FTYPE_DATA >> 2))) return;
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit d81bfb41e30c42531536c5d2baa4d275a8309715 ]
Fix the following sparse warning in mt7615_mac_write_txwi routine: drivers/net/wireless/mediatek/mt76/mt7615/mac.c:758:17: warning: incorrect type in assignment expected restricted __le32 [usertype] got unsigned long
Fixes: 04b8e65922f63 ("mt76: add mac80211 driver for MT7615 PCIe-based chipsets") Fixes: d4bf77bd74930 ("mt76: mt7615: introduce mt7663u support to mt7615_write_txwi") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index a83e48c07a71e..5455231f51881 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -755,12 +755,15 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, if (info->flags & IEEE80211_TX_CTL_NO_ACK) txwi[3] |= cpu_to_le32(MT_TXD3_NO_ACK);
- txwi[7] = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype) | - FIELD_PREP(MT_TXD7_SPE_IDX, 0x18); - if (!is_mmio) - txwi[8] = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) | - FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype); + val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | + FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype) | + FIELD_PREP(MT_TXD7_SPE_IDX, 0x18); + txwi[7] = cpu_to_le32(val); + if (!is_mmio) { + val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) | + FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype); + txwi[8] = cpu_to_le32(val); + }
return 0; }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 3924715ffe5e064a85f56490f77b7b2084230800 ]
Zero out all the unused members of "req" so that we don't disclose stack information.
Fixes: 495184ac91bb ("mt76: mt7915: add support for applying pre-calibration data") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Acked-by: Felix Fietkau nbd@nbd.name Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 2f30047bd80f2..caf2033c5c17e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -3481,7 +3481,7 @@ static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx, u8 idx; u8 rsv[4]; __le32 len; - } req; + } req = {}; struct sk_buff *skb;
skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req) + len);
From: Leon Yen Leon.Yen@mediatek.com
[ Upstream commit d741abeafa47a7331cd4fe526e44db4ad3da0f62 ]
The mistaken structure is introduced since we added the GTK rekey offload to mt7663. The patch fixes mt76_connac_gtk_rekey_tlv structure according to the MT7663 and MT7921 firmware we have submitted into linux-firmware.git.
Fixes: b47e21e75c80 ("mt76: mt7615: add gtk rekey offload support") Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Leon Yen Leon.Yen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 1c73beb226771..4bcd728ff97c5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -844,14 +844,14 @@ struct mt76_connac_gtk_rekey_tlv { * 2: rekey update */ u8 keyid; - u8 pad[2]; + u8 option; /* 1: rekey data update without enabling offload */ + u8 pad[1]; __le32 proto; /* WPA-RSN-WAPI-OPSN */ __le32 pairwise_cipher; __le32 group_cipher; __le32 key_mgmt; /* NONE-PSK-IEEE802.1X */ __le32 mgmt_group_cipher; - u8 option; /* 1: rekey data update without enabling offload */ - u8 reserverd[3]; + u8 reserverd[4]; } __packed;
#define MT76_CONNAC_WOW_MASK_MAX_LEN 16
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit adedbc643f02f5a3193b8dcc5cfca97b4c988667 ]
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c:114:10: error: implicit conversion from enumeration type 'enum mt76_cipher_type' to different enumeration type 'enum mcu_cipher_type' [-Werror,-Wenum-conversion] return MT_CIPHER_NONE; ~~~~~~ ^~~~~~~~~~~~~~
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c:114:10: error: implicit conversion from enumeration type 'enum mt76_cipher_type' to different enumeration type 'enum mcu_cipher_type' [-Werror,-Wenum-conversion] return MT_CIPHER_NONE; ~~~~~~ ^~~~~~~~~~~~~~
Fixes: c368362c36d3 ("mt76: fix iv and CCMP header insertion") Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index caf2033c5c17e..c08c7398f9b85 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -1201,7 +1201,7 @@ mt7915_mcu_sta_key_tlv(struct mt7915_sta *msta, struct sk_buff *skb, u8 cipher;
cipher = mt7915_mcu_get_cipher(key->cipher); - if (cipher == MT_CIPHER_NONE) + if (cipher == MCU_CIPHER_NONE) return -EOPNOTSUPP;
sec_key = &sec->key[0]; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 68840e55ede7a..8329b705c2ca2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -620,7 +620,7 @@ mt7921_mcu_sta_key_tlv(struct mt7921_sta *msta, struct sk_buff *skb, u8 cipher;
cipher = mt7921_mcu_get_cipher(key->cipher); - if (cipher == MT_CIPHER_NONE) + if (cipher == MCU_CIPHER_NONE) return -EOPNOTSUPP;
sec_key = &sec->key[0];
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 64ed76d118c656907ec1155f2cdd24de778470a2 ]
Fix MIB tx-rx MIB counters for survey-dump reporting.
Fixes: 163f4d22c118d ("mt76: mt7921: add MAC support") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 4 ++++ drivers/net/wireless/mediatek/mt76/mt7921/regs.h | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index a9ce10b988273..52d40385fab6c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -106,6 +106,10 @@ mt7921_mac_init_band(struct mt7921_dev *dev, u8 band) mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN); mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
+ /* enable MIB tx-rx time reporting */ + mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_TXDUR_EN); + mt76_set(dev, MT_MIB_SCR1(band), MT_MIB_RXDUR_EN); + mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536); /* disable rx rate report by default due to hw issues */ mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h index b6944c867a573..26fb118237626 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/regs.h @@ -96,6 +96,10 @@ #define MT_WF_MIB_BASE(_band) ((_band) ? 0xa4800 : 0x24800) #define MT_WF_MIB(_band, ofs) (MT_WF_MIB_BASE(_band) + (ofs))
+#define MT_MIB_SCR1(_band) MT_WF_MIB(_band, 0x004) +#define MT_MIB_TXDUR_EN BIT(8) +#define MT_MIB_RXDUR_EN BIT(9) + #define MT_MIB_SDR3(_band) MT_WF_MIB(_band, 0x698) #define MT_MIB_SDR3_FCS_ERR_MASK GENMASK(31, 16)
@@ -108,9 +112,9 @@ #define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090) #define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0)
-#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x098) +#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x054) #define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0) -#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x09c) +#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x058) #define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0)
#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0)
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit c33edef520213feccebc22c9474c685b9fb60611 ]
Fix the following sparse warning in mt76x02_mac_write_txwi and mt76x02_mac_tx_rate_val routines: drivers/net/wireless/mediatek/mt76/mt76x02_mac.c:237:19: warning: restricted __le16 degrades to intege warning: cast from restricted __le16 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c:383:28: warning: incorrect type in assignment (different base types) expected restricted __le16 [usertype] rate got unsigned long
Fixes: db9f11d3433f7 ("mt76: store wcid tx rate info in one u32 reduce locking") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c index c32e6dc687739..07b21b2085823 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -176,7 +176,7 @@ void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop) mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); }
-static __le16 +static u16 mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val) { @@ -222,14 +222,14 @@ mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev, rateval |= MT_RXWI_RATE_SGI;
*nss_val = nss; - return cpu_to_le16(rateval); + return rateval; }
void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate) { s8 max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate); - __le16 rateval; + u16 rateval; u32 tx_info; s8 nss;
@@ -342,7 +342,7 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi, struct ieee80211_key_conf *key = info->control.hw_key; u32 wcid_tx_info; u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); - u16 txwi_flags = 0; + u16 txwi_flags = 0, rateval; u8 nss; s8 txpwr_adj, max_txpwr_adj; u8 ccmp_pn[8], nstreams = dev->mphy.chainmask & 0xf; @@ -380,14 +380,15 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
if (wcid && (rate->idx < 0 || !rate->count)) { wcid_tx_info = wcid->tx_info; - txwi->rate = FIELD_GET(MT_WCID_TX_INFO_RATE, wcid_tx_info); + rateval = FIELD_GET(MT_WCID_TX_INFO_RATE, wcid_tx_info); max_txpwr_adj = FIELD_GET(MT_WCID_TX_INFO_TXPWR_ADJ, wcid_tx_info); nss = FIELD_GET(MT_WCID_TX_INFO_NSS, wcid_tx_info); } else { - txwi->rate = mt76x02_mac_tx_rate_val(dev, rate, &nss); + rateval = mt76x02_mac_tx_rate_val(dev, rate, &nss); max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate); } + txwi->rate = cpu_to_le16(rateval);
txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->txpower_conf, max_txpwr_adj);
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit cd3f387371e941e6806b455b4ba5b9f4ca4b77c6 ]
The acceptable event report should inlcude original CMD-ID. Otherwise, drop unexpected result from fw.
Fixes: 1c099ab44727c ("mt76: mt7921: add MCU support") Signed-off-by: Jimmy Hu Jimmy.Hu@mediatek.com Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 8329b705c2ca2..8ced55501d373 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -157,6 +157,7 @@ mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq) { struct mt7921_mcu_rxd *rxd; + int mcu_cmd = cmd & MCU_CMD_MASK; int ret = 0;
if (!skb) { @@ -194,6 +195,9 @@ mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, skb_pull(skb, sizeof(*rxd)); event = (struct mt7921_mcu_uni_event *)skb->data; ret = le32_to_cpu(event->status); + /* skip invalid event */ + if (mcu_cmd != event->cid) + ret = -EAGAIN; break; } case MCU_CMD_REG_READ: {
From: Shayne Chen shayne.chen@mediatek.com
[ Upstream commit 82a980f82a511ce74ab57eb9f692d02225eb32f4 ]
If total eeprom size is divisible by per-page size, the i in for loop will exceed max page index, which happens in our newer chipset.
Fixes: 26f18380e6ca ("mt76: mt7915: add support for flash mode") Signed-off-by: Bo Jiao bo.jiao@mediatek.com Signed-off-by: Shayne Chen shayne.chen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index c08c7398f9b85..e7e396f58c92c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -3391,20 +3391,20 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev) { -#define TOTAL_PAGE_MASK GENMASK(7, 5) +#define MAX_PAGE_IDX_MASK GENMASK(7, 5) #define PAGE_IDX_MASK GENMASK(4, 2) #define PER_PAGE_SIZE 0x400 struct mt7915_mcu_eeprom req = { .buffer_mode = EE_MODE_BUFFER }; - u8 total = MT7915_EEPROM_SIZE / PER_PAGE_SIZE; + u8 total = DIV_ROUND_UP(MT7915_EEPROM_SIZE, PER_PAGE_SIZE); u8 *eep = (u8 *)dev->mt76.eeprom.data; int eep_len; int i;
- for (i = 0; i <= total; i++, eep += eep_len) { + for (i = 0; i < total; i++, eep += eep_len) { struct sk_buff *skb; int ret;
- if (i == total) + if (i == total - 1 && !!(MT7915_EEPROM_SIZE % PER_PAGE_SIZE)) eep_len = MT7915_EEPROM_SIZE % PER_PAGE_SIZE; else eep_len = PER_PAGE_SIZE; @@ -3414,7 +3414,7 @@ static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev) if (!skb) return -ENOMEM;
- req.format = FIELD_PREP(TOTAL_PAGE_MASK, total) | + req.format = FIELD_PREP(MAX_PAGE_IDX_MASK, total - 1) | FIELD_PREP(PAGE_IDX_MASK, i) | EE_FORMAT_WHOLE; req.len = cpu_to_le16(eep_len);
From: Shayne Chen shayne.chen@mediatek.com
[ Upstream commit 47f1c08db7f3aaa2d13f8e56209375462ace7b8a ]
The bit fields of tx rate idx should be 6 bits, otherwise it might be incorrect in HT mode. For VHT/HE rates, only 4 bits are actually used by rate idx, the other 2 bits are used for other functions.
Fixes: c31d94af1843 ("mt76: mt7915: fix tx rate related fields in tx descriptor") Signed-off-by: Shayne Chen shayne.chen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h index eb1885f4bd8eb..fee7741b5d421 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h @@ -272,7 +272,8 @@ enum tx_mcu_port_q_idx { #define MT_TX_RATE_MODE GENMASK(9, 6) #define MT_TX_RATE_SU_EXT_TONE BIT(5) #define MT_TX_RATE_DCM BIT(4) -#define MT_TX_RATE_IDX GENMASK(3, 0) +/* VHT/HE only use bits 0-3 */ +#define MT_TX_RATE_IDX GENMASK(5, 0)
#define MT_TXP_MAX_BUF_NUM 6
From: Deren Wu deren.wu@mediatek.com
[ Upstream commit a23f80aa9c5e6ad4ec8df88037b7ffd4162b1ec4 ]
The dma would be broken after rmmod flow. There are two different cases causing this issue. 1. dma access without privilege. 2. hw access sequence borken by another context.
This patch handle both cases to avoid hw crash.
Fixes: 2b9ea5a8cf1bd ("mt76: mt7921: add mt7921_dma_cleanup in mt7921_unregister_device") Signed-off-by: Deren Wu deren.wu@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 52d40385fab6c..78a00028137bd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -251,8 +251,17 @@ int mt7921_register_device(struct mt7921_dev *dev)
void mt7921_unregister_device(struct mt7921_dev *dev) { + int i; + struct mt76_connac_pm *pm = &dev->pm; + mt76_unregister_device(&dev->mt76); + mt76_for_each_q_rx(&dev->mt76, i) + napi_disable(&dev->mt76.napi[i]); + cancel_delayed_work_sync(&pm->ps_work); + cancel_work_sync(&pm->wake_work); + mt7921_tx_token_put(dev); + mt7921_mcu_drv_pmctrl(dev); mt7921_dma_cleanup(dev); mt7921_mcu_exit(dev);
From: Leon Yen Leon.Yen@mediatek.com
[ Upstream commit 781f62960c635cfed55a8f8c0f909bdaf8268257 ]
Update the proper firmware programming sequence to fix GTK rekey offload failure on WPA mixed mode.
In the mt76_connac_mcu_key_iter, gtk_tlv->proto should be only set up on pairwise key and gtk_tlk->group_cipher should be only set up on the group key.
Otherwise, those parameters required by firmware would be set incorrectly to cause GTK rekey offload failure on WPA mixed mode and then disconnection follows.
Fixes: b47e21e75c80 ("mt76: mt7615: add gtk rekey offload support") Co-developed-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Leon Yen Leon.Yen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 5c3a81e5f559d..f57f047fce99c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -1929,19 +1929,22 @@ mt76_connac_mcu_key_iter(struct ieee80211_hw *hw, key->cipher != WLAN_CIPHER_SUITE_TKIP) return;
- if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { - gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1); + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) cipher = BIT(3); - } else { - gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2); + else cipher = BIT(4); - }
/* we are assuming here to have a single pairwise key */ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1); + else + gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2); + gtk_tlv->pairwise_cipher = cpu_to_le32(cipher); - gtk_tlv->group_cipher = cpu_to_le32(cipher); gtk_tlv->keyid = key->keyidx; + } else { + gtk_tlv->group_cipher = cpu_to_le32(cipher); } }
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit f6e1f59885dae5a2553f8bbd328be2cb1c80ccb2 ]
Introduce mt76_register_debugfs_fops routine in order to define per-driver regs file operations and make sure the device is up before reading or writing its registers
Fixes: 1d8efc741df8 ("mt76: mt7921: introduce Runtime PM support") Fixes: de5ff3c9d1a2 ("mt76: mt7615: introduce pm_power_save delayed work") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/debugfs.c | 10 ++++--- drivers/net/wireless/mediatek/mt76/mt76.h | 8 ++++- .../wireless/mediatek/mt76/mt7615/debugfs.c | 29 ++++++++++++++++++- .../wireless/mediatek/mt76/mt7921/debugfs.c | 28 +++++++++++++++++- 4 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index fa48cc3a7a8f7..ad97308c78534 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -116,8 +116,11 @@ static int mt76_read_rate_txpower(struct seq_file *s, void *data) return 0; }
-struct dentry *mt76_register_debugfs(struct mt76_dev *dev) +struct dentry * +mt76_register_debugfs_fops(struct mt76_dev *dev, + const struct file_operations *ops) { + const struct file_operations *fops = ops ? ops : &fops_regval; struct dentry *dir;
dir = debugfs_create_dir("mt76", dev->hw->wiphy->debugfsdir); @@ -126,8 +129,7 @@ struct dentry *mt76_register_debugfs(struct mt76_dev *dev)
debugfs_create_u8("led_pin", 0600, dir, &dev->led_pin); debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg); - debugfs_create_file_unsafe("regval", 0600, dir, dev, - &fops_regval); + debugfs_create_file_unsafe("regval", 0600, dir, dev, fops); debugfs_create_file_unsafe("napi_threaded", 0600, dir, dev, &fops_napi_threaded); debugfs_create_blob("eeprom", 0400, dir, &dev->eeprom); @@ -140,4 +142,4 @@ struct dentry *mt76_register_debugfs(struct mt76_dev *dev)
return dir; } -EXPORT_SYMBOL_GPL(mt76_register_debugfs); +EXPORT_SYMBOL_GPL(mt76_register_debugfs_fops); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 25c5ceef52577..4d01fd85283df 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -869,7 +869,13 @@ struct mt76_phy *mt76_alloc_phy(struct mt76_dev *dev, unsigned int size, int mt76_register_phy(struct mt76_phy *phy, bool vht, struct ieee80211_rate *rates, int n_rates);
-struct dentry *mt76_register_debugfs(struct mt76_dev *dev); +struct dentry *mt76_register_debugfs_fops(struct mt76_dev *dev, + const struct file_operations *ops); +static inline struct dentry *mt76_register_debugfs(struct mt76_dev *dev) +{ + return mt76_register_debugfs_fops(dev, NULL); +} + int mt76_queues_read(struct seq_file *s, void *data); void mt76_seq_puts_array(struct seq_file *file, const char *str, s8 *val, int len); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c index cb4659771fd97..bda22ca0bd714 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c @@ -2,6 +2,33 @@
#include "mt7615.h"
+static int +mt7615_reg_set(void *data, u64 val) +{ + struct mt7615_dev *dev = data; + + mt7615_mutex_acquire(dev); + mt76_wr(dev, dev->mt76.debugfs_reg, val); + mt7615_mutex_release(dev); + + return 0; +} + +static int +mt7615_reg_get(void *data, u64 *val) +{ + struct mt7615_dev *dev = data; + + mt7615_mutex_acquire(dev); + *val = mt76_rr(dev, dev->mt76.debugfs_reg); + mt7615_mutex_release(dev); + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7615_reg_get, mt7615_reg_set, + "0x%08llx\n"); + static int mt7615_radar_pattern_set(void *data, u64 val) { @@ -506,7 +533,7 @@ int mt7615_init_debugfs(struct mt7615_dev *dev) { struct dentry *dir;
- dir = mt76_register_debugfs(&dev->mt76); + dir = mt76_register_debugfs_fops(&dev->mt76, &fops_regval); if (!dir) return -ENOMEM;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c index 77468bdae460b..4c89c4ac8031a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c @@ -4,6 +4,32 @@ #include "mt7921.h" #include "eeprom.h"
+static int +mt7921_reg_set(void *data, u64 val) +{ + struct mt7921_dev *dev = data; + + mt7921_mutex_acquire(dev); + mt76_wr(dev, dev->mt76.debugfs_reg, val); + mt7921_mutex_release(dev); + + return 0; +} + +static int +mt7921_reg_get(void *data, u64 *val) +{ + struct mt7921_dev *dev = data; + + mt7921_mutex_acquire(dev); + *val = mt76_rr(dev, dev->mt76.debugfs_reg); + mt7921_mutex_release(dev); + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mt7921_reg_get, mt7921_reg_set, + "0x%08llx\n"); static int mt7921_fw_debug_set(void *data, u64 val) { @@ -373,7 +399,7 @@ int mt7921_init_debugfs(struct mt7921_dev *dev) { struct dentry *dir;
- dir = mt76_register_debugfs(&dev->mt76); + dir = mt76_register_debugfs_fops(&dev->mt76, &fops_regval); if (!dir) return -ENOMEM;
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 4fee32153ab62356aeea9d152d8f33a5fd3a0086 ]
Report HE MU/BF radiotap.
That fixed HE MU packets dropped by mac80211 because they are missing the ieee80211_radiotap_he_mu header.
Fixes: 163f4d22c118d ("mt76: mt7921: add MAC support") Co-developed-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Ryder Lee ryder.lee@mediatek.com Co-developed-by: Eric-SY Chang Eric-SY.Chang@mediatek.com Signed-off-by: Eric-SY Chang Eric-SY.Chang@mediatek.com Tested-by: Eric-SY Chang Eric-SY.Chang@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt7921/mac.c | 65 ++++++++++++++++--- .../net/wireless/mediatek/mt76/mt7921/mac.h | 8 +++ 2 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index f4714b0f6e5c4..8a16f3f4d5253 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -180,12 +180,56 @@ mt7921_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); }
+static void +mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb, + struct mt76_rx_status *status, + __le32 *rxv) +{ + static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | + HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | + HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN) | + HE_BITS(MU_FLAGS1_SIG_B_COMP_KNOWN), + .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN) | + HE_BITS(MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN), + }; + struct ieee80211_radiotap_he_mu *he_mu = NULL; + + he_mu = skb_push(skb, sizeof(mu_known)); + memcpy(he_mu, &mu_known, sizeof(mu_known)); + +#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) + + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); + if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); + + he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[2], MT_CRXV_HE_NUM_USER)); + + he_mu->ru_ch1[0] = FIELD_GET(MT_CRXV_HE_RU0, cpu_to_le32(rxv[3])); + + if (status->bw >= RATE_INFO_BW_40) { + he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); + he_mu->ru_ch2[0] = + FIELD_GET(MT_CRXV_HE_RU1, cpu_to_le32(rxv[3])); + } + + if (status->bw >= RATE_INFO_BW_80) { + he_mu->ru_ch1[1] = + FIELD_GET(MT_CRXV_HE_RU2, cpu_to_le32(rxv[3])); + he_mu->ru_ch2[1] = + FIELD_GET(MT_CRXV_HE_RU3, cpu_to_le32(rxv[3])); + } +} + static void mt7921_mac_decode_he_radiotap(struct sk_buff *skb, struct mt76_rx_status *status, __le32 *rxv, u32 phy) { - /* TODO: struct ieee80211_radiotap_he_mu */ static const struct ieee80211_radiotap_he known = { .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | HE_BITS(DATA1_DATA_DCM_KNOWN) | @@ -193,6 +237,7 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, HE_BITS(DATA1_CODING_KNOWN) | HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | HE_BITS(DATA1_DOPPLER_KNOWN) | + HE_BITS(DATA1_SPTL_REUSE_KNOWN) | HE_BITS(DATA1_BSS_COLOR_KNOWN), .data2 = HE_BITS(DATA2_GI_KNOWN) | HE_BITS(DATA2_TXBF_KNOWN) | @@ -207,9 +252,12 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb,
he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) | HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]); + he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]); he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) | le16_encode_bits(ltf_size, IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); + if (cpu_to_le32(rxv[0]) & MT_PRXV_TXBF) + he->data5 |= HE_BITS(DATA5_TXBF); he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) | HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]);
@@ -217,8 +265,7 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, case MT_PHY_TYPE_HE_SU: he->data1 |= HE_BITS(DATA1_FORMAT_SU) | HE_BITS(DATA1_UL_DL_KNOWN) | - HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE_KNOWN); + HE_BITS(DATA1_BEAM_CHANGE_KNOWN);
he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) | HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); @@ -232,17 +279,15 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb, break; case MT_PHY_TYPE_HE_MU: he->data1 |= HE_BITS(DATA1_FORMAT_MU) | - HE_BITS(DATA1_UL_DL_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE_KNOWN); + HE_BITS(DATA1_UL_DL_KNOWN);
he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); - he->data4 |= HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]); + he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]);
mt7921_mac_decode_he_radiotap_ru(status, he, rxv); break; case MT_PHY_TYPE_HE_TB: he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | - HE_BITS(DATA1_SPTL_REUSE_KNOWN) | HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | HE_BITS(DATA1_SPTL_REUSE4_KNOWN); @@ -606,9 +651,13 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
mt7921_mac_assoc_rssi(dev, skb);
- if (rxv && status->flag & RX_FLAG_RADIOTAP_HE) + if (rxv && status->flag & RX_FLAG_RADIOTAP_HE) { mt7921_mac_decode_he_radiotap(skb, status, rxv, mode);
+ if (status->flag & RX_FLAG_RADIOTAP_HE_MU) + mt7921_mac_decode_he_mu_radiotap(skb, status, rxv); + } + if (!status->wcid || !ieee80211_is_data_qos(fc)) return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h index 3af67fac213df..f0194c8780372 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h @@ -116,6 +116,7 @@ enum rx_pkt_type { #define MT_PRXV_TX_DCM BIT(4) #define MT_PRXV_TX_ER_SU_106T BIT(5) #define MT_PRXV_NSTS GENMASK(9, 7) +#define MT_PRXV_TXBF BIT(10) #define MT_PRXV_HT_AD_CODE BIT(11) #define MT_PRXV_FRAME_MODE GENMASK(14, 12) #define MT_PRXV_SGI GENMASK(16, 15) @@ -138,8 +139,15 @@ enum rx_pkt_type { #define MT_CRXV_HE_LTF_SIZE GENMASK(18, 17) #define MT_CRXV_HE_LDPC_EXT_SYM BIT(20) #define MT_CRXV_HE_PE_DISAMBIG BIT(23) +#define MT_CRXV_HE_NUM_USER GENMASK(30, 24) #define MT_CRXV_HE_UPLINK BIT(31)
+#define MT_CRXV_HE_RU0 GENMASK(7, 0) +#define MT_CRXV_HE_RU1 GENMASK(15, 8) +#define MT_CRXV_HE_RU2 GENMASK(23, 16) +#define MT_CRXV_HE_RU3 GENMASK(31, 24) +#define MT_CRXV_HE_MU_AID GENMASK(30, 20) + #define MT_CRXV_HE_SR_MASK GENMASK(11, 8) #define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) #define MT_CRXV_HE_SR2_MASK GENMASK(20, 17)
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 99b8e195994d9d77de3bfe0cb403c44a57c2cf79 ]
According to the firmware usage, OFDM rates should fill out bit 6 - 13 while CCK rates should fill out bit 0 - 3 in legacy field of RA info to make the rate adaption runs propertly. Otherwise, a unicast frame might be picking up the unsupported rate to send out.
Fixes: 1c099ab44727 ("mt76: mt7921: add MCU support") Reported-by: Joshua Emele jemele@chromium.org Co-developed-by: YN Chen YN.Chen@mediatek.com Signed-off-by: YN Chen YN.Chen@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 11 ++++++++++- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index f57f047fce99c..98d233e24afcc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -719,6 +719,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, struct sta_rec_state *state; struct sta_rec_phy *phy; struct tlv *tlv; + u16 supp_rates;
/* starec ht */ if (sta->ht_cap.ht_supported) { @@ -767,7 +768,15 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info)); ra_info = (struct sta_rec_ra_info *)tlv; - ra_info->legacy = cpu_to_le16((u16)sta->supp_rates[band]); + + supp_rates = sta->supp_rates[band]; + if (band == NL80211_BAND_2GHZ) + supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) | + FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf); + else + supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates); + + ra_info->legacy = cpu_to_le16(supp_rates);
if (sta->ht_cap.ht_supported) memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask, diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 4bcd728ff97c5..77d4435e4581e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -124,6 +124,8 @@ struct sta_rec_state { u8 rsv[1]; } __packed;
+#define RA_LEGACY_OFDM GENMASK(13, 6) +#define RA_LEGACY_CCK GENMASK(3, 0) #define HT_MCS_MASK_NUM 10 struct sta_rec_ra_info { __le16 tag;
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 8e695328a1006b7bab2d972e7d0111fa6e6faf51 ]
Fix the kernel warning from cfg80211_calculate_bitrate due to the legacy rate is not parsed well in the current driver.
Also, zeros struct rate_info before we fill it out to avoid the old value is kept such as rate->legacy.
[ 790.921560] WARNING: CPU: 7 PID: 970 at net/wireless/util.c:1298 cfg80211_calculate_bitrate+0x354/0x35c [cfg80211] [ 790.987738] Hardware name: MediaTek Asurada rev1 board (DT) [ 790.993298] pstate: a0400009 (NzCv daif +PAN -UAO) [ 790.998104] pc : cfg80211_calculate_bitrate+0x354/0x35c [cfg80211] [ 791.004295] lr : cfg80211_calculate_bitrate+0x180/0x35c [cfg80211] [ 791.010462] sp : ffffffc0129c3880 [ 791.013765] x29: ffffffc0129c3880 x28: ffffffd38305bea8 [ 791.019065] x27: ffffffc0129c3970 x26: 0000000000000013 [ 791.024364] x25: 00000000000003ca x24: 000000000000002f [ 791.029664] x23: 00000000000000d0 x22: ffffff8d108bc000 [ 791.034964] x21: ffffff8d108bc0d0 x20: ffffffc0129c39a8 [ 791.040264] x19: ffffffc0129c39a8 x18: 00000000ffff0a10 [ 791.045563] x17: 0000000000000050 x16: 00000000000000ec [ 791.050910] x15: ffffffd3f9ebed9c x14: 0000000000000006 [ 791.056211] x13: 00000000000b2eea x12: 0000000000000000 [ 791.061511] x11: 00000000ffffffff x10: 0000000000000000 [ 791.066811] x9 : 0000000000000000 x8 : 0000000000000000 [ 791.072110] x7 : 0000000000000000 x6 : ffffffd3fafa5a7b [ 791.077409] x5 : 0000000000000000 x4 : 0000000000000000 [ 791.082708] x3 : 0000000000000000 x2 : 0000000000000000 [ 791.088008] x1 : ffffff8d3f79c918 x0 : 0000000000000000 [ 791.093308] Call trace: [ 791.095770] cfg80211_calculate_bitrate+0x354/0x35c [cfg80211] [ 791.101615] nl80211_put_sta_rate+0x6c/0x2c0 [cfg80211] [ 791.106853] nl80211_send_station+0x980/0xaa4 [cfg80211] [ 791.112178] nl80211_get_station+0xb4/0x134 [cfg80211] [ 791.117308] genl_rcv_msg+0x3a0/0x440 [ 791.120960] netlink_rcv_skb+0xcc/0x118 [ 791.124785] genl_rcv+0x34/0x48 [ 791.127916] netlink_unicast+0x144/0x1dc
Fixes: 1c099ab44727 ("mt76: mt7921: add MCU support") Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 8ced55501d373..3cb53c642d242 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -320,11 +320,13 @@ mt7921_mcu_tx_rate_parse(struct mt76_phy *mphy, struct rate_info *rate, u16 r) { struct ieee80211_supported_band *sband; - u16 flags = 0; + u16 flags = 0, rate_idx; u8 txmode = FIELD_GET(MT_WTBL_RATE_TX_MODE, r); u8 gi = 0; u8 bw = 0; + bool cck = false;
+ memset(rate, 0, sizeof(*rate)); rate->mcs = FIELD_GET(MT_WTBL_RATE_MCS, r); rate->nss = FIELD_GET(MT_WTBL_RATE_NSS, r) + 1;
@@ -349,13 +351,18 @@ mt7921_mcu_tx_rate_parse(struct mt76_phy *mphy,
switch (txmode) { case MT_PHY_TYPE_CCK: + cck = true; + fallthrough; case MT_PHY_TYPE_OFDM: if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) sband = &mphy->sband_5g.sband; else sband = &mphy->sband_2g.sband;
- rate->legacy = sband->bitrates[rate->mcs].bitrate; + rate_idx = FIELD_GET(MT_TX_RATE_IDX, r); + rate_idx = mt76_get_rate(mphy->dev, sband, rate_idx, + cck); + rate->legacy = sband->bitrates[rate_idx].bitrate; break; case MT_PHY_TYPE_HT: case MT_PHY_TYPE_HT_GF:
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit 569008744178b672ea3ad9047fa3098f1b73ca55 ]
Add missing device wakeup in debugfs code if we are accessing chip registers.
Fixes: 1d8efc741df8 ("mt76: mt7921: introduce Runtime PM support") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c index 4c89c4ac8031a..30f3b3085c786 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c @@ -95,6 +95,8 @@ mt7921_tx_stats_show(struct seq_file *file, void *data) struct mt7921_dev *dev = file->private; int stat[8], i, n;
+ mt7921_mutex_acquire(dev); + mt7921_ampdu_stat_read_phy(&dev->phy, file);
/* Tx amsdu info */ @@ -104,6 +106,8 @@ mt7921_tx_stats_show(struct seq_file *file, void *data) n += stat[i]; }
+ mt7921_mutex_release(dev); + for (i = 0; i < ARRAY_SIZE(stat); i++) { seq_printf(file, "AMSDU pack count of %d MSDU in TXD: 0x%x ", i + 1, stat[i]); @@ -124,6 +128,8 @@ mt7921_queues_acq(struct seq_file *s, void *data) struct mt7921_dev *dev = dev_get_drvdata(s->private); int i;
+ mt7921_mutex_acquire(dev); + for (i = 0; i < 16; i++) { int j, acs = i / 4, index = i % 4; u32 ctrl, val, qlen = 0; @@ -143,6 +149,8 @@ mt7921_queues_acq(struct seq_file *s, void *data) seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen); }
+ mt7921_mutex_release(dev); + return 0; }
From: Ben Greear greearb@candelatech.com
[ Upstream commit 0ae3ff5684514d72357240f1033a7494c51f93ed ]
Without this change, garbage is seen in the hwmon name and sensors output for mt7915 is garbled. It appears that the hwmon logic does not make a copy of the incoming string, but instead just copies a char* and expects it to never go away.
Fixes: 33fe9c639c13 ("mt76: mt7915: add thermal sensor device support") Signed-off-by: Ben Greear greearb@candelatech.com Signed-off-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/init.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index 4798d6344305d..b171027e0cfa8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -130,9 +130,12 @@ static int mt7915_thermal_init(struct mt7915_phy *phy) struct wiphy *wiphy = phy->mt76->hw->wiphy; struct thermal_cooling_device *cdev; struct device *hwmon; + const char *name;
- cdev = thermal_cooling_device_register(wiphy_name(wiphy), phy, - &mt7915_thermal_ops); + name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7915_%s", + wiphy_name(wiphy)); + + cdev = thermal_cooling_device_register(name, phy, &mt7915_thermal_ops); if (!IS_ERR(cdev)) { if (sysfs_create_link(&wiphy->dev.kobj, &cdev->device.kobj, "cooling_device") < 0) @@ -144,8 +147,7 @@ static int mt7915_thermal_init(struct mt7915_phy *phy) if (!IS_REACHABLE(CONFIG_HWMON)) return 0;
- hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, - wiphy_name(wiphy), phy, + hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, mt7915_hwmon_groups); if (IS_ERR(hwmon)) return PTR_ERR(hwmon);
From: Ryder Lee ryder.lee@mediatek.com
[ Upstream commit 0bb4e9187ea4a59dc6658a62978deda0c0dc4b28 ]
Without this change, garbage is seen in the hwmon name and sensors output for mt7615 is garbled.
Fixes: 109e505ad944 ("mt76: mt7615: add thermal sensor device support") Signed-off-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7615/init.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c index 2f1ac644e018e..47f23ac905a3c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c @@ -49,12 +49,14 @@ int mt7615_thermal_init(struct mt7615_dev *dev) { struct wiphy *wiphy = mt76_hw(dev)->wiphy; struct device *hwmon; + const char *name;
if (!IS_REACHABLE(CONFIG_HWMON)) return 0;
- hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, - wiphy_name(wiphy), dev, + name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7615_%s", + wiphy_name(wiphy)); + hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, dev, mt7615_hwmon_groups); if (IS_ERR(hwmon)) return PTR_ERR(hwmon);
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit e500c9470e26be66eb2bc6de773ae9091149118a ]
Fix possible infinite loop in mt7915_load_patch if mt7915_mcu_patch_sem_ctrl always returns an error.
Fixes: e57b7901469fc ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index e7e396f58c92c..85c9c08ee2a82 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2790,7 +2790,7 @@ out: default: ret = -EAGAIN; dev_err(dev->mt76.dev, "Failed to release patch semaphore\n"); - goto out; + break; } release_firmware(fw);
From: Sean Wang sean.wang@mediatek.com
[ Upstream commit 02d1c7d494d8052288bc175e4ff54b56d08a3c5f ]
We should pass the error code to the caller immediately to avoid the possible infinite retry to release the semaphore.
Fixes: 1c099ab44727 ("mt76: mt7921: add MCU support") Co-developed-by: YN Chen YN.Chen@mediatek.com Signed-off-by: YN Chen YN.Chen@mediatek.com Signed-off-by: Sean Wang sean.wang@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 3cb53c642d242..506a1909ce6d5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -827,7 +827,7 @@ out: default: ret = -EAGAIN; dev_err(dev->mt76.dev, "Failed to release patch semaphore\n"); - goto out; + break; } release_firmware(fw);
From: Ryder Lee ryder.lee@mediatek.com
[ Upstream commit a6fdbdd1ac2996a58a84672ef37efb5cbb98fadf ]
[ 103.451600] CPU 3 Unable to handle kernel paging request at virtual address 00000003, epc == 8576591c, ra == 857659f0 [ 103.462226] Oops[#1]: [ 103.464499] CPU: 3 PID: 9247 Comm: ifconfig Tainted: G W 5.4.143 #0 [ 103.472031] $ 0 : 00000000 00000001 83be3854 00000000 [ 103.477239] $ 4 : 8102a374 8102a374 8102f0b0 00000200 [ 103.482444] $ 8 : 0000002d 000001e4 64373765 5d206337 [ 103.487647] $12 : 00000000 00000005 00000000 0006d1df [ 103.492853] $16 : 83be3848 853838a8 8743d600 00010000 [ 103.498059] $20 : 00000000 00000000 8553dec0 0000007f [ 103.503266] $24 : 00000003 80382084 [ 103.508472] $28 : 831d4000 831d5bc0 00000001 857659f0 [ 103.513678] Hi : 00000122 [ 103.516543] Lo : d1768000 [ 103.519452] epc : 8576591c mt7615_mcu_add_bss+0xd0/0x3c0 [mt7615_common] [ 103.526306] ra : 857659f0 mt7615_mcu_add_bss+0x1a4/0x3c0 [mt7615_common] [ 103.533232] Status: 11007c03 KERNEL EXL IE [ 103.537402] Cause : 40800008 (ExcCode 02) [ 103.541389] BadVA : 00000003 [ 103.544253] PrId : 0001992f (MIPS 1004Kc) [ 103.797086] Call Trace: [ 103.799562] [<8576591c>] mt7615_mcu_add_bss+0xd0/0x3c0 [mt7615_common] [ 103.806082] [<85760a14>] mt7615_remove_interface+0x74/0x1e0 [mt7615_common] [ 103.813280] [<85603fcc>] drv_remove_interface+0x2c/0xa0 [mac80211] [ 103.819612] [<8561a8e4>] ieee80211_del_virtual_monitor.part.22+0x74/0xe8 [mac80211] [ 103.827410] [<8561b7f0>] ieee80211_do_stop+0x4a4/0x8a0 [mac80211] [ 103.833671] [<8561bc00>] ieee80211_stop+0x14/0x24 [mac80211] [ 103.839405] [<8045a328>] __dev_close_many+0x9c/0x10c [ 103.844364] [<80463de4>] __dev_change_flags+0x16c/0x1e4 [ 103.849569] [<80463e84>] dev_change_flags+0x28/0x70 [ 103.854440] [<80521e54>] devinet_ioctl+0x280/0x774 [ 103.859222] [<80526248>] inet_ioctl+0xa4/0x1c8 [ 103.863674] [<80436830>] sock_ioctl+0x2d8/0x4bc [ 103.868201] [<801adbb4>] do_vfs_ioctl+0xb8/0x7c0 [ 103.872804] [<801ae30c>] ksys_ioctl+0x50/0xb4 [ 103.877156] [<80014598>] syscall_common+0x34/0x58
Fixes: 04b8e65922f63 ("mt76: add mac80211 driver for MT7615 PCIe-based chipsets") Signed-off-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index f8a09692d3e4c..4fed3afad67cc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -808,7 +808,8 @@ mt7615_mcu_ctrl_pm_state(struct mt7615_dev *dev, int band, int state)
static int mt7615_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, bool enable) + struct ieee80211_sta *sta, struct mt7615_phy *phy, + bool enable) { struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA; @@ -821,6 +822,7 @@ mt7615_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, switch (vif->type) { case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_MONITOR: break; case NL80211_IFTYPE_STATION: /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ @@ -840,14 +842,19 @@ mt7615_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, }
bss = (struct bss_info_basic *)tlv; - memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); - bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); bss->network_type = cpu_to_le32(type); - bss->dtim_period = vif->bss_conf.dtim_period; bss->bmc_tx_wlan_idx = wlan_idx; bss->wmm_idx = mvif->mt76.wmm_idx; bss->active = enable;
+ if (vif->type != NL80211_IFTYPE_MONITOR) { + memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); + bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); + bss->dtim_period = vif->bss_conf.dtim_period; + } else { + memcpy(bss->bssid, phy->mt76->macaddr, ETH_ALEN); + } + return 0; }
@@ -863,6 +870,7 @@ mt7615_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_OMAC, sizeof(*omac));
switch (vif->type) { + case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_AP: if (vif->p2p) @@ -929,7 +937,7 @@ mt7615_mcu_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif, if (enable) mt7615_mcu_bss_omac_tlv(skb, vif);
- mt7615_mcu_bss_basic_tlv(skb, vif, sta, enable); + mt7615_mcu_bss_basic_tlv(skb, vif, sta, phy, enable);
if (enable && mvif->mt76.omac_idx >= EXT_BSSID_START && mvif->mt76.omac_idx < REPEATER_BSSID_START)
From: Lorenzo Bianconi lorenzo@kernel.org
[ Upstream commit b5f2ba8a4c794e8349c0e30036352b9f685164c4 ]
Fix the following NULL pointer dereference in mt76_connac_get_phy_mode_v2 routine triggered on mt7663s device when sta is NULL
[ 5.490700] mt7663s mmc0:0001:1: N9 Firmware Version: 3.1.1, Build Time: 20200604161656 [ 5.490815] mt7663s mmc0:0001:1: Region number: 0x4 [ 5.490868] mt7663s mmc0:0001:1: Parsing tailer Region: 0 [ 5.496251] mt7663s mmc0:0001:1: Region 0, override_addr = 0x00118000 [ 5.496419] mt7663s mmc0:0001:1: Parsing tailer Region: 1 [ 5.624027] mt7663s mmc0:0001:1: Parsing tailer Region: 2 [ 5.656999] mt7663s mmc0:0001:1: Parsing tailer Region: 3 [ 5.671876] mt7663s mmc0:0001:1: override_addr = 0x00118000, option = 3 [ 9.358658] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 9.358775] #PF: supervisor read access in kernel mode [ 9.358831] #PF: error_code(0x0000) - not-present page [ 9.358886] PGD 0 P4D 0 [ 9.358917] Oops: 0000 [#1] SMP [ 9.358960] CPU: 0 PID: 235 Comm: NetworkManager Not tainted 5.15.0-rc4-kvm-02151-g39e333d657f4-dirty #769 [ 9.359057] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-4.fc34 04/01/2014 [ 9.359150] RIP: 0010:mt76_connac_get_phy_mode_v2+0xc9/0x11c [ 9.359473] RAX: 0000000000000013 RBX: 0000000000000000 RCX: 0000000000000027 [ 9.359546] RDX: ffff8881f9c17358 RSI: 0000000000000001 RDI: ffff8881f9c17350 [ 9.359624] RBP: ffff88810bac1ed4 R08: ffffffff822a4a48 R09: 0000000000000003 [ 9.359697] R10: ffffffff82234a60 R11: ffffffff82234a60 R12: ffff88810bac1eec [ 9.359779] R13: 0000000000000000 R14: ffff88810bad1648 R15: ffff88810bac1eb8 [ 9.359859] FS: 00007f5f1e45bbc0(0000) GS:ffff8881f9c00000(0000) knlGS:0000000000000000 [ 9.359939] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 9.360003] CR2: 0000000000000000 CR3: 0000000105d5d000 CR4: 00000000000006b0 [ 9.360083] Call Trace: [ 9.360116] mt76_connac_mcu_uni_add_bss.cold+0x21/0x250 [ 9.360175] ? schedule_preempt_disabled+0xa/0x10 [ 9.360232] ? __mutex_lock.constprop.0+0x2ab/0x460 [ 9.360286] mt7615_remove_interface+0x63/0x1d0 [ 9.360342] drv_remove_interface+0x32/0xe0 [ 9.360385] ieee80211_do_stop+0x5da/0x800 [ 9.360428] ? dev_reset_queue+0x30/0x90 [ 9.360472] ieee80211_stop+0x3b/0xb0 [ 9.360516] __dev_close_many+0x7a/0xd0 [ 9.360559] __dev_change_flags+0xd6/0x1f0 [ 9.360604] dev_change_flags+0x21/0x60 [ 9.360648] do_setlink+0x259/0xfb0 [ 9.360686] ? __nla_validate_parse+0x51/0xb80 [ 9.360742] __rtnl_newlink+0x5b3/0x960 [ 9.360785] ? inet6_fill_ifla6_attrs+0x41d/0x470 [ 9.360841] ? __kmalloc_track_caller+0x57/0x3c0 [ 9.360905] ? netlink_trim+0x8a/0xb0 [ 9.360949] ? skb_queue_tail+0x1b/0x50
Fixes: 67aa27431c7f8 ("mt76: mt7921: rely on mt76_connac_mcu common library") Signed-off-by: Lorenzo Bianconi lorenzo@kernel.org Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 98d233e24afcc..d25b50e769328 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -689,7 +689,7 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif, if (ht_cap->ht_supported) mode |= PHY_TYPE_BIT_HT;
- if (he_cap->has_he) + if (he_cap && he_cap->has_he) mode |= PHY_TYPE_BIT_HE; } else if (band == NL80211_BAND_5GHZ) { mode |= PHY_TYPE_BIT_OFDM; @@ -700,7 +700,7 @@ mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif, if (vht_cap->vht_supported) mode |= PHY_TYPE_BIT_VHT;
- if (he_cap->has_he) + if (he_cap && he_cap->has_he) mode |= PHY_TYPE_BIT_HE; }
From: Shayne Chen shayne.chen@mediatek.com
[ Upstream commit afa0370f3a3a64af6d368da0bedd72ab2a026cd0 ]
Fix tag len error for sta_rec_wtbl, which causes fw parsing error for the tags placed behind it.
Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") Signed-off-by: Shayne Chen shayne.chen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 85c9c08ee2a82..6dfe3716a63a5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -757,7 +757,7 @@ mt7915_mcu_alloc_wtbl_req(struct mt7915_dev *dev, struct mt7915_sta *msta, }
if (sta_hdr) - sta_hdr->len = cpu_to_le16(sizeof(hdr)); + le16_add_cpu(&sta_hdr->len, sizeof(hdr));
return skb_put_data(nskb, &hdr, sizeof(hdr)); }
From: Shayne Chen shayne.chen@mediatek.com
[ Upstream commit 161cc13912d3c3e8857001988dfba39be842454a ]
For broadcast/multicast wcid, the muar_idx should be 0xe.
Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") Signed-off-by: Shayne Chen shayne.chen@mediatek.com Signed-off-by: Felix Fietkau nbd@nbd.name Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 6dfe3716a63a5..ba36d3caec8e1 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -721,7 +721,7 @@ mt7915_mcu_alloc_sta_req(struct mt7915_dev *dev, struct mt7915_vif *mvif, .bss_idx = mvif->idx, .wlan_idx_lo = msta ? to_wcid_lo(msta->wcid.idx) : 0, .wlan_idx_hi = msta ? to_wcid_hi(msta->wcid.idx) : 0, - .muar_idx = msta ? mvif->omac_idx : 0, + .muar_idx = msta && msta->wcid.sta ? mvif->omac_idx : 0xe, .is_tlv_append = 1, }; struct sk_buff *skb;
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit 515e7184bdf0a3ebf1757cc77fb046b4fe282189 ]
When fail to init coex module, free 'common' and 'adapter' directly, but common->tx_thread which will access 'common' and 'adapter' is running at the same time. That will trigger the UAF bug.
================================================================== BUG: KASAN: use-after-free in rsi_tx_scheduler_thread+0x50f/0x520 [rsi_91x] Read of size 8 at addr ffff8880076dc000 by task Tx-Thread/124777 CPU: 0 PID: 124777 Comm: Tx-Thread Not tainted 5.15.0-rc5+ #19 Call Trace: dump_stack_lvl+0xe2/0x152 print_address_description.constprop.0+0x21/0x140 ? rsi_tx_scheduler_thread+0x50f/0x520 kasan_report.cold+0x7f/0x11b ? rsi_tx_scheduler_thread+0x50f/0x520 rsi_tx_scheduler_thread+0x50f/0x520 ...
Freed by task 111873: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 __kasan_slab_free+0x109/0x140 kfree+0x117/0x4c0 rsi_91x_init+0x741/0x8a0 [rsi_91x] rsi_probe+0x9f/0x1750 [rsi_usb]
Stop thread before free 'common' and 'adapter' to fix it.
Fixes: 2108df3c4b18 ("rsi: add coex support") Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211015040335.1021546-1-william.xuanziyang@huawei... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/rsi/rsi_91x_main.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c index 143224a3802ba..f1bf71e6c6081 100644 --- a/drivers/net/wireless/rsi/rsi_91x_main.c +++ b/drivers/net/wireless/rsi/rsi_91x_main.c @@ -369,6 +369,7 @@ struct rsi_hw *rsi_91x_init(u16 oper_mode) if (common->coex_mode > 1) { if (rsi_coex_attach(common)) { rsi_dbg(ERR_ZONE, "Failed to init coex module\n"); + rsi_kill_thread(&common->tx_thread); goto err; } }
From: Jonas Dreßler verdre@v0yd.nl
[ Upstream commit cc8a8bc37466f79b24d972555237f3d591150602 ]
While looking at on-air packets using Wireshark, I noticed we're never setting the initiator bit when sending DELBA requests to the AP: While we set the bit on our del_ba_param_set bitmask, we forget to actually copy that bitmask over to the command struct, which means we never actually set the initiator bit.
Fix that and copy the bitmask over to the host_cmd_ds_11n_delba command struct.
Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver") Signed-off-by: Jonas Dreßler verdre@v0yd.nl Acked-by: Pali Rohár pali@kernel.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211016153244.24353-5-verdre@v0yd.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/mwifiex/11n.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c index 6696bce561786..cf08a4af84d6d 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n.c +++ b/drivers/net/wireless/marvell/mwifiex/11n.c @@ -657,14 +657,15 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, uint16_t del_ba_param_set;
memset(&delba, 0, sizeof(delba)); - delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS);
- del_ba_param_set = le16_to_cpu(delba.del_ba_param_set); + del_ba_param_set = tid << DELBA_TID_POS; + if (initiator) del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK; else del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK;
+ delba.del_ba_param_set = cpu_to_le16(del_ba_param_set); memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
/* We don't wait for the response of this command */
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 2f629a7772e2a7bdaff25178917a40073f79702c ]
If resume fails for some reason, we need to set the PM state back to normal so we're able to send commands during firmware reset, rather than failing all of them because we're in D3.
Signed-off-by: Johannes Berg johannes.berg@intel.com Fixes: 708a39aaca22 ("iwlwifi: mvm: don't send commands during suspend\resume transition") Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/iwlwifi.20211016114029.7ceb9eaca9f6.If0cbef38c6d07... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 9f706fffb5922..d3013a51a5096 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -2336,7 +2336,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, false, 0); ret = 1; - mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; goto err; }
@@ -2385,6 +2384,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) } }
+ /* after the successful handshake, we're out of D3 */ mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
/* @@ -2455,6 +2455,9 @@ out: */ set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
+ /* regardless of what happened, we're now out of D3 */ + mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED; + return 1; }
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 0f892441d8c353144e3669b7991fa5fe0bd353e9 ]
We shouldn't kmemdup() more data than we have, that might cause the code to crash. Fix that by updating the length before the kmemdup.
Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/iwlwifi.20211016114029.ab0e64c3fba9.Ic6a3295fc3847... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index dde22bdc87039..9b0eee53488ab 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -284,16 +284,15 @@ int iwl_pnvm_load(struct iwl_trans *trans, /* First attempt to get the PNVM from BIOS */ package = iwl_uefi_get_pnvm(trans, &len); if (!IS_ERR_OR_NULL(package)) { + /* we need only the data */ + len -= sizeof(*package); data = kmemdup(package->data, len, GFP_KERNEL);
/* free package regardless of whether kmemdup succeeded */ kfree(package);
- if (data) { - /* we need only the data size */ - len -= sizeof(*package); + if (data) goto parse; - } }
/* If it's not available, try from the filesystem */
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit e864a77f51d0d8113b49cf7d030bc9dc911c8176 ]
If the data we get from EFI is not even long enough for the package struct we expect then ignore it entirely.
Signed-off-by: Johannes Berg johannes.berg@intel.com Fixes: a1a6a4cf49ec ("iwlwifi: pnvm: implement reading PNVM from UEFI") Signed-off-by: Luca Coelho luciano.coelho@intel.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/iwlwifi.20211016114029.33feba783518.I54a5cf33975d0... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/fw/pnvm.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index 9b0eee53488ab..069fcbc46d2ba 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -284,9 +284,13 @@ int iwl_pnvm_load(struct iwl_trans *trans, /* First attempt to get the PNVM from BIOS */ package = iwl_uefi_get_pnvm(trans, &len); if (!IS_ERR_OR_NULL(package)) { - /* we need only the data */ - len -= sizeof(*package); - data = kmemdup(package->data, len, GFP_KERNEL); + if (len >= sizeof(*package)) { + /* we need only the data */ + len -= sizeof(*package); + data = kmemdup(package->data, len, GFP_KERNEL); + } else { + data = NULL; + }
/* free package regardless of whether kmemdup succeeded */ kfree(package);
From: Tim Gardner tim.gardner@canonical.com
[ Upstream commit cd4bc63de774eee95e9bac26a565cd80e0fca421 ]
Coverity complains of a possible dereference of a null return value.
5. returned_null: kzalloc returns NULL. [show details] 6. var_assigned: Assigning: si_data = NULL return value from kzalloc. 488 si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); 489 cbd.length = cpu_to_le16(data_size); 490 491 dma = dma_map_single(&priv->si->pdev->dev, si_data, 492 data_size, DMA_FROM_DEVICE);
While this kzalloc() is unlikely to fail, I did notice that the function returned without unmapping si_data.
Fix this by refactoring the error paths and checking for kzalloc() failure.
Fixes: 888ae5a3952ba ("net: enetc: add tc flower psfp offload driver") Cc: Claudiu Manoil claudiu.manoil@nxp.com Cc: "David S. Miller" davem@davemloft.net Cc: Jakub Kicinski kuba@kernel.org Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org (open list) Signed-off-by: Tim Gardner tim.gardner@canonical.com Acked-by: Claudiu Manoil claudiu.manoil@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/freescale/enetc/enetc_qos.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c index 4577226d3c6ad..0536d2c76fbc4 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c @@ -486,14 +486,16 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv,
data_size = sizeof(struct streamid_data); si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); + if (!si_data) + return -ENOMEM; cbd.length = cpu_to_le16(data_size);
dma = dma_map_single(&priv->si->pdev->dev, si_data, data_size, DMA_FROM_DEVICE); if (dma_mapping_error(&priv->si->pdev->dev, dma)) { netdev_err(priv->si->ndev, "DMA mapping failed!\n"); - kfree(si_data); - return -ENOMEM; + err = -ENOMEM; + goto out; }
cbd.addr[0] = cpu_to_le32(lower_32_bits(dma)); @@ -512,12 +514,10 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv,
err = enetc_send_cmd(priv->si, &cbd); if (err) - return -EINVAL; + goto out;
- if (!enable) { - kfree(si_data); - return 0; - } + if (!enable) + goto out;
/* Enable the entry overwrite again incase space flushed by hardware */ memset(&cbd, 0, sizeof(cbd)); @@ -560,6 +560,10 @@ static int enetc_streamid_hw_set(struct enetc_ndev_priv *priv, }
err = enetc_send_cmd(priv->si, &cbd); +out: + if (!dma_mapping_error(&priv->si->pdev->dev, dma)) + dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_FROM_DEVICE); + kfree(si_data);
return err;
From: Stefan Agner stefan@agner.ch
[ Upstream commit 2641b62d2fab52648e34cdc6994b2eacde2d27c1 ]
Some Micrel KSZ8041NL PHY chips exhibit continuous RX errors after using the power down mode bit (0.11). If the PHY is taken out of power down mode in a certain temperature range, the PHY enters a weird state which leads to continuously reporting RX errors. In that state, the MAC is not able to receive or send any Ethernet frames and the activity LED is constantly blinking. Since Linux is using the suspend callback when the interface is taken down, ending up in that state can easily happen during a normal startup.
Micrel confirmed the issue in errata DS80000700A [*], caused by abnormal clock recovery when using power down mode. Even the latest revision (A4, Revision ID 0x1513) seems to suffer that problem, and according to the errata is not going to be fixed.
Remove the suspend/resume callback to avoid using the power down mode completely.
[*] https://ww1.microchip.com/downloads/en/DeviceDoc/80000700A.pdf
Fixes: 1a5465f5d6a2 ("phy/micrel: Add suspend/resume support to Micrel PHYs") Signed-off-by: Stefan Agner stefan@agner.ch Acked-by: Marcel Ziswiler marcel.ziswiler@toradex.com Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/micrel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 643b1c1827a92..aec0fcefdccd6 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -1593,8 +1593,9 @@ static struct phy_driver ksphy_driver[] = { .get_sset_count = kszphy_get_sset_count, .get_strings = kszphy_get_strings, .get_stats = kszphy_get_stats, - .suspend = genphy_suspend, - .resume = genphy_resume, + /* No suspend/resume callbacks because of errata DS80000700A, + * receiver error following software power down. + */ }, { .phy_id = PHY_ID_KSZ8041RNLI, .phy_id_mask = MICREL_PHY_ID_MASK,
From: Ye Bin yebin10@huawei.com
[ Upstream commit 0c98057be9efa32de78dbc4685fc73da9d71faa1 ]
I got issue as follows: [ 263.886511] BUG: KASAN: use-after-free in pid_show+0x11f/0x13f [ 263.888359] Read of size 4 at addr ffff8880bf0648c0 by task cat/746 [ 263.890479] CPU: 0 PID: 746 Comm: cat Not tainted 4.19.90-dirty #140 [ 263.893162] Call Trace: [ 263.893509] dump_stack+0x108/0x15f [ 263.893999] print_address_description+0xa5/0x372 [ 263.894641] kasan_report.cold+0x236/0x2a8 [ 263.895696] __asan_report_load4_noabort+0x25/0x30 [ 263.896365] pid_show+0x11f/0x13f [ 263.897422] dev_attr_show+0x48/0x90 [ 263.898361] sysfs_kf_seq_show+0x24d/0x4b0 [ 263.899479] kernfs_seq_show+0x14e/0x1b0 [ 263.900029] seq_read+0x43f/0x1150 [ 263.900499] kernfs_fop_read+0xc7/0x5a0 [ 263.903764] vfs_read+0x113/0x350 [ 263.904231] ksys_read+0x103/0x270 [ 263.905230] __x64_sys_read+0x77/0xc0 [ 263.906284] do_syscall_64+0x106/0x360 [ 263.906797] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Reproduce this issue as follows: 1. nbd-server 8000 /tmp/disk 2. nbd-client localhost 8000 /dev/nbd1 3. cat /sys/block/nbd1/pid Then trigger use-after-free in pid_show.
Reason is after do step '2', nbd-client progress is already exit. So it's task_struct already freed. To solve this issue, revert part of 6521d39a64b3's modify and remove useless 'recv_task' member of nbd_device.
Fixes: 6521d39a64b3 ("nbd: Remove variable 'pid'") Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: Josef Bacik josef@toxicpanda.com Link: https://lore.kernel.org/r/20211020073959.2679255-1-yebin10@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/nbd.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 1183f7872b713..4f1b591c3a555 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -122,10 +122,10 @@ struct nbd_device { struct work_struct remove_work;
struct list_head list; - struct task_struct *task_recv; struct task_struct *task_setup;
unsigned long flags; + pid_t pid; /* pid of nbd-client, if attached */
char *backend; }; @@ -217,7 +217,7 @@ static ssize_t pid_show(struct device *dev, struct gendisk *disk = dev_to_disk(dev); struct nbd_device *nbd = (struct nbd_device *)disk->private_data;
- return sprintf(buf, "%d\n", task_pid_nr(nbd->task_recv)); + return sprintf(buf, "%d\n", nbd->pid); }
static const struct device_attribute pid_attr = { @@ -329,7 +329,7 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, nbd->config->bytesize = bytesize; nbd->config->blksize_bits = __ffs(blksize);
- if (!nbd->task_recv) + if (!nbd->pid) return 0;
if (nbd->config->flags & NBD_FLAG_SEND_TRIM) { @@ -1241,7 +1241,7 @@ static void nbd_config_put(struct nbd_device *nbd) if (test_and_clear_bit(NBD_RT_HAS_PID_FILE, &config->runtime_flags)) device_remove_file(disk_to_dev(nbd->disk), &pid_attr); - nbd->task_recv = NULL; + nbd->pid = 0; if (test_and_clear_bit(NBD_RT_HAS_BACKEND_FILE, &config->runtime_flags)) { device_remove_file(disk_to_dev(nbd->disk), &backend_attr); @@ -1282,7 +1282,7 @@ static int nbd_start_device(struct nbd_device *nbd) int num_connections = config->num_connections; int error = 0, i;
- if (nbd->task_recv) + if (nbd->pid) return -EBUSY; if (!config->socks) return -EINVAL; @@ -1301,7 +1301,7 @@ static int nbd_start_device(struct nbd_device *nbd) }
blk_mq_update_nr_hw_queues(&nbd->tag_set, config->num_connections); - nbd->task_recv = current; + nbd->pid = task_pid_nr(current);
nbd_parse_flags(nbd);
@@ -1557,8 +1557,8 @@ static int nbd_dbg_tasks_show(struct seq_file *s, void *unused) { struct nbd_device *nbd = s->private;
- if (nbd->task_recv) - seq_printf(s, "recv: %d\n", task_pid_nr(nbd->task_recv)); + if (nbd->pid) + seq_printf(s, "recv: %d\n", nbd->pid);
return 0; } @@ -2135,7 +2135,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) mutex_lock(&nbd->config_lock); config = nbd->config; if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) || - !nbd->task_recv) { + !nbd->pid) { dev_err(nbd_to_dev(nbd), "not configured, cannot reconfigure\n"); ret = -EINVAL;
From: Max Gurtovoy mgurtovoy@nvidia.com
[ Upstream commit 09748122009aed7bfaa7acc33c10c083a4758322 ]
In case that icdoff is not zero or mandatory keyed sgls are not supported by the NVMe/RDMA target, we'll go to error flow but we'll return 0 to the caller. Fix it by returning an appropriate error code.
Fixes: c66e2998c8ca ("nvme-rdma: centralize controller setup sequence") Signed-off-by: Max Gurtovoy mgurtovoy@nvidia.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/rdma.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 042c594bc57e2..0498801542eb6 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1095,11 +1095,13 @@ static int nvme_rdma_setup_ctrl(struct nvme_rdma_ctrl *ctrl, bool new) return ret;
if (ctrl->ctrl.icdoff) { + ret = -EOPNOTSUPP; dev_err(ctrl->ctrl.device, "icdoff is not supported!\n"); goto destroy_admin; }
if (!(ctrl->ctrl.sgls & (1 << 2))) { + ret = -EOPNOTSUPP; dev_err(ctrl->ctrl.device, "Mandatory keyed sgls are not supported!\n"); goto destroy_admin;
From: Anders Roxell anders.roxell@linaro.org
[ Upstream commit 01de5fcd8b1ac0ca28d2bb0921226a54fdd62684 ]
When building the kernel with sparse enabled 'C=1' the following warnings shows up:
kernel/power/swap.c:390:29: warning: incorrect type in assignment (different base types) kernel/power/swap.c:390:29: expected int ret kernel/power/swap.c:390:29: got restricted blk_status_t
This is due to function hib_wait_io() returns a 'blk_status_t' which is a bitwise u8. Commit 5416da01ff6e ("PM: hibernate: Remove blk_status_to_errno in hib_wait_io") seemed to have mixed up the return type. However, the 4e4cbee93d56 ("block: switch bios to blk_status_t") actually broke the behaviour by returning the wrong type.
Rework so function hib_wait_io() returns a 'int' instead of 'blk_status_t' and make sure to call function blk_status_to_errno(hb->error)' when returning from function hib_wait_io() a int gets returned.
Fixes: 4e4cbee93d56 ("block: switch bios to blk_status_t") Fixes: 5416da01ff6e ("PM: hibernate: Remove blk_status_to_errno in hib_wait_io") Signed-off-by: Anders Roxell anders.roxell@linaro.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/power/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 0aabc94125d6b..f3a1086f7cdb2 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -299,7 +299,7 @@ static int hib_submit_io(int op, int op_flags, pgoff_t page_off, void *addr, return error; }
-static blk_status_t hib_wait_io(struct hib_bio_batch *hb) +static int hib_wait_io(struct hib_bio_batch *hb) { /* * We are relying on the behavior of blk_plug that a thread with
From: Kees Cook keescook@chromium.org
[ Upstream commit eda9a4f7af6ee47e9e131f20e4f8a41a97379293 ]
When building OMAP_DM_TIMER without TIMER_OF, there are orphan sections due to the use of TIMER_OF_DELCARE() without CONFIG_TIMER_OF. Select CONFIG_TIMER_OF when enaling OMAP_DM_TIMER:
arm-linux-gnueabi-ld: warning: orphan section `__timer_of_table' from `drivers/clocksource/timer-ti-dm-systimer.o' being placed in section `__timer_of_table'
Reported-by: kernel test robot lkp@intel.com Link: https://lore.kernel.org/lkml/202108282255.tkdt4ani-lkp@intel.com/ Cc: Tony Lindgren tony@atomide.com Cc: Daniel Lezcano daniel.lezcano@linaro.org Cc: Keerthy j-keerthy@ti.com Cc: Sebastian Reichel sebastian.reichel@collabora.co.uk Cc: Ladislav Michl ladis@linux-mips.org Cc: Grygorii Strashko grygorii.strashko@ti.com Cc: linux-omap@vger.kernel.org Fixes: 52762fbd1c47 ("clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support") Signed-off-by: Kees Cook keescook@chromium.org Acked-by: Tony Lindgren tony@atomide.com Link: https://lore.kernel.org/r/20210828175747.3777891-1-keescook@chromium.org Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clocksource/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 0f5e3983951a8..08f8cb944a2ac 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -24,6 +24,7 @@ config I8253_LOCK
config OMAP_DM_TIMER bool + select TIMER_OF
config CLKBLD_I8253 def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
From: Joerg Roedel jroedel@suse.de
[ Upstream commit 5681981fb788281b09a4ea14d310d30b2bd89132 ]
The value of STACK_TYPE_EXCEPTION_LAST points to the last _valid_ exception stack. Reflect that in the check done in the vc_switch_off_ist() function.
Fixes: a13644f3a53de ("x86/entry/64: Add entry code for #VC handler") Reported-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Borislav Petkov bp@suse.de Link: https://lkml.kernel.org/r/20211021080833.30875-2-joro@8bytes.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index cc6de3a01293c..5b1984d468227 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -743,7 +743,7 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r stack = (unsigned long *)sp;
if (!get_stack_info_noinstr(stack, current, &info) || info.type == STACK_TYPE_ENTRY || - info.type >= STACK_TYPE_EXCEPTION_LAST) + info.type > STACK_TYPE_EXCEPTION_LAST) sp = __this_cpu_ist_top_va(VC2);
sync:
From: Jessica Zhang jesszhan@codeaurora.org
[ Upstream commit 8bf71a5719b6cc5b6ba358096081e5d50ea23ab6 ]
Move initialization of sblk in _sspp_subblk_offset() after NULL check to avoid potential NULL pointer dereference.
Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Jessica Zhang jesszhan@codeaurora.org Link: https://lore.kernel.org/r/20211020175733.3379-1-jesszhan@codeaurora.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c index 69eed79324865..f9460672176aa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -138,11 +138,13 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx, u32 *idx) { int rc = 0; - const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk; + const struct dpu_sspp_sub_blks *sblk;
- if (!ctx) + if (!ctx || !ctx->cap || !ctx->cap->sblk) return -EINVAL;
+ sblk = ctx->cap->sblk; + switch (s_id) { case DPU_SSPP_SRC: *idx = sblk->src_blk.base; @@ -419,7 +421,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
(void)pe; if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp - || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk) + || !scaler3_cfg) return;
dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
From: Jessica Zhang jesszhan@codeaurora.org
[ Upstream commit 409af447c2a0a6e08ba190993a1153c91d3b11bd ]
Change byte_clk_rate, pixel_clk_rate, esc_clk_rate, and src_clk_rate from u32 to unsigned long, since clk_get_rate() returns an unsigned long.
Fixes: a6bcddbc2ee1 ("drm/msm: dsi: Handle dual-channel for 6G as well") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Jessica Zhang jesszhan@codeaurora.org Link: https://lore.kernel.org/r/20211020183438.32263-1-jesszhan@codeaurora.org Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/msm/dsi/dsi_host.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index bccd379bdba75..ea641151e77e7 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -115,16 +115,16 @@ struct msm_dsi_host { struct clk *pixel_clk_src; struct clk *byte_intf_clk;
- u32 byte_clk_rate; - u32 pixel_clk_rate; - u32 esc_clk_rate; + unsigned long byte_clk_rate; + unsigned long pixel_clk_rate; + unsigned long esc_clk_rate;
/* DSI v2 specific clocks */ struct clk *src_clk; struct clk *esc_clk_src; struct clk *dsi_clk_src;
- u32 src_clk_rate; + unsigned long src_clk_rate;
struct gpio_desc *disp_en_gpio; struct gpio_desc *te_gpio; @@ -498,10 +498,10 @@ int msm_dsi_runtime_resume(struct device *dev)
int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host) { - u32 byte_intf_rate; + unsigned long byte_intf_rate; int ret;
- DBG("Set clk rates: pclk=%d, byteclk=%d", + DBG("Set clk rates: pclk=%d, byteclk=%lu", msm_host->mode->clock, msm_host->byte_clk_rate);
ret = dev_pm_opp_set_rate(&msm_host->pdev->dev, @@ -583,7 +583,7 @@ int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host) { int ret;
- DBG("Set clk rates: pclk=%d, byteclk=%d, esc_clk=%d, dsi_src_clk=%d", + DBG("Set clk rates: pclk=%d, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu", msm_host->mode->clock, msm_host->byte_clk_rate, msm_host->esc_clk_rate, msm_host->src_clk_rate);
@@ -673,10 +673,10 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) clk_disable_unprepare(msm_host->byte_clk); }
-static u32 dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi) +static unsigned long dsi_get_pclk_rate(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { struct drm_display_mode *mode = msm_host->mode; - u32 pclk_rate; + unsigned long pclk_rate;
pclk_rate = mode->clock * 1000;
@@ -696,7 +696,7 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { u8 lanes = msm_host->lanes; u32 bpp = dsi_get_bpp(msm_host->format); - u32 pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi); + unsigned long pclk_rate = dsi_get_pclk_rate(msm_host, is_bonded_dsi); u64 pclk_bpp = (u64)pclk_rate * bpp;
if (lanes == 0) { @@ -713,7 +713,7 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi) msm_host->pixel_clk_rate = pclk_rate; msm_host->byte_clk_rate = pclk_bpp;
- DBG("pclk=%d, bclk=%d", msm_host->pixel_clk_rate, + DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
} @@ -772,7 +772,7 @@ int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
- DBG("esc=%d, src=%d", msm_host->esc_clk_rate, + DBG("esc=%lu, src=%lu", msm_host->esc_clk_rate, msm_host->src_clk_rate);
return 0;
From: Horia Geantă horia.geanta@nxp.com
[ Upstream commit 3ae88f676aa63366ffa9eebb8ae787c7e19f0c57 ]
Commit ad6d66bcac77e ("crypto: tcrypt - include 1420 byte blocks in aead and skcipher benchmarks") mentions:
power-of-2 block size. So let's add 1420 bytes explicitly, and round it up to the next blocksize multiple of the algo in question if it does not support 1420 byte blocks.
but misses updating skcipher multi-buffer tests.
Fix this by using the proper (rounded) input size.
Fixes: ad6d66bcac77e ("crypto: tcrypt - include 1420 byte blocks in aead and skcipher benchmarks") Signed-off-by: Horia Geantă horia.geanta@nxp.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/tcrypt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 82b0400985a51..00149657a4bc1 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1333,7 +1333,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
if (bs > XBUFSIZE * PAGE_SIZE) { pr_err("template (%u) too big for buffer (%lu)\n", - *b_size, XBUFSIZE * PAGE_SIZE); + bs, XBUFSIZE * PAGE_SIZE); goto out; }
@@ -1386,8 +1386,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, memset(cur->xbuf[p], 0xff, k);
skcipher_request_set_crypt(cur->req, cur->sg, - cur->sg, *b_size, - iv); + cur->sg, bs, iv); }
if (secs) {
From: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp
[ Upstream commit 0934ad42bb2c5df90a1b9de690f93de735b622fe ]
syzbot is reporting UAF at cipso_v4_doi_search() [1], for smk_cipso_doi() is calling kfree() without removing from the cipso_v4_doi_list list after netlbl_cfg_cipsov4_map_add() returned an error. We need to use netlbl_cfg_cipsov4_del() in order to remove from the list and wait for RCU grace period before kfree().
Link: https://syzkaller.appspot.com/bug?extid=93dba5b91f0fed312cbd [1] Reported-by: syzbot syzbot+93dba5b91f0fed312cbd@syzkaller.appspotmail.com Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Fixes: 6c2e8ac0953fccdd ("netlabel: Update kernel configuration API") Signed-off-by: Casey Schaufler casey@schaufler-ca.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/smack/smackfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 89989d28ffc55..658eab05599e6 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -712,7 +712,7 @@ static void smk_cipso_doi(void) if (rc != 0) { printk(KERN_WARNING "%s:%d map add rc = %d\n", __func__, __LINE__, rc); - kfree(doip); + netlbl_cfg_cipsov4_del(doip->doi, &nai); return; } }
From: Jim Mattson jmattson@google.com
[ Upstream commit ed290e1c20da19fa100a3e0f421aa31b65984960 ]
Though gcc conveniently compiles a simple memset to "rep stos," clang prefers to call the libc version of memset. If a test is dynamically linked, the libc memset isn't available in L1 (nor is the PLT or the GOT, for that matter). Even if the test is statically linked, the libc memset may choose to use some CPU features, like AVX, which may not be enabled in L1. Note that __builtin_memset doesn't solve the problem, because (a) the compiler is free to call memset anyway, and (b) __builtin_memset may also choose to use features like AVX, which may not be available in L1.
To avoid a myriad of problems, use an explicit "rep stos" to clear the VMCB in generic_svm_setup(), which is called both from L0 and L1.
Reported-by: Ricardo Koller ricarkol@google.com Signed-off-by: Jim Mattson jmattson@google.com Fixes: 20ba262f8631a ("selftests: KVM: AMD Nested test infrastructure") Message-Id: 20210930003649.4026553-1-jmattson@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/kvm/lib/x86_64/svm.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/lib/x86_64/svm.c b/tools/testing/selftests/kvm/lib/x86_64/svm.c index 2ac98d70d02bd..161eba7cd1289 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/svm.c +++ b/tools/testing/selftests/kvm/lib/x86_64/svm.c @@ -54,6 +54,18 @@ static void vmcb_set_seg(struct vmcb_seg *seg, u16 selector, seg->base = base; }
+/* + * Avoid using memset to clear the vmcb, since libc may not be + * available in L1 (and, even if it is, features that libc memset may + * want to use, like AVX, may not be enabled). + */ +static void clear_vmcb(struct vmcb *vmcb) +{ + int n = sizeof(*vmcb) / sizeof(u32); + + asm volatile ("rep stosl" : "+c"(n), "+D"(vmcb) : "a"(0) : "memory"); +} + void generic_svm_setup(struct svm_test_data *svm, void *guest_rip, void *guest_rsp) { struct vmcb *vmcb = svm->vmcb; @@ -70,7 +82,7 @@ void generic_svm_setup(struct svm_test_data *svm, void *guest_rip, void *guest_r wrmsr(MSR_EFER, efer | EFER_SVME); wrmsr(MSR_VM_HSAVE_PA, svm->save_area_gpa);
- memset(vmcb, 0, sizeof(*vmcb)); + clear_vmcb(vmcb); asm volatile ("vmsave %0\n\t" : : "a" (vmcb_gpa) : "memory"); vmcb_set_seg(&save->es, get_es(), 0, -1U, data_seg_attr); vmcb_set_seg(&save->cs, get_cs(), 0, -1U, code_seg_attr);
From: Mauricio Vásquez mauricio@kinvolk.io
[ Upstream commit 1000298c76830bc291358e98e8fa5baa3baa9b3a ]
Free btf_dedup if btf_ensure_modifiable() returns error.
Fixes: 919d2b1dbb07 ("libbpf: Allow modification of BTF and add btf__add_str API") Signed-off-by: Mauricio Vásquez mauricio@kinvolk.io Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20211022202035.48868-1-mauricio@kinvolk.io Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/btf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 77dc24d58302d..bf8c8676d68e5 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -2914,8 +2914,10 @@ int btf__dedup(struct btf *btf, struct btf_ext *btf_ext, return libbpf_err(-EINVAL); }
- if (btf_ensure_modifiable(btf)) - return libbpf_err(-ENOMEM); + if (btf_ensure_modifiable(btf)) { + err = -ENOMEM; + goto done; + }
err = btf_dedup_prep(d); if (err) {
From: Quentin Monnet quentin@isovalent.com
[ Upstream commit e89ef634f81c9d90e1824ab183721f3b361472e6 ]
Bpftool creates a new JSON object for writing program metadata in plain text mode, regardless of metadata being present or not. Then this writer is freed if any metadata has been found and printed, but it leaks otherwise. We cannot destroy the object unconditionally, because the destructor prints an undesirable line break. Instead, make sure the writer is created only after we have found program metadata to print.
Found with valgrind.
Fixes: aff52e685eb3 ("bpftool: Support dumping metadata") Signed-off-by: Quentin Monnet quentin@isovalent.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20211022094743.11052-1-quentin@isovalent.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/bpftool/prog.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 9c3e343b7d872..fe59404e87046 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -308,18 +308,12 @@ static void show_prog_metadata(int fd, __u32 num_maps) if (printed_header) jsonw_end_object(json_wtr); } else { - json_writer_t *btf_wtr = jsonw_new(stdout); + json_writer_t *btf_wtr; struct btf_dumper d = { .btf = btf, - .jw = btf_wtr, .is_plain_text = true, };
- if (!btf_wtr) { - p_err("jsonw alloc failed"); - goto out_free; - } - for (i = 0; i < vlen; i++, vsi++) { t_var = btf__type_by_id(btf, vsi->type); name = btf__name_by_offset(btf, t_var->name_off); @@ -329,6 +323,14 @@ static void show_prog_metadata(int fd, __u32 num_maps)
if (!printed_header) { printf("\tmetadata:"); + + btf_wtr = jsonw_new(stdout); + if (!btf_wtr) { + p_err("jsonw alloc failed"); + goto out_free; + } + d.jw = btf_wtr, + printed_header = true; }
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit 5245dafe3d49efba4d3285cf27ee1cc1eeafafc6 ]
btf_header's str_off+str_len or type_off+type_len can overflow as they are u32s. This will lead to bypassing the sanity checks during BTF parsing, resulting in crashes afterwards. Fix by using 64-bit signed integers for comparison.
Fixes: d8123624506c ("libbpf: Fix BTF data layout checks and allow empty BTF") Reported-by: Evgeny Vereshchagin evvers@ya.ru Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20211023003157.726961-1-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/btf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index bf8c8676d68e5..cfd701debcf61 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -236,12 +236,12 @@ static int btf_parse_hdr(struct btf *btf) }
meta_left = btf->raw_size - sizeof(*hdr); - if (meta_left < hdr->str_off + hdr->str_len) { + if (meta_left < (long long)hdr->str_off + hdr->str_len) { pr_debug("Invalid BTF total size:%u\n", btf->raw_size); return -EINVAL; }
- if (hdr->type_off + hdr->type_len > hdr->str_off) { + if ((long long)hdr->type_off + hdr->type_len > hdr->str_off) { pr_debug("Invalid BTF data sections layout: type data at %u + %u, strings data at %u + %u\n", hdr->type_off, hdr->type_len, hdr->str_off, hdr->str_len); return -EINVAL;
From: Andrii Nakryiko andrii@kernel.org
[ Upstream commit c825f5fee19caf301d9821cd79abaa734322de26 ]
Original code assumed fixed and correct BTF header length. That's not always the case, though, so fix this bug with a proper additional check. And use actual header length instead of sizeof(struct btf_header) in sanity checks.
Fixes: 8a138aed4a80 ("bpf: btf: Add BTF support to libbpf") Reported-by: Evgeny Vereshchagin evvers@ya.ru Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20211023003157.726961-2-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/btf.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index cfd701debcf61..1b9341ef638b0 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c @@ -231,13 +231,19 @@ static int btf_parse_hdr(struct btf *btf) } btf_bswap_hdr(hdr); } else if (hdr->magic != BTF_MAGIC) { - pr_debug("Invalid BTF magic:%x\n", hdr->magic); + pr_debug("Invalid BTF magic: %x\n", hdr->magic); return -EINVAL; }
- meta_left = btf->raw_size - sizeof(*hdr); + if (btf->raw_size < hdr->hdr_len) { + pr_debug("BTF header len %u larger than data size %u\n", + hdr->hdr_len, btf->raw_size); + return -EINVAL; + } + + meta_left = btf->raw_size - hdr->hdr_len; if (meta_left < (long long)hdr->str_off + hdr->str_len) { - pr_debug("Invalid BTF total size:%u\n", btf->raw_size); + pr_debug("Invalid BTF total size: %u\n", btf->raw_size); return -EINVAL; }
From: Nick Hainke vincent@systemli.org
[ Upstream commit 753453afacc0243bd45de45e34218a8d17493e8f ]
commit 7f4b7920318b ("mt76: mt7615: add ibss support") introduced IBSS and commit f4ec7fdf7f83 ("mt76: mt7615: enable support for mesh") meshpoint support.
Both used in the "get_omac_idx"-function:
if (~mask & BIT(HW_BSSID_0)) return HW_BSSID_0;
With commit d8d59f66d136 ("mt76: mt7615: support 16 interfaces") the ibss and meshpoint mode should "prefer hw bssid slot 1-3". However, with that change the ibss or meshpoint mode will not send any beacon on the mt7622 wifi anymore. Devices were still able to exchange data but only if a bssid already existed. Two mt7622 devices will never be able to communicate.
This commits reverts the preferation of slot 1-3 for ibss and meshpoint. Only NL80211_IFTYPE_STATION will still prefer slot 1-3.
Tested on Banana Pi R64.
Fixes: d8d59f66d136 ("mt76: mt7615: support 16 interfaces") Signed-off-by: Nick Hainke vincent@systemli.org Acked-by: Felix Fietkau nbd@nbd.name Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211007225725.2615-1-vincent@systemli.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index dada43d6d879e..51260a669d166 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -135,8 +135,6 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) int i;
switch (type) { - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: /* prefer hw bssid slot 1-3 */ i = get_free_idx(mask, HW_BSSID_1, HW_BSSID_3); @@ -160,6 +158,8 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) return HW_BSSID_0;
break; + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP: /* ap uses hw bssid 0 and ext bssid */
From: David Hildenbrand david@redhat.com
[ Upstream commit 2d8fb8f3914b40e3cc12f8cbb74daefd5245349d ]
We should not walk/touch page tables outside of VMA boundaries when holding only the mmap sem in read mode. Evil user space can modify the VMA layout just before this function runs and e.g., trigger races with page table removal code since commit dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap"). The pure prescence in our guest_to_host radix tree does not imply that there is a VMA.
Further, we should not allocate page tables (via get_locked_pte()) outside of VMA boundaries: if evil user space decides to map hugetlbfs to these ranges, bad things will happen because we suddenly have PTE or PMD page tables where we shouldn't have them.
Similarly, we have to check if we suddenly find a hugetlbfs VMA, before calling get_locked_pte().
Note that gmap_discard() is different: zap_page_range()->unmap_single_vma() makes sure to stay within VMA boundaries.
Fixes: b31288fa83b2 ("s390/kvm: support collaborative memory management") Signed-off-by: David Hildenbrand david@redhat.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Acked-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20210909162248.14969-2-david@redhat.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/gmap.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 4d3b33ce81c62..e0735c3437759 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -672,6 +672,7 @@ EXPORT_SYMBOL_GPL(gmap_fault); */ void __gmap_zap(struct gmap *gmap, unsigned long gaddr) { + struct vm_area_struct *vma; unsigned long vmaddr; spinlock_t *ptl; pte_t *ptep; @@ -681,6 +682,11 @@ void __gmap_zap(struct gmap *gmap, unsigned long gaddr) gaddr >> PMD_SHIFT); if (vmaddr) { vmaddr |= gaddr & ~PMD_MASK; + + vma = vma_lookup(gmap->mm, vmaddr); + if (!vma || is_vm_hugetlb_page(vma)) + return; + /* Get pointer to the page table entry */ ptep = get_locked_pte(gmap->mm, vmaddr, &ptl); if (likely(ptep))
From: David Hildenbrand david@redhat.com
[ Upstream commit b159f94c86b43cf7e73e654bc527255b1f4eafc4 ]
... otherwise we will try unlocking a spinlock that was never locked via a garbage pointer.
At the time we reach this code path, we usually successfully looked up a PGSTE already; however, evil user space could have manipulated the VMA layout in the meantime and triggered removal of the page table.
Fixes: 1e133ab296f3 ("s390/mm: split arch/s390/mm/pgtable.c") Signed-off-by: David Hildenbrand david@redhat.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Acked-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20210909162248.14969-3-david@redhat.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/gmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index e0735c3437759..d63c0ccc5ccda 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -689,9 +689,10 @@ void __gmap_zap(struct gmap *gmap, unsigned long gaddr)
/* Get pointer to the page table entry */ ptep = get_locked_pte(gmap->mm, vmaddr, &ptl); - if (likely(ptep)) + if (likely(ptep)) { ptep_zap_unused(gmap->mm, vmaddr, ptep, 0); - pte_unmap_unlock(ptep, ptl); + pte_unmap_unlock(ptep, ptl); + } } } EXPORT_SYMBOL_GPL(__gmap_zap);
From: David Hildenbrand david@redhat.com
[ Upstream commit fe3d10024073f06f04c74b9674bd71ccc1d787cf ]
We should not walk/touch page tables outside of VMA boundaries when holding only the mmap sem in read mode. Evil user space can modify the VMA layout just before this function runs and e.g., trigger races with page table removal code since commit dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap"). gfn_to_hva() will only translate using KVM memory regions, but won't validate the VMA.
Further, we should not allocate page tables outside of VMA boundaries: if evil user space decides to map hugetlbfs to these ranges, bad things will happen because we suddenly have PTE or PMD page tables where we shouldn't have them.
Similarly, we have to check if we suddenly find a hugetlbfs VMA, before calling get_locked_pte().
Fixes: 2d42f9477320 ("s390/kvm: Add PGSTE manipulation functions") Signed-off-by: David Hildenbrand david@redhat.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Acked-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20210909162248.14969-4-david@redhat.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/pgtable.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 034721a68d8fd..2717a406edeb3 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -988,6 +988,7 @@ EXPORT_SYMBOL(get_guest_storage_key); int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, unsigned long *oldpte, unsigned long *oldpgste) { + struct vm_area_struct *vma; unsigned long pgstev; spinlock_t *ptl; pgste_t pgste; @@ -997,6 +998,10 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, WARN_ON_ONCE(orc > ESSA_MAX); if (unlikely(orc > ESSA_MAX)) return -EINVAL; + + vma = vma_lookup(mm, hva); + if (!vma || is_vm_hugetlb_page(vma)) + return -EFAULT; ptep = get_locked_pte(mm, hva, &ptl); if (unlikely(!ptep)) return -EFAULT; @@ -1089,10 +1094,14 @@ EXPORT_SYMBOL(pgste_perform_essa); int set_pgste_bits(struct mm_struct *mm, unsigned long hva, unsigned long bits, unsigned long value) { + struct vm_area_struct *vma; spinlock_t *ptl; pgste_t new; pte_t *ptep;
+ vma = vma_lookup(mm, hva); + if (!vma || is_vm_hugetlb_page(vma)) + return -EFAULT; ptep = get_locked_pte(mm, hva, &ptl); if (unlikely(!ptep)) return -EFAULT; @@ -1117,9 +1126,13 @@ EXPORT_SYMBOL(set_pgste_bits); */ int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep) { + struct vm_area_struct *vma; spinlock_t *ptl; pte_t *ptep;
+ vma = vma_lookup(mm, hva); + if (!vma || is_vm_hugetlb_page(vma)) + return -EFAULT; ptep = get_locked_pte(mm, hva, &ptl); if (unlikely(!ptep)) return -EFAULT;
From: David Hildenbrand david@redhat.com
[ Upstream commit 949f5c1244ee6c36d2e81c588d1200eaa83a3df6 ]
There are multiple things broken about our storage key handling functions:
1. We should not walk/touch page tables outside of VMA boundaries when holding only the mmap sem in read mode. Evil user space can modify the VMA layout just before this function runs and e.g., trigger races with page table removal code since commit dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap"). gfn_to_hva() will only translate using KVM memory regions, but won't validate the VMA.
2. We should not allocate page tables outside of VMA boundaries: if evil user space decides to map hugetlbfs to these ranges, bad things will happen because we suddenly have PTE or PMD page tables where we shouldn't have them.
3. We don't handle large PUDs that might suddenly appeared inside our page table hierarchy.
Don't manually allocate page tables, properly validate that we have VMA and bail out on pud_large().
All callers of page table handling functions, except get_guest_storage_key(), call fixup_user_fault() in case they receive an -EFAULT and retry; this will allocate the necessary page tables if required.
To keep get_guest_storage_key() working as expected and not requiring kvm_s390_get_skeys() to call fixup_user_fault() distinguish between "there is simply no page table or huge page yet and the key is assumed to be 0" and "this is a fault to be reported".
Although commit 637ff9efe5ea ("s390/mm: Add huge pmd storage key handling") introduced most of the affected code, it was actually already broken before when using get_locked_pte() without any VMA checks.
Note: Ever since commit 637ff9efe5ea ("s390/mm: Add huge pmd storage key handling") we can no longer set a guest storage key (for example from QEMU during VM live migration) without actually resolving a fault. Although we would have created most page tables, we would choke on the !pmd_present(), requiring a call to fixup_user_fault(). I would have thought that this is problematic in combination with postcopy life migration ... but nobody noticed and this patch doesn't change the situation. So maybe it's just fine.
Fixes: 9fcf93b5de06 ("KVM: S390: Create helper function get_guest_storage_key") Fixes: 24d5dd0208ed ("s390/kvm: Provide function for setting the guest storage key") Fixes: a7e19ab55ffd ("KVM: s390: handle missing storage-key facility") Signed-off-by: David Hildenbrand david@redhat.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Acked-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20210909162248.14969-5-david@redhat.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/pgtable.c | 57 +++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-)
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 2717a406edeb3..6ad634a27d5b9 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -429,22 +429,36 @@ static inline pmd_t pmdp_flush_lazy(struct mm_struct *mm, }
#ifdef CONFIG_PGSTE -static pmd_t *pmd_alloc_map(struct mm_struct *mm, unsigned long addr) +static int pmd_lookup(struct mm_struct *mm, unsigned long addr, pmd_t **pmdp) { + struct vm_area_struct *vma; pgd_t *pgd; p4d_t *p4d; pud_t *pud; - pmd_t *pmd; + + /* We need a valid VMA, otherwise this is clearly a fault. */ + vma = vma_lookup(mm, addr); + if (!vma) + return -EFAULT;
pgd = pgd_offset(mm, addr); - p4d = p4d_alloc(mm, pgd, addr); - if (!p4d) - return NULL; - pud = pud_alloc(mm, p4d, addr); - if (!pud) - return NULL; - pmd = pmd_alloc(mm, pud, addr); - return pmd; + if (!pgd_present(*pgd)) + return -ENOENT; + + p4d = p4d_offset(pgd, addr); + if (!p4d_present(*p4d)) + return -ENOENT; + + pud = pud_offset(p4d, addr); + if (!pud_present(*pud)) + return -ENOENT; + + /* Large PUDs are not supported yet. */ + if (pud_large(*pud)) + return -EFAULT; + + *pmdp = pmd_offset(pud, addr); + return 0; } #endif
@@ -778,8 +792,7 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp; pte_t *ptep;
- pmdp = pmd_alloc_map(mm, addr); - if (unlikely(!pmdp)) + if (pmd_lookup(mm, addr, &pmdp)) return -EFAULT;
ptl = pmd_lock(mm, pmdp); @@ -881,8 +894,7 @@ int reset_guest_reference_bit(struct mm_struct *mm, unsigned long addr) pte_t *ptep; int cc = 0;
- pmdp = pmd_alloc_map(mm, addr); - if (unlikely(!pmdp)) + if (pmd_lookup(mm, addr, &pmdp)) return -EFAULT;
ptl = pmd_lock(mm, pmdp); @@ -935,15 +947,24 @@ int get_guest_storage_key(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp; pte_t *ptep;
- pmdp = pmd_alloc_map(mm, addr); - if (unlikely(!pmdp)) + /* + * If we don't have a PTE table and if there is no huge page mapped, + * the storage key is 0. + */ + *key = 0; + + switch (pmd_lookup(mm, addr, &pmdp)) { + case -ENOENT: + return 0; + case 0: + break; + default: return -EFAULT; + }
ptl = pmd_lock(mm, pmdp); if (!pmd_present(*pmdp)) { - /* Not yet mapped memory has a zero key */ spin_unlock(ptl); - *key = 0; return 0; }
From: David Hildenbrand david@redhat.com
[ Upstream commit 46c22ffd2772201662350bc7b94b9ea9d3ee5ac2 ]
We should not walk/touch page tables outside of VMA boundaries when holding only the mmap sem in read mode. Evil user space can modify the VMA layout just before this function runs and e.g., trigger races with page table removal code since commit dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap").
find_vma() does not check if the address is >= the VMA start address; use vma_lookup() instead.
Fixes: 214d9bbcd3a6 ("s390/mm: provide memory management functions for protected KVM guests") Signed-off-by: David Hildenbrand david@redhat.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Acked-by: Heiko Carstens hca@linux.ibm.com Reviewed-by: Liam R. Howlett Liam.Howlett@oracle.com Link: https://lore.kernel.org/r/20210909162248.14969-6-david@redhat.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kernel/uv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c index 5a656c7b7a67a..f95ccbd396925 100644 --- a/arch/s390/kernel/uv.c +++ b/arch/s390/kernel/uv.c @@ -212,7 +212,7 @@ again: uaddr = __gmap_translate(gmap, gaddr); if (IS_ERR_VALUE(uaddr)) goto out; - vma = find_vma(gmap->mm, uaddr); + vma = vma_lookup(gmap->mm, uaddr); if (!vma) goto out; /*
From: Claudio Imbrenda imbrenda@linux.ibm.com
[ Upstream commit d4074324b07a94a1fca476d452dfbb3a4e7bf656 ]
If kvm_s390_pv_destroy_cpu is called more than once, we risk calling free_page on a random page, since the sidad field is aliased with the gbea, which is not guaranteed to be zero.
This can happen, for example, if userspace calls the KVM_PV_DISABLE IOCTL, and it fails, and then userspace calls the same IOCTL again. This scenario is only possible if KVM has some serious bug or if the hardware is broken.
The solution is to simply return successfully immediately if the vCPU was already non secure.
Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Fixes: 19e1227768863a1469797c13ef8fea1af7beac2c ("KVM: S390: protvirt: Introduce instruction data area bounce buffer") Reviewed-by: Janosch Frank frankja@linux.ibm.com Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Message-Id: 20210920132502.36111-3-imbrenda@linux.ibm.com Signed-off-by: Janosch Frank frankja@linux.ibm.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/pv.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c index c8841f476e913..0a854115100b4 100644 --- a/arch/s390/kvm/pv.c +++ b/arch/s390/kvm/pv.c @@ -16,18 +16,17 @@
int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) { - int cc = 0; + int cc;
- if (kvm_s390_pv_cpu_get_handle(vcpu)) { - cc = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), - UVC_CMD_DESTROY_SEC_CPU, rc, rrc); + if (!kvm_s390_pv_cpu_get_handle(vcpu)) + return 0; + + cc = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), UVC_CMD_DESTROY_SEC_CPU, rc, rrc); + + KVM_UV_EVENT(vcpu->kvm, 3, "PROTVIRT DESTROY VCPU %d: rc %x rrc %x", + vcpu->vcpu_id, *rc, *rrc); + WARN_ONCE(cc, "protvirt destroy cpu failed rc %x rrc %x", *rc, *rrc);
- KVM_UV_EVENT(vcpu->kvm, 3, - "PROTVIRT DESTROY VCPU %d: rc %x rrc %x", - vcpu->vcpu_id, *rc, *rrc); - WARN_ONCE(cc, "protvirt destroy cpu failed rc %x rrc %x", - *rc, *rrc); - } /* Intended memory leak for something that should never happen. */ if (!cc) free_pages(vcpu->arch.pv.stor_base,
From: Claudio Imbrenda imbrenda@linux.ibm.com
[ Upstream commit 1e2aa46de526a5adafe580bca4c25856bb06f09e ]
When the system is heavily overcommitted, kvm_s390_pv_init_vm might generate stall notifications.
Fix this by using uv_call_sched instead of just uv_call. This is ok because we are not holding spinlocks.
Signed-off-by: Claudio Imbrenda imbrenda@linux.ibm.com Fixes: 214d9bbcd3a672 ("s390/mm: provide memory management functions for protected KVM guests") Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Reviewed-by: Janosch Frank frankja@linux.ibm.com Message-Id: 20210920132502.36111-4-imbrenda@linux.ibm.com Signed-off-by: Janosch Frank frankja@linux.ibm.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/pv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c index 0a854115100b4..00d272d134c24 100644 --- a/arch/s390/kvm/pv.c +++ b/arch/s390/kvm/pv.c @@ -195,7 +195,7 @@ int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc) uvcb.conf_base_stor_origin = (u64)kvm->arch.pv.stor_base; uvcb.conf_virt_stor_origin = (u64)kvm->arch.pv.stor_var;
- cc = uv_call(0, (u64)&uvcb); + cc = uv_call_sched(0, (u64)&uvcb); *rc = uvcb.header.rc; *rrc = uvcb.header.rrc; KVM_UV_EVENT(kvm, 3, "PROTVIRT CREATE VM: handle %llx len %llx rc %x rrc %x",
From: Mark Rutland mark.rutland@arm.com
[ Upstream commit c65b52d02f6c1a06ddb20cba175ad49eccd6410d ]
As bcm6345_l1_irq_handle() is a chained irqchip handler, it will be invoked within the context of the root irqchip handler, which must have entered IRQ context already.
When bcm6345_l1_irq_handle() calls arch/mips's do_IRQ() , this will nest another call to irq_enter(), and the resulting nested increment to `rcu_data.dynticks_nmi_nesting` will cause rcu_is_cpu_rrupt_from_idle() to fail to identify wakeups from idle, resulting in failure to preempt, and RCU stalls.
Chained irqchip handlers must invoke IRQ handlers by way of thee core irqchip code, i.e. generic_handle_irq() or generic_handle_domain_irq() and should not call do_IRQ(), which is intended only for root irqchip handlers.
Fix bcm6345_l1_irq_handle() by calling generic_handle_irq() directly.
Fixes: c7c42ec2baa1de7a ("irqchips/bmips: Add bcm6345-l1 interrupt controller") Signed-off-by: Mark Rutland mark.rutland@arm.com Reviewed-by: Marc Zyngier maz@kernel.org Acked-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Cc: Thomas Gleixner tglx@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-bcm6345-l1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c index e3483789f4df3..1bd0621c4ce2a 100644 --- a/drivers/irqchip/irq-bcm6345-l1.c +++ b/drivers/irqchip/irq-bcm6345-l1.c @@ -140,7 +140,7 @@ static void bcm6345_l1_irq_handle(struct irq_desc *desc) for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { irq = irq_linear_revmap(intc->domain, base + hwirq); if (irq) - do_IRQ(irq); + generic_handle_irq(irq); else spurious_interrupt(); }
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 232deb3f9567ce37d99b8616a6c07c1fc0436abf ]
At present, when either of ds->ops->port_fdb_del() or ds->ops->port_mdb_del() return a non-zero error code, we attempt to save the day and keep the data structure associated with that switchdev object, as the deletion procedure did not complete.
However, the way in which we do this is suspicious to the checker in lib/refcount.c, who thinks it is buggy to increment a refcount that became zero, and that this is indicative of a use-after-free.
Fixes: 161ca59d39e9 ("net: dsa: reference count the MDB entries at the cross-chip notifier level") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/dsa/switch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/dsa/switch.c b/net/dsa/switch.c index 6466d0539af9f..44558fbdc65b3 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -264,7 +264,7 @@ static int dsa_switch_do_mdb_del(struct dsa_switch *ds, int port,
err = ds->ops->port_mdb_del(ds, port, mdb); if (err) { - refcount_inc(&a->refcount); + refcount_set(&a->refcount, 1); return err; }
@@ -329,7 +329,7 @@ static int dsa_switch_do_fdb_del(struct dsa_switch *ds, int port,
err = ds->ops->port_fdb_del(ds, port, addr, vid); if (err) { - refcount_inc(&a->refcount); + refcount_set(&a->refcount, 1); return err; }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit c2e6df3eaaf120cde5e7c3a70590dd82e427458a ]
pgd_page_vaddr() returns an 'unsigned long' address, causing a warning with the memcpy() call in kasan_init():
arch/arm/mm/kasan_init.c: In function 'kasan_init': include/asm-generic/pgtable-nop4d.h:44:50: error: passing argument 2 of '__memcpy' makes pointer from integer without a cast [-Werror=int-conversion] 44 | #define pgd_page_vaddr(pgd) ((unsigned long)(p4d_pgtable((p4d_t){ pgd }))) | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | long unsigned int arch/arm/include/asm/string.h:58:45: note: in definition of macro 'memcpy' 58 | #define memcpy(dst, src, len) __memcpy(dst, src, len) | ^~~ arch/arm/mm/kasan_init.c:229:16: note: in expansion of macro 'pgd_page_vaddr' 229 | pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)), | ^~~~~~~~~~~~~~ arch/arm/include/asm/string.h:21:47: note: expected 'const void *' but argument is of type 'long unsigned int' 21 | extern void *__memcpy(void *dest, const void *src, __kernel_size_t n); | ~~~~~~~~~~~~^~~
Avoid this by adding an explicit typecast.
Link: https://lore.kernel.org/all/CACRpkdb3DMvof3-xdtss0Pc6KM36pJA-iy=WhvtNVnsDpeJ...
Fixes: 5615f69bc209 ("ARM: 9016/2: Initialize the mapping of KASan shadow memory") Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mm/kasan_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c index 9c348042a7244..4b1619584b23c 100644 --- a/arch/arm/mm/kasan_init.c +++ b/arch/arm/mm/kasan_init.c @@ -226,7 +226,7 @@ void __init kasan_init(void) BUILD_BUG_ON(pgd_index(KASAN_SHADOW_START) != pgd_index(KASAN_SHADOW_END)); memcpy(tmp_pmd_table, - pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)), + (void*)pgd_page_vaddr(*pgd_offset_k(KASAN_SHADOW_START)), sizeof(tmp_pmd_table)); set_pgd(&tmp_pgd_table[pgd_index(KASAN_SHADOW_START)], __pgd(__pa(tmp_pmd_table) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
From: Abinaya Kalaiselvan akalaise@codeaurora.org
[ Upstream commit 6f8c8bf4c7c9be1c42088689fd4370e06b46608a ]
Commit 9af7c32ceca8 ("ath10k: add target IRAM recovery feature support") introduced a new firmware feature flag ATH10K_FW_FEATURE_IRAM_RECOVERY. But this caused ath10k_pci module load to fail if ATH10K_FW_CRASH_DUMP_RAM_DATA bit was not enabled in the ath10k coredump_mask module parameter:
[ 2209.328190] ath10k_pci 0000:02:00.0: qca9984/qca9994 hw1.0 target 0x01000000 chip_id 0x00000000 sub 168c:cafe [ 2209.434414] ath10k_pci 0000:02:00.0: kconfig debug 1 debugfs 1 tracing 1 dfs 1 testmode 1 [ 2209.547191] ath10k_pci 0000:02:00.0: firmware ver 10.4-3.9.0.2-00099 api 5 features no-p2p,mfp,peer-flow-ctrl,btcoex-param,allows-mesh-bcast,no-ps,peer-fixed-rate,iram-recovery crc32 cbade90a [ 2210.896485] ath10k_pci 0000:02:00.0: board_file api 1 bmi_id 0:1 crc32 a040efc2 [ 2213.603339] ath10k_pci 0000:02:00.0: failed to copy target iram contents: -12 [ 2213.839027] ath10k_pci 0000:02:00.0: could not init core (-12) [ 2213.933910] ath10k_pci 0000:02:00.0: could not probe fw (-12)
And by default coredump_mask does not have ATH10K_FW_CRASH_DUMP_RAM_DATA enabled so anyone using a firmware with iram-recovery feature would fail. To my knowledge only QCA9984 firmwares starting from release 10.4-3.9.0.2-00099 enabled the feature.
The reason for regression was that ath10k_core_copy_target_iram() used ath10k_coredump_get_mem_layout() to get the memory layout, but when ATH10K_FW_CRASH_DUMP_RAM_DATA was disabled it would get just NULL and bail out with an error.
While looking at all this I noticed another bug: if CONFIG_DEV_COREDUMP is disabled but the firmware has iram-recovery enabled the module load fails with similar error messages. I fixed that by returning 0 from ath10k_core_copy_target_iram() when _ath10k_coredump_get_mem_layout() returns NULL.
Tested-on: QCA9984 hw2.0 PCI 10.4-3.9.0.2-00139
Fixes: 9af7c32ceca8 ("ath10k: add target IRAM recovery feature support") Signed-off-by: Abinaya Kalaiselvan akalaise@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211020075054.23061-1-kvalo@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath10k/core.c | 11 +++++++++-- drivers/net/wireless/ath/ath10k/coredump.c | 11 ++++++++--- drivers/net/wireless/ath/ath10k/coredump.h | 7 +++++++ 3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 2f9be182fbfbb..64c7145b51a2e 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2690,9 +2690,16 @@ static int ath10k_core_copy_target_iram(struct ath10k *ar) int i, ret; u32 len, remaining_len;
- hw_mem = ath10k_coredump_get_mem_layout(ar); + /* copy target iram feature must work also when + * ATH10K_FW_CRASH_DUMP_RAM_DATA is disabled, so + * _ath10k_coredump_get_mem_layout() to accomplist that + */ + hw_mem = _ath10k_coredump_get_mem_layout(ar); if (!hw_mem) - return -ENOMEM; + /* if CONFIG_DEV_COREDUMP is disabled we get NULL, then + * just silently disable the feature by doing nothing + */ + return 0;
for (i = 0; i < hw_mem->region_table.size; i++) { tmp = &hw_mem->region_table.regions[i]; diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c index 7eb72290a925c..55e7e11d06d94 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.c +++ b/drivers/net/wireless/ath/ath10k/coredump.c @@ -1447,11 +1447,17 @@ static u32 ath10k_coredump_get_ramdump_size(struct ath10k *ar)
const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar) { - int i; - if (!test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) return NULL;
+ return _ath10k_coredump_get_mem_layout(ar); +} +EXPORT_SYMBOL(ath10k_coredump_get_mem_layout); + +const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar) +{ + int i; + if (WARN_ON(ar->target_version == 0)) return NULL;
@@ -1464,7 +1470,6 @@ const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k
return NULL; } -EXPORT_SYMBOL(ath10k_coredump_get_mem_layout);
struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) { diff --git a/drivers/net/wireless/ath/ath10k/coredump.h b/drivers/net/wireless/ath/ath10k/coredump.h index 42404e246e0e9..240d705150888 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.h +++ b/drivers/net/wireless/ath/ath10k/coredump.h @@ -176,6 +176,7 @@ int ath10k_coredump_register(struct ath10k *ar); void ath10k_coredump_unregister(struct ath10k *ar); void ath10k_coredump_destroy(struct ath10k *ar);
+const struct ath10k_hw_mem_layout *_ath10k_coredump_get_mem_layout(struct ath10k *ar); const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k *ar);
#else /* CONFIG_DEV_COREDUMP */ @@ -214,6 +215,12 @@ ath10k_coredump_get_mem_layout(struct ath10k *ar) return NULL; }
+static inline const struct ath10k_hw_mem_layout * +_ath10k_coredump_get_mem_layout(struct ath10k *ar) +{ + return NULL; +} + #endif /* CONFIG_DEV_COREDUMP */
#endif /* _COREDUMP_H_ */
From: Michael Schmitz schmitzmic@gmail.com
[ Upstream commit d28e4dff085c5a87025c9a0a85fb798bd8e9ca17 ]
As it turns out, my earlier patch in commit 86d46fdaa12a (block: ataflop: fix breakage introduced at blk-mq refactoring) was incomplete. This patch fixes any remaining issues found during more testing and code review.
Requests exceeding 4 k are handled in 4k segments but __blk_mq_end_request() is never called on these (still sectors outstanding on the request). With redo_fd_request() removed, there is no provision to kick off processing of the next segment, causing requests exceeding 4k to hang. (By setting /sys/block/fd0/queue/max_sectors_k <= 4 as workaround, this behaviour can be avoided).
Instead of reintroducing redo_fd_request(), requeue the remainder of the request by calling blk_mq_requeue_request() on incomplete requests (i.e. when blk_update_request() still returns true), and rely on the block layer to queue the residual as new request.
Both error handling and formatting needs to release the ST-DMA lock, so call finish_fdc() on these (this was previously handled by redo_fd_request()). finish_fdc() may be called legitimately without the ST-DMA lock held - make sure we only release the lock if we actually held it. In a similar way, early exit due to errors in ataflop_queue_rq() must release the lock.
After minor errors, fd_error sets up to recalibrate the drive but never re-runs the current operation (another task handled by redo_fd_request() before). Call do_fd_action() to get the next steps (seek, retry read/write) underway.
Signed-off-by: Michael Schmitz schmitzmic@gmail.com Fixes: 6ec3938cff95f (ataflop: convert to blk-mq) CC: linux-block@vger.kernel.org Link: https://lore.kernel.org/r/20211024002013.9332-1-schmitzmic@gmail.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ataflop.c | 45 +++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index bbb64331cf8f4..4947e41f89b7d 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -456,10 +456,20 @@ static DEFINE_TIMER(fd_timer, check_change); static void fd_end_request_cur(blk_status_t err) { + DPRINT(("fd_end_request_cur(), bytes %d of %d\n", + blk_rq_cur_bytes(fd_request), + blk_rq_bytes(fd_request))); + if (!blk_update_request(fd_request, err, blk_rq_cur_bytes(fd_request))) { + DPRINT(("calling __blk_mq_end_request()\n")); __blk_mq_end_request(fd_request, err); fd_request = NULL; + } else { + /* requeue rest of request */ + DPRINT(("calling blk_mq_requeue_request()\n")); + blk_mq_requeue_request(fd_request, true); + fd_request = NULL; } }
@@ -697,12 +707,21 @@ static void fd_error( void ) if (fd_request->error_count >= MAX_ERRORS) { printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive ); fd_end_request_cur(BLK_STS_IOERR); + finish_fdc(); + return; } else if (fd_request->error_count == RECALIBRATE_ERRORS) { printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive ); if (SelectedDrive != -1) SUD.track = -1; } + /* need to re-run request to recalibrate */ + atari_disable_irq( IRQ_MFP_FDC ); + + setup_req_params( SelectedDrive ); + do_fd_action( SelectedDrive ); + + atari_enable_irq( IRQ_MFP_FDC ); }
@@ -729,8 +748,10 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) if (type) { type--; if (type >= NUM_DISK_MINORS || - minor2disktype[type].drive_types > DriveType) + minor2disktype[type].drive_types > DriveType) { + finish_fdc(); return -EINVAL; + } }
q = unit[drive].disk[type]->queue; @@ -748,6 +769,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) }
if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { + finish_fdc(); ret = -EINVAL; goto out; } @@ -788,6 +810,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc)
wait_for_completion(&format_wait);
+ finish_fdc(); ret = FormatError ? -EIO : 0; out: blk_mq_unquiesce_queue(q); @@ -822,6 +845,7 @@ static void do_fd_action( int drive ) else { /* all sectors finished */ fd_end_request_cur(BLK_STS_OK); + finish_fdc(); return; } } @@ -1225,8 +1249,8 @@ static void fd_rwsec_done1(int status) } else { /* all sectors finished */ - finish_fdc(); fd_end_request_cur(BLK_STS_OK); + finish_fdc(); } return;
@@ -1348,7 +1372,7 @@ static void fd_times_out(struct timer_list *unused)
static void finish_fdc( void ) { - if (!NeedSeek) { + if (!NeedSeek || !stdma_is_locked_by(floppy_irq)) { finish_fdc_done( 0 ); } else { @@ -1383,7 +1407,8 @@ static void finish_fdc_done( int dummy ) start_motor_off_timer();
local_irq_save(flags); - stdma_release(); + if (stdma_is_locked_by(floppy_irq)) + stdma_release(); local_irq_restore(flags);
DPRINT(("finish_fdc() finished\n")); @@ -1480,7 +1505,9 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, int drive = floppy - unit; int type = floppy->type;
- DPRINT(("Queue request: drive %d type %d last %d\n", drive, type, bd->last)); + DPRINT(("Queue request: drive %d type %d sectors %d of %d last %d\n", + drive, type, blk_rq_cur_sectors(bd->rq), + blk_rq_sectors(bd->rq), bd->last));
spin_lock_irq(&ataflop_lock); if (fd_request) { @@ -1502,6 +1529,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, /* drive not connected */ printk(KERN_ERR "Unknown Device: fd%d\n", drive ); fd_end_request_cur(BLK_STS_IOERR); + stdma_release(); goto out; } @@ -1518,11 +1546,13 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, if (--type >= NUM_DISK_MINORS) { printk(KERN_WARNING "fd%d: invalid disk format", drive ); fd_end_request_cur(BLK_STS_IOERR); + stdma_release(); goto out; } if (minor2disktype[type].drive_types > DriveType) { printk(KERN_WARNING "fd%d: unsupported disk format", drive ); fd_end_request_cur(BLK_STS_IOERR); + stdma_release(); goto out; } type = minor2disktype[type].index; @@ -1623,6 +1653,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, /* what if type > 0 here? Overwrite specified entry ? */ if (type) { /* refuse to re-set a predefined type for now */ + finish_fdc(); return -EINVAL; }
@@ -1690,8 +1721,10 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode,
/* sanity check */ if (setprm.track != dtp->blocks/dtp->spt/2 || - setprm.head != 2) + setprm.head != 2) { + finish_fdc(); return -EINVAL; + }
UDT = dtp; set_capacity(disk, UDT->blocks);
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 0c9d338c8443b06da8e8d3bfce824c5ea6d3488f ]
Our test reports a null pointer dereference:
[ 168.534653] ================================================================== [ 168.535614] Disabling lock debugging due to kernel taint [ 168.536346] BUG: kernel NULL pointer dereference, address: 0000000000000008 [ 168.537274] #PF: supervisor read access in kernel mode [ 168.537964] #PF: error_code(0x0000) - not-present page [ 168.538667] PGD 0 P4D 0 [ 168.539025] Oops: 0000 [#1] PREEMPT SMP KASAN [ 168.539656] CPU: 13 PID: 759 Comm: bash Tainted: G B 5.15.0-rc2-next-202100 [ 168.540954] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ?-20190727_0738364 [ 168.542736] RIP: 0010:bfq_pd_init+0x88/0x1e0 [ 168.543318] Code: 98 00 00 00 e8 c9 e4 5b ff 4c 8b 65 00 49 8d 7c 24 08 e8 bb e4 5b ff 4d0 [ 168.545803] RSP: 0018:ffff88817095f9c0 EFLAGS: 00010002 [ 168.546497] RAX: 0000000000000001 RBX: ffff888101a1c000 RCX: 0000000000000000 [ 168.547438] RDX: 0000000000000003 RSI: 0000000000000002 RDI: ffff888106553428 [ 168.548402] RBP: ffff888106553400 R08: ffffffff961bcaf4 R09: 0000000000000001 [ 168.549365] R10: ffffffffa2e16c27 R11: fffffbfff45c2d84 R12: 0000000000000000 [ 168.550291] R13: ffff888101a1c098 R14: ffff88810c7a08c8 R15: ffffffffa55541a0 [ 168.551221] FS: 00007fac75227700(0000) GS:ffff88839ba80000(0000) knlGS:0000000000000000 [ 168.552278] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 168.553040] CR2: 0000000000000008 CR3: 0000000165ce7000 CR4: 00000000000006e0 [ 168.554000] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 168.554929] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 168.555888] Call Trace: [ 168.556221] <TASK> [ 168.556510] blkg_create+0x1c0/0x8c0 [ 168.556989] blkg_conf_prep+0x574/0x650 [ 168.557502] ? stack_trace_save+0x99/0xd0 [ 168.558033] ? blkcg_conf_open_bdev+0x1b0/0x1b0 [ 168.558629] tg_set_conf.constprop.0+0xb9/0x280 [ 168.559231] ? kasan_set_track+0x29/0x40 [ 168.559758] ? kasan_set_free_info+0x30/0x60 [ 168.560344] ? tg_set_limit+0xae0/0xae0 [ 168.560853] ? do_sys_openat2+0x33b/0x640 [ 168.561383] ? do_sys_open+0xa2/0x100 [ 168.561877] ? __x64_sys_open+0x4e/0x60 [ 168.562383] ? __kasan_check_write+0x20/0x30 [ 168.562951] ? copyin+0x48/0x70 [ 168.563390] ? _copy_from_iter+0x234/0x9e0 [ 168.563948] tg_set_conf_u64+0x17/0x20 [ 168.564467] cgroup_file_write+0x1ad/0x380 [ 168.565014] ? cgroup_file_poll+0x80/0x80 [ 168.565568] ? __mutex_lock_slowpath+0x30/0x30 [ 168.566165] ? pgd_free+0x100/0x160 [ 168.566649] kernfs_fop_write_iter+0x21d/0x340 [ 168.567246] ? cgroup_file_poll+0x80/0x80 [ 168.567796] new_sync_write+0x29f/0x3c0 [ 168.568314] ? new_sync_read+0x410/0x410 [ 168.568840] ? __handle_mm_fault+0x1c97/0x2d80 [ 168.569425] ? copy_page_range+0x2b10/0x2b10 [ 168.570007] ? _raw_read_lock_bh+0xa0/0xa0 [ 168.570622] vfs_write+0x46e/0x630 [ 168.571091] ksys_write+0xcd/0x1e0 [ 168.571563] ? __x64_sys_read+0x60/0x60 [ 168.572081] ? __kasan_check_write+0x20/0x30 [ 168.572659] ? do_user_addr_fault+0x446/0xff0 [ 168.573264] __x64_sys_write+0x46/0x60 [ 168.573774] do_syscall_64+0x35/0x80 [ 168.574264] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 168.574960] RIP: 0033:0x7fac74915130 [ 168.575456] Code: 73 01 c3 48 8b 0d 58 ed 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 444 [ 168.577969] RSP: 002b:00007ffc3080e288 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 168.578986] RAX: ffffffffffffffda RBX: 0000000000000009 RCX: 00007fac74915130 [ 168.579937] RDX: 0000000000000009 RSI: 000056007669f080 RDI: 0000000000000001 [ 168.580884] RBP: 000056007669f080 R08: 000000000000000a R09: 00007fac75227700 [ 168.581841] R10: 000056007655c8f0 R11: 0000000000000246 R12: 0000000000000009 [ 168.582796] R13: 0000000000000001 R14: 00007fac74be55e0 R15: 00007fac74be08c0 [ 168.583757] </TASK> [ 168.584063] Modules linked in: [ 168.584494] CR2: 0000000000000008 [ 168.584964] ---[ end trace 2475611ad0f77a1a ]---
This is because blkg_alloc() is called from blkg_conf_prep() without holding 'q->queue_lock', and elevator is exited before blkg_create():
thread 1 thread 2 blkg_conf_prep spin_lock_irq(&q->queue_lock); blkg_lookup_check -> return NULL spin_unlock_irq(&q->queue_lock);
blkg_alloc blkcg_policy_enabled -> true pd = ->pd_alloc_fn blkg->pd[i] = pd blk_mq_exit_sched bfq_exit_queue blkcg_deactivate_policy spin_lock_irq(&q->queue_lock); __clear_bit(pol->plid, q->blkcg_pols); spin_unlock_irq(&q->queue_lock); q->elevator = NULL; spin_lock_irq(&q->queue_lock); blkg_create if (blkg->pd[i]) ->pd_init_fn -> q->elevator is NULL spin_unlock_irq(&q->queue_lock);
Because blkcg_deactivate_policy() requires queue to be frozen, we can grab q_usage_counter to synchoronize blkg_conf_prep() against blkcg_deactivate_policy().
Fixes: e21b7a0b9887 ("block, bfq: add full hierarchical scheduling and cgroups support") Signed-off-by: Yu Kuai yukuai3@huawei.com Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20211020014036.2141723-1-yukuai3@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-cgroup.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 9a1c5839dd469..ebff1af402e5b 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -633,6 +633,14 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
q = bdev->bd_disk->queue;
+ /* + * blkcg_deactivate_policy() requires queue to be frozen, we can grab + * q_usage_counter to prevent concurrent with blkcg_deactivate_policy(). + */ + ret = blk_queue_enter(q, 0); + if (ret) + return ret; + rcu_read_lock(); spin_lock_irq(&q->queue_lock);
@@ -702,6 +710,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, goto success; } success: + blk_queue_exit(q); ctx->bdev = bdev; ctx->blkg = blkg; ctx->body = input; @@ -714,6 +723,7 @@ fail_unlock: rcu_read_unlock(); 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: Andrii Nakryiko andrii@kernel.org
[ Upstream commit de5d0dcef602de39070c31c7e56c58249c56ba37 ]
Fix instruction index validity check which has off-by-one error.
Fixes: 3ee4f5335511 ("libbpf: Split bpf_core_apply_relo() into bpf_program independent helper.") Signed-off-by: Andrii Nakryiko andrii@kernel.org Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20211025224531.1088894-2-andrii@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 51180f300d2e1..7145463a4a562 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -5138,7 +5138,7 @@ static int bpf_core_apply_relo(struct bpf_program *prog, * relocated, so it's enough to just subtract in-section offset */ insn_idx = insn_idx - prog->sec_insn_off; - if (insn_idx > prog->insns_cnt) + if (insn_idx >= prog->insns_cnt) return -EINVAL; insn = &prog->insns[insn_idx];
From: Hao Wu hao.wu@rubrik.com
[ Upstream commit 79ca6f74dae067681a779fd573c2eb59649989bc ]
The Atmel TPM 1.2 chips crash with error `tpm_try_transmit: send(): error -62` since kernel 4.14. It is observed from the kernel log after running `tpm_sealdata -z`. The error thrown from the command is as follows ``` $ tpm_sealdata -z Tspi_Key_LoadKey failed: 0x00001087 - layer=tddl, code=0087 (135), I/O error ```
The issue was reproduced with the following Atmel TPM chip: ``` $ tpm_version T0 TPM 1.2 Version Info: Chip Version: 1.2.66.1 Spec Level: 2 Errata Revision: 3 TPM Vendor ID: ATML TPM Version: 01010000 Manufacturer Info: 41544d4c ```
The root cause of the issue is due to the TPM calls to msleep() were replaced with usleep_range() [1], which reduces the actual timeout. Via experiments, it is observed that the original msleep(5) actually sleeps for 15ms. Because of a known timeout issue in Atmel TPM 1.2 chip, the shorter timeout than 15ms can cause the error described above.
A few further changes in kernel 4.16 [2] and 4.18 [3, 4] further reduced the timeout to less than 1ms. With experiments, the problematic timeout in the latest kernel is the one for `wait_for_tpm_stat`.
To fix it, the patch reverts the timeout of `wait_for_tpm_stat` to 15ms for all Atmel TPM 1.2 chips, but leave it untouched for Ateml TPM 2.0 chip, and chips from other vendors. As explained above, the chosen 15ms timeout is the actual timeout before this issue introduced, thus the old value is used here. Particularly, TPM_ATML_TIMEOUT_WAIT_STAT_MIN is set to 14700us, TPM_ATML_TIMEOUT_WAIT_STAT_MIN is set to 15000us according to the existing TPM_TIMEOUT_RANGE_US (300us). The fixed has been tested in the system with the affected Atmel chip with no issues observed after boot up.
[1] 9f3fc7bcddcb tpm: replace msleep() with usleep_range() in TPM 1.2/2.0 generic drivers [2] cf151a9a44d5 tpm: reduce tpm polling delay in tpm_tis_core [3] 59f5a6b07f64 tpm: reduce poll sleep time in tpm_transmit() [4] 424eaf910c32 tpm: reduce polling time to usecs for even finer granularity
Fixes: 9f3fc7bcddcb ("tpm: replace msleep() with usleep_range() in TPM 1.2/2.0 generic drivers") Link: https://patchwork.kernel.org/project/linux-integrity/patch/20200926223150.10... Signed-off-by: Hao Wu hao.wu@rubrik.com Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_core.c | 26 ++++++++++++++++++-------- drivers/char/tpm/tpm_tis_core.h | 4 ++++ include/linux/tpm.h | 1 + 3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 69579efb247b3..b2659a4c40168 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -48,6 +48,7 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, wait_queue_head_t *queue, bool check_cancel) { + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); unsigned long stop; long rc; u8 status; @@ -80,8 +81,8 @@ again: } } else { do { - usleep_range(TPM_TIMEOUT_USECS_MIN, - TPM_TIMEOUT_USECS_MAX); + usleep_range(priv->timeout_min, + priv->timeout_max); status = chip->ops->status(chip); if ((status & mask) == mask) return 0; @@ -945,7 +946,22 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX); chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX); chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX); + priv->timeout_min = TPM_TIMEOUT_USECS_MIN; + priv->timeout_max = TPM_TIMEOUT_USECS_MAX; priv->phy_ops = phy_ops; + + rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); + if (rc < 0) + goto out_err; + + priv->manufacturer_id = vendor; + + if (priv->manufacturer_id == TPM_VID_ATML && + !(chip->flags & TPM_CHIP_FLAG_TPM2)) { + priv->timeout_min = TIS_TIMEOUT_MIN_ATML; + priv->timeout_max = TIS_TIMEOUT_MAX_ATML; + } + dev_set_drvdata(&chip->dev, priv);
if (is_bsw()) { @@ -988,12 +1004,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (rc) goto out_err;
- rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); - if (rc < 0) - goto out_err; - - priv->manufacturer_id = vendor; - rc = tpm_tis_read8(priv, TPM_RID(0), &rid); if (rc < 0) goto out_err; diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index b2a3c6c72882d..3be24f221e32a 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -54,6 +54,8 @@ enum tis_defaults { TIS_MEM_LEN = 0x5000, TIS_SHORT_TIMEOUT = 750, /* ms */ TIS_LONG_TIMEOUT = 2000, /* 2 sec */ + TIS_TIMEOUT_MIN_ATML = 14700, /* usecs */ + TIS_TIMEOUT_MAX_ATML = 15000, /* usecs */ };
/* Some timeout values are needed before it is known whether the chip is @@ -98,6 +100,8 @@ struct tpm_tis_data { wait_queue_head_t read_queue; const struct tpm_tis_phy_ops *phy_ops; unsigned short rng_quality; + unsigned int timeout_min; /* usecs */ + unsigned int timeout_max; /* usecs */ };
struct tpm_tis_phy_ops { diff --git a/include/linux/tpm.h b/include/linux/tpm.h index aa11fe323c56b..12d827734686d 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -269,6 +269,7 @@ enum tpm2_cc_attrs { #define TPM_VID_INTEL 0x8086 #define TPM_VID_WINBOND 0x1050 #define TPM_VID_STM 0x104A +#define TPM_VID_ATML 0x1114
enum tpm_chip_flags { TPM_CHIP_FLAG_TPM2 = BIT(1),
From: Mark Brown broonie@kernel.org
[ Upstream commit 7eba41fe8c7bb01ff3d4b757bd622375792bc720 ]
In commit c46ed2281bbe ("tpm_tis_spi: add missing SPI device ID entries") we added SPI IDs for all the DT aliases to handle the fact that we always use SPI modaliases to load modules even when probed via DT however the mentioned commit missed that the SPI and OF device ID entries did not match and were different and so DT nodes with compatible "tcg,tpm_tis-spi" will not match. Add an extra ID for tpm_tis-spi rather than just fix the existing one since what's currently there is going to be better for anyone actually using SPI IDs to instantiate.
Fixes: c46ed2281bbe ("tpm_tis_spi: add missing SPI device ID entries") Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Reviewed-by: Jarkko Sakkinen jarkko@kernel.org Reviewed-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Jarkko Sakkinen jarkko@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/tpm/tpm_tis_spi_main.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c index 54584b4b00d19..aaa59a00eeaef 100644 --- a/drivers/char/tpm/tpm_tis_spi_main.c +++ b/drivers/char/tpm/tpm_tis_spi_main.c @@ -267,6 +267,7 @@ static const struct spi_device_id tpm_tis_spi_id[] = { { "st33htpm-spi", (unsigned long)tpm_tis_spi_probe }, { "slb9670", (unsigned long)tpm_tis_spi_probe }, { "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe }, + { "tpm_tis-spi", (unsigned long)tpm_tis_spi_probe }, { "cr50", (unsigned long)cr50_spi_probe }, {} };
From: Ilya Leoshkevich iii@linux.ibm.com
[ Upstream commit 45f2bebc8079788f62f22d9e8b2819afb1789d7b ]
__BYTE_ORDER is supposed to be defined by a libc, and __BYTE_ORDER__ - by a compiler. bpf_core_read.h checks __BYTE_ORDER == __LITTLE_ENDIAN, which is true if neither are defined, leading to incorrect behavior on big-endian hosts if libc headers are not included, which is often the case.
Fixes: ee26dade0e3b ("libbpf: Add support for relocatable bitfields") Signed-off-by: Ilya Leoshkevich iii@linux.ibm.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20211026010831.748682-2-iii@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/bpf_core_read.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf_core_read.h b/tools/lib/bpf/bpf_core_read.h index 09ebe3db5f2f8..e4aa9996a5501 100644 --- a/tools/lib/bpf/bpf_core_read.h +++ b/tools/lib/bpf/bpf_core_read.h @@ -40,7 +40,7 @@ enum bpf_enum_value_kind { #define __CORE_RELO(src, field, info) \ __builtin_preserve_field_info((src)->field, BPF_FIELD_##info)
-#if __BYTE_ORDER == __LITTLE_ENDIAN +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \ bpf_probe_read_kernel( \ (void *)dst, \
From: Jon Maxwell jmaxwell37@gmail.com
[ Upstream commit cf12e6f9124629b18a6182deefc0315f0a73a199 ]
v1: Implement a more general statement as recommended by Eric Dumazet. The sequence number will be advanced, so this check will fix the FIN case and other cases.
A customer reported sockets stuck in the CLOSING state. A Vmcore revealed that the write_queue was not empty as determined by tcp_write_queue_empty() but the sk_buff containing the FIN flag had been freed and the socket was zombied in that state. Corresponding pcaps show no FIN from the Linux kernel on the wire.
Some instrumentation was added to the kernel and it was found that there is a timing window where tcp_sendmsg() can run after tcp_send_fin().
tcp_sendmsg() will hit an error, for example:
1269 ▹ if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))↩ 1270 ▹ ▹ goto do_error;↩
tcp_remove_empty_skb() will then free the FIN sk_buff as "skb->len == 0". The TCP socket is now wedged in the FIN-WAIT-1 state because the FIN is never sent.
If the other side sends a FIN packet the socket will transition to CLOSING and remain that way until the system is rebooted.
Fix this by checking for the FIN flag in the sk_buff and don't free it if that is the case. Testing confirmed that fixed the issue.
Fixes: fdfc5c8594c2 ("tcp: remove empty skb from write queue in error cases") Signed-off-by: Jon Maxwell jmaxwell37@gmail.com Reported-by: Monir Zouaoui Monir.Zouaoui@mail.schwarz Reported-by: Simon Stier simon.stier@mail.schwarz Reviewed-by: Eric Dumazet edumazet@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index d13050b68045b..8affba5909bdf 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -952,7 +952,7 @@ int tcp_send_mss(struct sock *sk, int *size_goal, int flags) */ void tcp_remove_empty_skb(struct sock *sk, struct sk_buff *skb) { - if (skb && !skb->len) { + if (skb && TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq) { tcp_unlink_write_queue(skb, sk); if (tcp_write_queue_empty(sk)) tcp_chrono_stop(sk, TCP_CHRONO_BUSY);
From: Mathieu Desnoyers mathieu.desnoyers@efficios.com
[ Upstream commit 3c20bd3af535d64771b193bb4dd41ed662c464ce ]
trace_boot_init_histograms misses NULL pointer checks for kstrdup failure.
Link: https://lkml.kernel.org/r/20211015195550.22742-1-mathieu.desnoyers@efficios....
Fixes: 64dc7f6958ef5 ("tracing/boot: Show correct histogram error command") Acked-by: Masami Hiramatsu mhiramat@kernel.org Signed-off-by: Mathieu Desnoyers mathieu.desnoyers@efficios.com Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/trace_boot.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c index 8d252f63cd784..0580287d7a0d1 100644 --- a/kernel/trace/trace_boot.c +++ b/kernel/trace/trace_boot.c @@ -430,6 +430,8 @@ trace_boot_init_histograms(struct trace_event_file *file, /* All digit started node should be instances. */ if (trace_boot_compose_hist_cmd(node, buf, size) == 0) { tmp = kstrdup(buf, GFP_KERNEL); + if (!tmp) + return; if (trigger_process_regex(file, buf) < 0) pr_err("Failed to apply hist trigger: %s\n", tmp); kfree(tmp); @@ -439,6 +441,8 @@ trace_boot_init_histograms(struct trace_event_file *file, if (xbc_node_find_subkey(hnode, "keys")) { if (trace_boot_compose_hist_cmd(hnode, buf, size) == 0) { tmp = kstrdup(buf, GFP_KERNEL); + if (!tmp) + return; if (trigger_process_regex(file, buf) < 0) pr_err("Failed to apply hist trigger: %s\n", tmp); kfree(tmp);
From: Zhang Rui rui.zhang@intel.com
[ Upstream commit c72bcf0ab87a92634e58af62e89af0f40dfd0b88 ]
Fix a problem in active mode that cpu->pstate.turbo_freq is initialized only if HWP-to-frequency scaling factor is refined.
In passive mode, this problem is not exposed, because cpu->pstate.turbo_freq is set again, later in intel_cpufreq_cpu_init()->intel_pstate_get_hwp_cap().
Fixes: eb3693f0521e ("cpufreq: intel_pstate: hybrid: CPU-specific scaling factor") Signed-off-by: Zhang Rui rui.zhang@intel.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/intel_pstate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 8c176b7dae415..fc7a429f22d33 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -537,7 +537,8 @@ static void intel_pstate_hybrid_hwp_adjust(struct cpudata *cpu) * scaling factor is too high, so recompute it to make the HWP_CAP * highest performance correspond to the maximum turbo frequency. */ - if (turbo_freq < cpu->pstate.turbo_pstate * scaling) { + cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * scaling; + if (turbo_freq < cpu->pstate.turbo_freq) { cpu->pstate.turbo_freq = turbo_freq; scaling = DIV_ROUND_UP(turbo_freq, cpu->pstate.turbo_pstate); cpu->pstate.scaling = scaling;
From: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com
[ Upstream commit 0b0a281ed7001d4c4f4c47bdc84680c4997761ca ]
rpcif_sw_init() can fail so make sure we check the return value of it and on error exit rpcif_spi_probe() callback with error code.
Fixes: eb8d6d464a27 ("spi: add Renesas RPC-IF driver") Signed-off-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com Reviewed-by: Biju Das biju.das.jz@bp.renesas.com Reviewed-by: Wolfram Sang wsa+renesas@sang-engineering.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20211025205631.21151-4-prabhakar.mahadev-lad.rj@bp... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-rpc-if.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c index c53138ce00309..83796a4ead34a 100644 --- a/drivers/spi/spi-rpc-if.c +++ b/drivers/spi/spi-rpc-if.c @@ -139,7 +139,9 @@ static int rpcif_spi_probe(struct platform_device *pdev) return -ENOMEM;
rpc = spi_controller_get_devdata(ctlr); - rpcif_sw_init(rpc, parent); + error = rpcif_sw_init(rpc, parent); + if (error) + return error;
platform_set_drvdata(pdev, ctlr);
From: Kees Cook keescook@chromium.org
[ Upstream commit 42a20f86dc19f9282d974df0ba4d226c865ab9dd ]
Having a stable wchan means the process must be blocked and for it to stay that way while performing stack unwinding.
Suggested-by: Peter Zijlstra peterz@infradead.org Signed-off-by: Kees Cook keescook@chromium.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Acked-by: Geert Uytterhoeven geert@linux-m68k.org Acked-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk [arm] Tested-by: Mark Rutland mark.rutland@arm.com [arm64] Link: https://lkml.kernel.org/r/20211008111626.332092234@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/alpha/include/asm/processor.h | 2 +- arch/alpha/kernel/process.c | 5 ++--- arch/arc/include/asm/processor.h | 2 +- arch/arc/kernel/stacktrace.c | 4 ++-- arch/arm/include/asm/processor.h | 2 +- arch/arm/kernel/process.c | 4 +--- arch/arm64/include/asm/processor.h | 2 +- arch/arm64/kernel/process.c | 4 +--- arch/csky/include/asm/processor.h | 2 +- arch/csky/kernel/stacktrace.c | 5 ++--- arch/h8300/include/asm/processor.h | 2 +- arch/h8300/kernel/process.c | 5 +---- arch/hexagon/include/asm/processor.h | 2 +- arch/hexagon/kernel/process.c | 4 +--- arch/ia64/include/asm/processor.h | 2 +- arch/ia64/kernel/process.c | 5 +---- arch/m68k/include/asm/processor.h | 2 +- arch/m68k/kernel/process.c | 4 +--- arch/microblaze/include/asm/processor.h | 2 +- arch/microblaze/kernel/process.c | 2 +- arch/mips/include/asm/processor.h | 2 +- arch/mips/kernel/process.c | 8 +++----- arch/nds32/include/asm/processor.h | 2 +- arch/nds32/kernel/process.c | 7 +------ arch/nios2/include/asm/processor.h | 2 +- arch/nios2/kernel/process.c | 5 +---- arch/openrisc/include/asm/processor.h | 2 +- arch/openrisc/kernel/process.c | 2 +- arch/parisc/include/asm/processor.h | 2 +- arch/parisc/kernel/process.c | 5 +---- arch/powerpc/include/asm/processor.h | 2 +- arch/powerpc/kernel/process.c | 9 +++------ arch/riscv/include/asm/processor.h | 2 +- arch/riscv/kernel/stacktrace.c | 12 +++++------- arch/s390/include/asm/processor.h | 2 +- arch/s390/kernel/process.c | 4 ++-- arch/sh/include/asm/processor_32.h | 2 +- arch/sh/kernel/process_32.c | 5 +---- arch/sparc/include/asm/processor_32.h | 2 +- arch/sparc/include/asm/processor_64.h | 2 +- arch/sparc/kernel/process_32.c | 5 +---- arch/sparc/kernel/process_64.c | 5 +---- arch/um/include/asm/processor-generic.h | 2 +- arch/um/kernel/process.c | 5 +---- arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/process.c | 5 +---- arch/xtensa/include/asm/processor.h | 2 +- arch/xtensa/kernel/process.c | 5 +---- include/linux/sched.h | 1 + kernel/sched/core.c | 19 +++++++++++++++++++ 50 files changed, 80 insertions(+), 112 deletions(-)
diff --git a/arch/alpha/include/asm/processor.h b/arch/alpha/include/asm/processor.h index 6100431da07a3..090499c99c1c1 100644 --- a/arch/alpha/include/asm/processor.h +++ b/arch/alpha/include/asm/processor.h @@ -42,7 +42,7 @@ extern void start_thread(struct pt_regs *, unsigned long, unsigned long); struct task_struct; extern void release_thread(struct task_struct *);
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index a5123ea426ce5..5f8527081da92 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -376,12 +376,11 @@ thread_saved_pc(struct task_struct *t) }
unsigned long -get_wchan(struct task_struct *p) +__get_wchan(struct task_struct *p) { unsigned long schedule_frame; unsigned long pc; - if (!p || p == current || task_is_running(p)) - return 0; + /* * This one depends on the frame size of schedule(). Do a * "disass schedule" in gdb to find the frame size. Also, the diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h index f28afcf5c6d10..54db9d7bb562d 100644 --- a/arch/arc/include/asm/processor.h +++ b/arch/arc/include/asm/processor.h @@ -70,7 +70,7 @@ struct task_struct; extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp);
-extern unsigned int get_wchan(struct task_struct *p); +extern unsigned int __get_wchan(struct task_struct *p);
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index c376ff3147e7b..5372dc04e7847 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -15,7 +15,7 @@ * = specifics of data structs where trace is saved(CONFIG_STACKTRACE etc) * * vineetg: March 2009 - * -Implemented correct versions of thread_saved_pc() and get_wchan() + * -Implemented correct versions of thread_saved_pc() and __get_wchan() * * rajeshwarr: 2008 * -Initial implementation @@ -248,7 +248,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) * Of course just returning schedule( ) would be pointless so unwind until * the function is not in schedular code */ -unsigned int get_wchan(struct task_struct *tsk) +unsigned int __get_wchan(struct task_struct *tsk) { return arc_unwind_core(tsk, NULL, __get_first_nonsched, NULL); } diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 9e6b972863077..6af68edfa53ab 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -84,7 +84,7 @@ struct task_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *);
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 0e2d3051741ed..96f577e59595f 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -276,13 +276,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, return 0; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { struct stackframe frame; unsigned long stack_page; int count = 0; - if (!p || p == current || task_is_running(p)) - return 0;
frame.fp = thread_saved_fp(p); frame.sp = thread_saved_sp(p); diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index ee2bdc1b9f5bb..55ca034238eae 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -257,7 +257,7 @@ struct task_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *);
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
void update_sctlr_el1(u64 sctlr);
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 40adb8cdbf5af..aacf2f5559a8b 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -528,13 +528,11 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, return last; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { struct stackframe frame; unsigned long stack_page, ret = 0; int count = 0; - if (!p || p == current || task_is_running(p)) - return 0;
stack_page = (unsigned long)try_get_task_stack(p); if (!stack_page) diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h index 9e933021fe8e0..817dd60ff152d 100644 --- a/arch/csky/include/asm/processor.h +++ b/arch/csky/include/asm/processor.h @@ -81,7 +81,7 @@ static inline void release_thread(struct task_struct *dead_task)
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->usp) diff --git a/arch/csky/kernel/stacktrace.c b/arch/csky/kernel/stacktrace.c index 1b280ef080045..9f78f5d215117 100644 --- a/arch/csky/kernel/stacktrace.c +++ b/arch/csky/kernel/stacktrace.c @@ -111,12 +111,11 @@ static bool save_wchan(unsigned long pc, void *arg) return false; }
-unsigned long get_wchan(struct task_struct *task) +unsigned long __get_wchan(struct task_struct *task) { unsigned long pc = 0;
- if (likely(task && task != current && !task_is_running(task))) - walk_stackframe(task, NULL, save_wchan, &pc); + walk_stackframe(task, NULL, save_wchan, &pc); return pc; }
diff --git a/arch/h8300/include/asm/processor.h b/arch/h8300/include/asm/processor.h index a060b41b2d31c..141a23eb62b74 100644 --- a/arch/h8300/include/asm/processor.h +++ b/arch/h8300/include/asm/processor.h @@ -105,7 +105,7 @@ static inline void release_thread(struct task_struct *dead_task) { }
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) \ ({ \ diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 2ac27e4248a46..8833fa4f5d516 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c @@ -128,15 +128,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, return 0; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long fp, pc; unsigned long stack_page; int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - stack_page = (unsigned long)p; fp = ((struct pt_regs *)p->thread.ksp)->er6; do { diff --git a/arch/hexagon/include/asm/processor.h b/arch/hexagon/include/asm/processor.h index 9f0cc99420bee..615f7e49968e6 100644 --- a/arch/hexagon/include/asm/processor.h +++ b/arch/hexagon/include/asm/processor.h @@ -64,7 +64,7 @@ struct thread_struct { extern void release_thread(struct task_struct *dead_task);
/* Get wait channel for task P. */ -extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
/* The following stuff is pretty HEXAGON specific. */
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index 6a6835fb42425..232dfd8956aa2 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -130,13 +130,11 @@ void flush_thread(void) * is an identification of the point at which the scheduler * was invoked by a blocked thread. */ -unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long fp, pc; unsigned long stack_page; int count = 0; - if (!p || p == current || task_is_running(p)) - return 0;
stack_page = (unsigned long)task_stack_page(p); fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp; diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h index 2d8bcdc27d7f8..45365c2ef5983 100644 --- a/arch/ia64/include/asm/processor.h +++ b/arch/ia64/include/asm/processor.h @@ -330,7 +330,7 @@ struct task_struct; #define release_thread(dead_task)
/* Get wait channel for task P. */ -extern unsigned long get_wchan (struct task_struct *p); +extern unsigned long __get_wchan (struct task_struct *p);
/* Return instruction pointer of blocked task TSK. */ #define KSTK_EIP(tsk) \ diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index e56d63f4abf9d..834df24a88f12 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -523,15 +523,12 @@ exit_thread (struct task_struct *tsk) }
unsigned long -get_wchan (struct task_struct *p) +__get_wchan (struct task_struct *p) { struct unw_frame_info info; unsigned long ip; int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - /* * Note: p may not be a blocked task (it could be current or * another process running on some other CPU. Rather than diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h index f4d82c619a5c4..ffeda9aa526a5 100644 --- a/arch/m68k/include/asm/processor.h +++ b/arch/m68k/include/asm/processor.h @@ -150,7 +150,7 @@ static inline void release_thread(struct task_struct *dead_task) { }
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) \ ({ \ diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index 1ab692b952cd6..a6030dbaa0891 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c @@ -263,13 +263,11 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) } EXPORT_SYMBOL(dump_fpu);
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long fp, pc; unsigned long stack_page; int count = 0; - if (!p || p == current || task_is_running(p)) - return 0;
stack_page = (unsigned long)task_stack_page(p); fp = ((struct switch_stack *)p->thread.ksp)->a6; diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 06c6e493590a2..7e9e92670df33 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -68,7 +68,7 @@ static inline void release_thread(struct task_struct *dead_task) { }
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
/* The size allocated for kernel stacks. This _must_ be a power of two! */ # define KERNEL_STACK_SIZE 0x2000 diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c index 62aa237180b67..5e2b91c1e8ced 100644 --- a/arch/microblaze/kernel/process.c +++ b/arch/microblaze/kernel/process.c @@ -112,7 +112,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg, return 0; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { /* TBD (used by procfs) */ return 0; diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 0c3550c82b726..252ed38ce8c5a 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -369,7 +369,7 @@ static inline void flush_thread(void) { }
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \ THREAD_SIZE - 32 - sizeof(struct pt_regs)) diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 95aa86fa60778..cbff1b974f882 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -511,7 +511,7 @@ static int __init frame_info_init(void)
/* * Without schedule() frame info, result given by - * thread_saved_pc() and get_wchan() are not reliable. + * thread_saved_pc() and __get_wchan() are not reliable. */ if (schedule_mfi.pc_offset < 0) printk("Can't analyze schedule() prologue at %p\n", schedule); @@ -652,9 +652,9 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, #endif
/* - * get_wchan - a maintenance nightmare^W^Wpain in the ass ... + * __get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ -unsigned long get_wchan(struct task_struct *task) +unsigned long __get_wchan(struct task_struct *task) { unsigned long pc = 0; #ifdef CONFIG_KALLSYMS @@ -662,8 +662,6 @@ unsigned long get_wchan(struct task_struct *task) unsigned long ra = 0; #endif
- if (!task || task == current || task_is_running(task)) - goto out; if (!task_stack_page(task)) goto out;
diff --git a/arch/nds32/include/asm/processor.h b/arch/nds32/include/asm/processor.h index b82369c7659d4..e6bfc74972bb3 100644 --- a/arch/nds32/include/asm/processor.h +++ b/arch/nds32/include/asm/processor.h @@ -83,7 +83,7 @@ extern struct task_struct *last_task_used_math; /* Prepare to copy thread state - unlazy all lazy status */ #define prepare_to_copy(tsk) do { } while (0)
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
diff --git a/arch/nds32/kernel/process.c b/arch/nds32/kernel/process.c index 391895b54d13c..49fab9e39cbff 100644 --- a/arch/nds32/kernel/process.c +++ b/arch/nds32/kernel/process.c @@ -233,15 +233,12 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)
EXPORT_SYMBOL(dump_fpu);
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long fp, lr; unsigned long stack_start, stack_end; int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - if (IS_ENABLED(CONFIG_FRAME_POINTER)) { stack_start = (unsigned long)end_of_stack(p); stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; @@ -258,5 +255,3 @@ unsigned long get_wchan(struct task_struct *p) } return 0; } - -EXPORT_SYMBOL(get_wchan); diff --git a/arch/nios2/include/asm/processor.h b/arch/nios2/include/asm/processor.h index 94bcb86f679f5..b8125dfbcad2d 100644 --- a/arch/nios2/include/asm/processor.h +++ b/arch/nios2/include/asm/processor.h @@ -69,7 +69,7 @@ static inline void release_thread(struct task_struct *dead_task) { }
-extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
#define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) diff --git a/arch/nios2/kernel/process.c b/arch/nios2/kernel/process.c index 9ff37ba2bb603..f8ea522a15880 100644 --- a/arch/nios2/kernel/process.c +++ b/arch/nios2/kernel/process.c @@ -217,15 +217,12 @@ void dump(struct pt_regs *fp) pr_emerg("\n\n"); }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long fp, pc; unsigned long stack_page; int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - stack_page = (unsigned long)p; fp = ((struct switch_stack *)p->thread.ksp)->fp; /* ;dgt2 */ do { diff --git a/arch/openrisc/include/asm/processor.h b/arch/openrisc/include/asm/processor.h index ad53b31848859..aa1699c18add8 100644 --- a/arch/openrisc/include/asm/processor.h +++ b/arch/openrisc/include/asm/processor.h @@ -73,7 +73,7 @@ struct thread_struct {
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp); void release_thread(struct task_struct *); -unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define cpu_relax() barrier()
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c index b0698d9ce14fa..3c0c91bcdcbaa 100644 --- a/arch/openrisc/kernel/process.c +++ b/arch/openrisc/kernel/process.c @@ -263,7 +263,7 @@ void dump_elf_thread(elf_greg_t *dest, struct pt_regs* regs) dest[35] = 0; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { /* TODO */
diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index eeb7da0642891..85a2dbfe52787 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -273,7 +273,7 @@ struct mm_struct; /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *);
-extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.regs.iaoq[0]) #define KSTK_ESP(tsk) ((tsk)->thread.regs.gr[30]) diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 38ec4ae812396..4f562dee65a2c 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -240,15 +240,12 @@ copy_thread(unsigned long clone_flags, unsigned long usp, }
unsigned long -get_wchan(struct task_struct *p) +__get_wchan(struct task_struct *p) { struct unwind_frame_info info; unsigned long ip; int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - /* * These bracket the sleeping functions.. */ diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index f348e564f7dd5..e39bd0ff69f3a 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -300,7 +300,7 @@ struct thread_struct {
#define task_pt_regs(tsk) ((tsk)->thread.regs)
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0) #define KSTK_ESP(tsk) ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 50436b52c2133..406d7ee9e3220 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -2111,14 +2111,11 @@ int validate_sp(unsigned long sp, struct task_struct *p,
EXPORT_SYMBOL(validate_sp);
-static unsigned long __get_wchan(struct task_struct *p) +static unsigned long ___get_wchan(struct task_struct *p) { unsigned long ip, sp; int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - sp = p->thread.ksp; if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD)) return 0; @@ -2137,14 +2134,14 @@ static unsigned long __get_wchan(struct task_struct *p) return 0; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long ret;
if (!try_get_task_stack(p)) return 0;
- ret = __get_wchan(p); + ret = ___get_wchan(p);
put_task_stack(p);
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h index 46b492c78cbbf..0749924d9e552 100644 --- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -66,7 +66,7 @@ static inline void release_thread(struct task_struct *dead_task) { }
-extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
static inline void wait_for_interrupt(void) diff --git a/arch/riscv/kernel/stacktrace.c b/arch/riscv/kernel/stacktrace.c index 315db3d0229bf..0fcdc0233faca 100644 --- a/arch/riscv/kernel/stacktrace.c +++ b/arch/riscv/kernel/stacktrace.c @@ -128,16 +128,14 @@ static bool save_wchan(void *arg, unsigned long pc) return true; }
-unsigned long get_wchan(struct task_struct *task) +unsigned long __get_wchan(struct task_struct *task) { unsigned long pc = 0;
- if (likely(task && task != current && !task_is_running(task))) { - if (!try_get_task_stack(task)) - return 0; - walk_stackframe(task, NULL, save_wchan, &pc); - put_task_stack(task); - } + if (!try_get_task_stack(task)) + return 0; + walk_stackframe(task, NULL, save_wchan, &pc); + put_task_stack(task); return pc; }
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 879b8e3f609cd..f54c152bf2bf9 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -192,7 +192,7 @@ static inline void release_thread(struct task_struct *tsk) { } void guarded_storage_release(struct task_struct *tsk); void gs_load_bc_cb(struct pt_regs *regs);
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p); #define task_pt_regs(tsk) ((struct pt_regs *) \ (task_stack_page(tsk) + THREAD_SIZE) - 1) #define KSTK_EIP(tsk) (task_pt_regs(tsk)->psw.addr) diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 350e94d0cac23..e5dd46b1bff8c 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -181,12 +181,12 @@ void execve_tail(void) asm volatile("sfpc %0" : : "d" (0)); }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { struct unwind_state state; unsigned long ip = 0;
- if (!p || p == current || task_is_running(p) || !task_stack_page(p)) + if (!task_stack_page(p)) return 0;
if (!try_get_task_stack(p)) diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h index aa92cc933889d..45240ec6b85a4 100644 --- a/arch/sh/include/asm/processor_32.h +++ b/arch/sh/include/asm/processor_32.h @@ -180,7 +180,7 @@ static inline void show_code(struct pt_regs *regs) } #endif
-extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15]) diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 717de05c81f49..1c28e3cddb60d 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -182,13 +182,10 @@ __switch_to(struct task_struct *prev, struct task_struct *next) return prev; }
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long pc;
- if (!p || p == current || task_is_running(p)) - return 0; - /* * The same comment as on the Alpha applies here, too ... */ diff --git a/arch/sparc/include/asm/processor_32.h b/arch/sparc/include/asm/processor_32.h index b6242f7771e9e..647bf0ac7beb9 100644 --- a/arch/sparc/include/asm/processor_32.h +++ b/arch/sparc/include/asm/processor_32.h @@ -89,7 +89,7 @@ static inline void start_thread(struct pt_regs * regs, unsigned long pc, /* Free all resources held by a thread. */ #define release_thread(tsk) do { } while(0)
-unsigned long get_wchan(struct task_struct *); +unsigned long __get_wchan(struct task_struct *);
#define task_pt_regs(tsk) ((tsk)->thread.kregs) #define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc) diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 5cf145f18f36b..ae851e8fce4c9 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -183,7 +183,7 @@ do { \ /* Free all resources held by a thread. */ #define release_thread(tsk) do { } while (0)
-unsigned long get_wchan(struct task_struct *task); +unsigned long __get_wchan(struct task_struct *task);
#define task_pt_regs(tsk) (task_thread_info(tsk)->kregs) #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index bbbe0cfef7465..2dc0bf9fe62eb 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c @@ -365,7 +365,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long arg, return 0; }
-unsigned long get_wchan(struct task_struct *task) +unsigned long __get_wchan(struct task_struct *task) { unsigned long pc, fp, bias = 0; unsigned long task_base = (unsigned long) task; @@ -373,9 +373,6 @@ unsigned long get_wchan(struct task_struct *task) struct reg_window32 *rw; int count = 0;
- if (!task || task == current || task_is_running(task)) - goto out; - fp = task_thread_info(task)->ksp + bias; do { /* Bogus frame pointer? */ diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index d1cc410d2f647..f5b2cac8669f9 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -663,7 +663,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) return 0; }
-unsigned long get_wchan(struct task_struct *task) +unsigned long __get_wchan(struct task_struct *task) { unsigned long pc, fp, bias = 0; struct thread_info *tp; @@ -671,9 +671,6 @@ unsigned long get_wchan(struct task_struct *task) unsigned long ret = 0; int count = 0;
- if (!task || task == current || task_is_running(task)) - goto out; - tp = task_thread_info(task); bias = STACK_BIAS; fp = task_thread_info(task)->ksp + bias; diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index b5cf0ed116d9e..579692a40a556 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -106,6 +106,6 @@ extern struct cpuinfo_um boot_cpu_data; #define cache_line_size() (boot_cpu_data.cache_alignment)
#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf) -extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
#endif diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 457a38db368b7..82107373ac7e9 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -364,14 +364,11 @@ unsigned long arch_align_stack(unsigned long sp) } #endif
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long stack_page, sp, ip; bool seen_sched = 0;
- if ((p == NULL) || (p == current) || task_is_running(p)) - return 0; - stack_page = (unsigned long) task_stack_page(p); /* Bail if the process has no kernel stack for some reason */ if (stack_page == 0) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 577f342dbfb27..2b5f6c6c2b322 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -590,7 +590,7 @@ static inline void load_sp0(unsigned long sp0) /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *);
-unsigned long get_wchan(struct task_struct *p); +unsigned long __get_wchan(struct task_struct *p);
/* * Generic CPUID function diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index cd426c3283ee1..266962547b58c 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -943,13 +943,10 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) * because the task might wake up and we might look at a stack * changing under us. */ -unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long entry = 0;
- if (p == current || task_is_running(p)) - return 0; - stack_trace_save_tsk(p, &entry, 1, 0); return entry; } diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 7f63aca6a0d34..ad15fbc572838 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -215,7 +215,7 @@ struct mm_struct; /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0)
-extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc) #define KSTK_ESP(tsk) (task_pt_regs(tsk)->areg[1]) diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 0601653406123..47f933fed8700 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -298,15 +298,12 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, * These bracket the sleeping functions.. */
-unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long sp, pc; unsigned long stack_page = (unsigned long) task_stack_page(p); int count = 0;
- if (!p || p == current || task_is_running(p)) - return 0; - sp = p->thread.sp; pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
diff --git a/include/linux/sched.h b/include/linux/sched.h index c1a927ddec646..71b012a224e4c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2137,6 +2137,7 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) #endif /* CONFIG_SMP */
extern bool sched_task_on_rq(struct task_struct *p); +extern unsigned long get_wchan(struct task_struct *p);
/* * In order to reduce various lock holder preemption latencies provide an diff --git a/kernel/sched/core.c b/kernel/sched/core.c index aea60eae21a7f..d37f959ed1ab8 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1962,6 +1962,25 @@ bool sched_task_on_rq(struct task_struct *p) return task_on_rq_queued(p); }
+unsigned long get_wchan(struct task_struct *p) +{ + unsigned long ip = 0; + unsigned int state; + + if (!p || p == current) + return 0; + + /* Only get wchan if task is blocked and we can keep it that way. */ + raw_spin_lock_irq(&p->pi_lock); + state = READ_ONCE(p->__state); + smp_rmb(); /* see try_to_wake_up() */ + if (state != TASK_RUNNING && state != TASK_WAKING && !p->on_rq) + ip = __get_wchan(p); + raw_spin_unlock_irq(&p->pi_lock); + + return ip; +} + static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags) { if (!(flags & ENQUEUE_NOCLOCK))
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 5d1ceb3969b6b2e47e2df6d17790a7c5a20fcbb4 ]
Use asm/unwind.h to implement wchan, since we cannot always rely on STACKTRACE=y.
Fixes: bc9bbb81730e ("x86: Fix get_wchan() to support the ORC unwinder") Reported-by: Stephen Rothwell sfr@canb.auug.org.au Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Kees Cook keescook@chromium.org Link: https://lkml.kernel.org/r/20211022152104.137058575@infradead.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/process.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 266962547b58c..2fe1810e922a9 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -43,6 +43,7 @@ #include <asm/io_bitmap.h> #include <asm/proto.h> #include <asm/frame.h> +#include <asm/unwind.h>
#include "process.h"
@@ -945,10 +946,20 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) */ unsigned long __get_wchan(struct task_struct *p) { - unsigned long entry = 0; + struct unwind_state state; + unsigned long addr = 0;
- stack_trace_save_tsk(p, &entry, 1, 0); - return entry; + for (unwind_start(&state, p, NULL, NULL); !unwind_done(&state); + unwind_next_frame(&state)) { + addr = unwind_get_return_address(&state); + if (!addr) + break; + if (in_sched_functions(addr)) + continue; + break; + } + + return addr; }
long do_arch_prctl_common(struct task_struct *task, int option,
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit f76fbbbb5061fe14824ba5807c44bd7400a6b4e1 ]
Use the actual return value instead of always -1 if register_kretprobe() failed.
E.g. without this patch:
# insmod samples/kprobes/kretprobe_example.ko func=no_such_func insmod: ERROR: could not insert module samples/kprobes/kretprobe_example.ko: Operation not permitted
With this patch:
# insmod samples/kprobes/kretprobe_example.ko func=no_such_func insmod: ERROR: could not insert module samples/kprobes/kretprobe_example.ko: Unknown symbol in module
Link: https://lkml.kernel.org/r/1635213091-24387-2-git-send-email-yangtiezhu@loong...
Fixes: 804defea1c02 ("Kprobes: move kprobe examples to samples/") Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Acked-by: Masami Hiramatsu mhiramat@kernel.org Signed-off-by: Steven Rostedt (VMware) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- samples/kprobes/kretprobe_example.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c index 5dc1bf3baa98b..228321ecb1616 100644 --- a/samples/kprobes/kretprobe_example.c +++ b/samples/kprobes/kretprobe_example.c @@ -86,7 +86,7 @@ static int __init kretprobe_init(void) ret = register_kretprobe(&my_kretprobe); if (ret < 0) { pr_err("register_kretprobe failed, returned %d\n", ret); - return -1; + return ret; } pr_info("Planted return probe at %s: %p\n", my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr);
From: Janis Schoetterl-Glausch scgl@linux.ibm.com
[ Upstream commit 85f517b29418158d3e6e90c3f0fc01b306d2f1a1 ]
If handle_sske cannot set the storage key, because there is no page table entry or no present large page entry, it calls fixup_user_fault. However, currently, if the call succeeds, handle_sske returns -EAGAIN, without having set the storage key. Instead, retry by continue'ing the loop without incrementing the address. The same issue in handle_pfmf was fixed by a11bdb1a6b78 ("KVM: s390: Fix pfmf and conditional skey emulation").
Fixes: bd096f644319 ("KVM: s390: Add skey emulation fault handling") Signed-off-by: Janis Schoetterl-Glausch scgl@linux.ibm.com Reviewed-by: Christian Borntraeger borntraeger@de.ibm.com Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Link: https://lore.kernel.org/r/20211022152648.26536-1-scgl@linux.ibm.com Signed-off-by: Christian Borntraeger borntraeger@de.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/priv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 53da4ceb16a3a..417154b314a64 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c @@ -397,6 +397,8 @@ static int handle_sske(struct kvm_vcpu *vcpu) mmap_read_unlock(current->mm); if (rc == -EFAULT) return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); + if (rc == -EAGAIN) + continue; if (rc < 0) return rc; start += PAGE_SIZE;
From: Wang Hai wanghai38@huawei.com
[ Upstream commit d549107305b4634c81223a853701c06bcf657bc3 ]
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff88810a2ddc00 (size 512): comm "kworker/6:1", pid 176, jiffies 4295009893 (age 757.220s) hex dump (first 32 bytes): 00 50 05 18 81 88 ff ff 00 00 00 00 00 00 00 00 .P.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<ffffffff8167939c>] slab_post_alloc_hook+0x9c/0x490 [<ffffffff8167f627>] kmem_cache_alloc_trace+0x1f7/0x470 [<ffffffffa02a1530>] if_usb_probe+0x60/0x37c [libertas_tf_usb] [<ffffffffa022668a>] usb_probe_interface+0x1aa/0x3c0 [usbcore] [<ffffffff82b59630>] really_probe+0x190/0x480 [<ffffffff82b59a19>] __driver_probe_device+0xf9/0x180 [<ffffffff82b59af3>] driver_probe_device+0x53/0x130 [<ffffffff82b5a075>] __device_attach_driver+0x105/0x130 [<ffffffff82b55949>] bus_for_each_drv+0x129/0x190 [<ffffffff82b593c9>] __device_attach+0x1c9/0x270 [<ffffffff82b5a250>] device_initial_probe+0x20/0x30 [<ffffffff82b579c2>] bus_probe_device+0x142/0x160 [<ffffffff82b52e49>] device_add+0x829/0x1300 [<ffffffffa02229b1>] usb_set_configuration+0xb01/0xcc0 [usbcore] [<ffffffffa0235c4e>] usb_generic_driver_probe+0x6e/0x90 [usbcore] [<ffffffffa022641f>] usb_probe_device+0x6f/0x130 [usbcore]
cardp is missing being freed in the error handling path of the probe and the path of the disconnect, which will cause memory leak.
This patch adds the missing kfree().
Fixes: c305a19a0d0a ("libertas_tf: usb specific functions") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wang Hai wanghai38@huawei.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211020120345.2016045-2-wanghai38@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/libertas_tf/if_usb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c index fe0a69e804d8c..75b5319d033f3 100644 --- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -230,6 +230,7 @@ static int if_usb_probe(struct usb_interface *intf,
dealloc: if_usb_free(cardp); + kfree(cardp); error: lbtf_deb_leave(LBTF_DEB_MAIN); return -ENOMEM; @@ -254,6 +255,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
/* Unlink and free urb */ if_usb_free(cardp); + kfree(cardp);
usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf));
From: Wang Hai wanghai38@huawei.com
[ Upstream commit 9692151e2fe7a326bafe99836fd1f20a2cc3a049 ]
I got memory leak as follows when doing fault injection test:
unreferenced object 0xffff88812c7d7400 (size 512): comm "kworker/6:1", pid 176, jiffies 4295003332 (age 822.830s) hex dump (first 32 bytes): 00 68 1e 04 81 88 ff ff 01 00 00 00 00 00 00 00 .h.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<ffffffff8167939c>] slab_post_alloc_hook+0x9c/0x490 [<ffffffff8167f627>] kmem_cache_alloc_trace+0x1f7/0x470 [<ffffffffa02c9873>] if_usb_probe+0x63/0x446 [usb8xxx] [<ffffffffa022668a>] usb_probe_interface+0x1aa/0x3c0 [usbcore] [<ffffffff82b59630>] really_probe+0x190/0x480 [<ffffffff82b59a19>] __driver_probe_device+0xf9/0x180 [<ffffffff82b59af3>] driver_probe_device+0x53/0x130 [<ffffffff82b5a075>] __device_attach_driver+0x105/0x130 [<ffffffff82b55949>] bus_for_each_drv+0x129/0x190 [<ffffffff82b593c9>] __device_attach+0x1c9/0x270 [<ffffffff82b5a250>] device_initial_probe+0x20/0x30 [<ffffffff82b579c2>] bus_probe_device+0x142/0x160 [<ffffffff82b52e49>] device_add+0x829/0x1300 [<ffffffffa02229b1>] usb_set_configuration+0xb01/0xcc0 [usbcore] [<ffffffffa0235c4e>] usb_generic_driver_probe+0x6e/0x90 [usbcore] [<ffffffffa022641f>] usb_probe_device+0x6f/0x130 [usbcore]
cardp is missing being freed in the error handling path of the probe and the path of the disconnect, which will cause memory leak.
This patch adds the missing kfree().
Fixes: 876c9d3aeb98 ("[PATCH] Marvell Libertas 8388 802.11b/g USB driver") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Wang Hai wanghai38@huawei.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211020120345.2016045-3-wanghai38@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/marvell/libertas/if_usb.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index 20436a289d5cd..5d6dc1dd050d4 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -292,6 +292,7 @@ err_add_card: if_usb_reset_device(cardp); dealloc: if_usb_free(cardp); + kfree(cardp);
error: return r; @@ -316,6 +317,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
/* Unlink and free urb */ if_usb_free(cardp); + kfree(cardp);
usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf));
From: Benjamin Li benl@squareup.com
[ Upstream commit 9bfe38e064af5decba2ffce66a2958ab8b10eaa4 ]
This is essentially exactly following the dma_wmb()/dma_rmb() usage instructions in Documentation/memory-barriers.txt.
The theoretical races here are:
1. DXE (the DMA Transfer Engine in the Wi-Fi subsystem) seeing the dxe->ctrl & WCN36xx_DXE_CTRL_VLD write before the dxe->dst_addr_l write, thus performing DMA into the wrong address.
2. CPU reading dxe->dst_addr_l before DXE unsets dxe->ctrl & WCN36xx_DXE_CTRL_VLD. This should generally be harmless since DXE doesn't write dxe->dst_addr_l (no risk of freeing the wrong skb).
Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware") Signed-off-by: Benjamin Li benl@squareup.com Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20211023001528.3077822-1-benl@squareup.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/dxe.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 0e0bbcd11300b..aff04ef662663 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -606,6 +606,10 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, dxe = ctl->desc;
while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) { + /* do not read until we own DMA descriptor */ + dma_rmb(); + + /* read/modify DMA descriptor */ skb = ctl->skb; dma_addr = dxe->dst_addr_l; ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC); @@ -616,9 +620,15 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, DMA_FROM_DEVICE); wcn36xx_rx_skb(wcn, skb); - } /* else keep old skb not submitted and use it for rx DMA */ + } + /* else keep old skb not submitted and reuse it for rx DMA + * (dropping the packet that it contained) + */
+ /* flush descriptor changes before re-marking as valid */ + dma_wmb(); dxe->ctrl = ctrl; + ctl = ctl->next; dxe = ctl->desc; }
From: Loic Poulain loic.poulain@linaro.org
[ Upstream commit 113f304dbc1627c6ec9d5329d839964095768980 ]
The firmware is offering features such as ARP offload, for which firmware crafts its own (QoS)packets without waking up the host. Point is that the sequence numbers generated by the firmware are not in sync with the host mac80211 layer and can cause packets such as firmware ARP reponses to be dropped by the AP (too old SN).
To fix this we need to let the firmware manages the sequence numbers by its own (except for QoS null frames). There is a SN counter for each QoS queue and one global/baseline counter for Non-QoS.
Fixes: 84aff52e4f57 ("wcn36xx: Use sequence number allocated by mac80211") Signed-off-by: Loic Poulain loic.poulain@linaro.org Tested-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1635150336-18736-1-git-send-email-loic.poulain@lin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/txrx.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c index c0f51fa13dfa1..bbd7194c82e27 100644 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ b/drivers/net/wireless/ath/wcn36xx/txrx.c @@ -344,8 +344,6 @@ static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd, bd->pdu.mpdu_header_off; bd->pdu.mpdu_len = len; bd->pdu.tid = tid; - /* Use seq number generated by mac80211 */ - bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; }
static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, @@ -442,6 +440,9 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, tid = ieee80211_get_tid(hdr); /* TID->QID is one-to-one mapping */ bd->queue_id = tid; + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS; + } else { + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; }
if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT || @@ -453,6 +454,8 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, /* Don't use a regular queue for null packet (no ampdu) */ bd->queue_id = WCN36XX_TX_U_WQ_ID; bd->bd_rate = WCN36XX_BD_RATE_CTRL; + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) + bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_HOST; }
if (bcast) { @@ -512,6 +515,8 @@ static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd, bd->queue_id = WCN36XX_TX_U_WQ_ID; *vif_priv = __vif_priv;
+ bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS; + wcn36xx_set_tx_pdu(bd, ieee80211_is_data_qos(hdr->frame_control) ? sizeof(struct ieee80211_qos_hdr) :
From: Eric Dumazet edumazet@google.com
[ Upstream commit f941eadd8d6d4ee2f8c9aeab8e1da5e647533a7d ]
__bpf_prog_run() can run from non IRQ contexts, meaning it could be re entered if interrupted.
This calls for the irq safe variant of u64_stats_update_{begin|end}, or risk a deadlock.
This patch is a nop on 64bit arches, fortunately.
syzbot report:
WARNING: inconsistent lock state 5.12.0-rc3-syzkaller #0 Not tainted -------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. udevd/4013 [HC0[0]:SC0[0]:HE1:SE1] takes: ff7c9dec (&(&pstats->syncp)->seq){+.?.}-{0:0}, at: sk_filter include/linux/filter.h:867 [inline] ff7c9dec (&(&pstats->syncp)->seq){+.?.}-{0:0}, at: do_one_broadcast net/netlink/af_netlink.c:1468 [inline] ff7c9dec (&(&pstats->syncp)->seq){+.?.}-{0:0}, at: netlink_broadcast_filtered+0x27c/0x4fc net/netlink/af_netlink.c:1520 {IN-SOFTIRQ-W} state was registered at: lock_acquire.part.0+0xf0/0x41c kernel/locking/lockdep.c:5510 lock_acquire+0x6c/0x74 kernel/locking/lockdep.c:5483 do_write_seqcount_begin_nested include/linux/seqlock.h:520 [inline] do_write_seqcount_begin include/linux/seqlock.h:545 [inline] u64_stats_update_begin include/linux/u64_stats_sync.h:129 [inline] bpf_prog_run_pin_on_cpu include/linux/filter.h:624 [inline] bpf_prog_run_clear_cb+0x1bc/0x270 include/linux/filter.h:755 run_filter+0xa0/0x17c net/packet/af_packet.c:2031 packet_rcv+0xc0/0x3e0 net/packet/af_packet.c:2104 dev_queue_xmit_nit+0x2bc/0x39c net/core/dev.c:2387 xmit_one net/core/dev.c:3588 [inline] dev_hard_start_xmit+0x94/0x518 net/core/dev.c:3609 sch_direct_xmit+0x11c/0x1f0 net/sched/sch_generic.c:313 qdisc_restart net/sched/sch_generic.c:376 [inline] __qdisc_run+0x194/0x7f8 net/sched/sch_generic.c:384 qdisc_run include/net/pkt_sched.h:136 [inline] qdisc_run include/net/pkt_sched.h:128 [inline] __dev_xmit_skb net/core/dev.c:3795 [inline] __dev_queue_xmit+0x65c/0xf84 net/core/dev.c:4150 dev_queue_xmit+0x14/0x18 net/core/dev.c:4215 neigh_resolve_output net/core/neighbour.c:1491 [inline] neigh_resolve_output+0x170/0x228 net/core/neighbour.c:1471 neigh_output include/net/neighbour.h:510 [inline] ip6_finish_output2+0x2e4/0x9fc net/ipv6/ip6_output.c:117 __ip6_finish_output net/ipv6/ip6_output.c:182 [inline] __ip6_finish_output+0x164/0x3f8 net/ipv6/ip6_output.c:161 ip6_finish_output+0x2c/0xb0 net/ipv6/ip6_output.c:192 NF_HOOK_COND include/linux/netfilter.h:290 [inline] ip6_output+0x74/0x294 net/ipv6/ip6_output.c:215 dst_output include/net/dst.h:448 [inline] NF_HOOK include/linux/netfilter.h:301 [inline] NF_HOOK include/linux/netfilter.h:295 [inline] mld_sendpack+0x2a8/0x7e4 net/ipv6/mcast.c:1679 mld_send_cr net/ipv6/mcast.c:1975 [inline] mld_ifc_timer_expire+0x1e8/0x494 net/ipv6/mcast.c:2474 call_timer_fn+0xd0/0x570 kernel/time/timer.c:1431 expire_timers kernel/time/timer.c:1476 [inline] __run_timers kernel/time/timer.c:1745 [inline] run_timer_softirq+0x2e4/0x384 kernel/time/timer.c:1758 __do_softirq+0x204/0x7ac kernel/softirq.c:345 do_softirq_own_stack include/asm-generic/softirq_stack.h:10 [inline] invoke_softirq kernel/softirq.c:228 [inline] __irq_exit_rcu+0x1d8/0x200 kernel/softirq.c:422 irq_exit+0x10/0x3c kernel/softirq.c:446 __handle_domain_irq+0xb4/0x120 kernel/irq/irqdesc.c:692 handle_domain_irq include/linux/irqdesc.h:176 [inline] gic_handle_irq+0x84/0xac drivers/irqchip/irq-gic.c:370 __irq_svc+0x5c/0x94 arch/arm/kernel/entry-armv.S:205 debug_smp_processor_id+0x0/0x24 lib/smp_processor_id.c:53 rcu_read_lock_held_common kernel/rcu/update.c:108 [inline] rcu_read_lock_sched_held+0x24/0x7c kernel/rcu/update.c:123 trace_lock_acquire+0x24c/0x278 include/trace/events/lock.h:13 lock_acquire+0x3c/0x74 kernel/locking/lockdep.c:5481 rcu_lock_acquire include/linux/rcupdate.h:267 [inline] rcu_read_lock include/linux/rcupdate.h:656 [inline] avc_has_perm_noaudit+0x6c/0x260 security/selinux/avc.c:1150 selinux_inode_permission+0x140/0x220 security/selinux/hooks.c:3141 security_inode_permission+0x44/0x60 security/security.c:1268 inode_permission.part.0+0x5c/0x13c fs/namei.c:521 inode_permission fs/namei.c:494 [inline] may_lookup fs/namei.c:1652 [inline] link_path_walk.part.0+0xd4/0x38c fs/namei.c:2208 link_path_walk fs/namei.c:2189 [inline] path_lookupat+0x3c/0x1b8 fs/namei.c:2419 filename_lookup+0xa8/0x1a4 fs/namei.c:2453 user_path_at_empty+0x74/0x90 fs/namei.c:2733 do_readlinkat+0x5c/0x12c fs/stat.c:417 __do_sys_readlink fs/stat.c:450 [inline] sys_readlink+0x24/0x28 fs/stat.c:447 ret_fast_syscall+0x0/0x2c arch/arm/mm/proc-v7.S:64 0x7eaa4974 irq event stamp: 298277 hardirqs last enabled at (298277): [<802000d0>] no_work_pending+0x4/0x34 hardirqs last disabled at (298276): [<8020c9b8>] do_work_pending+0x9c/0x648 arch/arm/kernel/signal.c:676 softirqs last enabled at (298216): [<8020167c>] __do_softirq+0x584/0x7ac kernel/softirq.c:372 softirqs last disabled at (298201): [<8024dff4>] do_softirq_own_stack include/asm-generic/softirq_stack.h:10 [inline] softirqs last disabled at (298201): [<8024dff4>] invoke_softirq kernel/softirq.c:228 [inline] softirqs last disabled at (298201): [<8024dff4>] __irq_exit_rcu+0x1d8/0x200 kernel/softirq.c:422
other info that might help us debug this: Possible unsafe locking scenario:
CPU0 ---- lock(&(&pstats->syncp)->seq); <Interrupt> lock(&(&pstats->syncp)->seq);
*** DEADLOCK ***
1 lock held by udevd/4013: #0: 82b09c5c (rcu_read_lock){....}-{1:2}, at: sk_filter_trim_cap+0x54/0x434 net/core/filter.c:139
stack backtrace: CPU: 1 PID: 4013 Comm: udevd Not tainted 5.12.0-rc3-syzkaller #0 Hardware name: ARM-Versatile Express Backtrace: [<81802550>] (dump_backtrace) from [<818027c4>] (show_stack+0x18/0x1c arch/arm/kernel/traps.c:252) r7:00000080 r6:600d0093 r5:00000000 r4:82b58344 [<818027ac>] (show_stack) from [<81809e98>] (__dump_stack lib/dump_stack.c:79 [inline]) [<818027ac>] (show_stack) from [<81809e98>] (dump_stack+0xb8/0xe8 lib/dump_stack.c:120) [<81809de0>] (dump_stack) from [<81804a00>] (print_usage_bug.part.0+0x228/0x230 kernel/locking/lockdep.c:3806) r7:86bcb768 r6:81a0326c r5:830f96a8 r4:86bcb0c0 [<818047d8>] (print_usage_bug.part.0) from [<802bb1b8>] (print_usage_bug kernel/locking/lockdep.c:3776 [inline]) [<818047d8>] (print_usage_bug.part.0) from [<802bb1b8>] (valid_state kernel/locking/lockdep.c:3818 [inline]) [<818047d8>] (print_usage_bug.part.0) from [<802bb1b8>] (mark_lock_irq kernel/locking/lockdep.c:4021 [inline]) [<818047d8>] (print_usage_bug.part.0) from [<802bb1b8>] (mark_lock.part.0+0xc34/0x136c kernel/locking/lockdep.c:4478) r10:83278fe8 r9:82c6d748 r8:00000000 r7:82c6d2d4 r6:00000004 r5:86bcb768 r4:00000006 [<802ba584>] (mark_lock.part.0) from [<802bc644>] (mark_lock kernel/locking/lockdep.c:4442 [inline]) [<802ba584>] (mark_lock.part.0) from [<802bc644>] (mark_usage kernel/locking/lockdep.c:4391 [inline]) [<802ba584>] (mark_lock.part.0) from [<802bc644>] (__lock_acquire+0x9bc/0x3318 kernel/locking/lockdep.c:4854) r10:86bcb768 r9:86bcb0c0 r8:00000001 r7:00040000 r6:0000075a r5:830f96a8 r4:00000000 [<802bbc88>] (__lock_acquire) from [<802bfb90>] (lock_acquire.part.0+0xf0/0x41c kernel/locking/lockdep.c:5510) r10:00000000 r9:600d0013 r8:00000000 r7:00000000 r6:828a2680 r5:828a2680 r4:861e5bc8 [<802bfaa0>] (lock_acquire.part.0) from [<802bff28>] (lock_acquire+0x6c/0x74 kernel/locking/lockdep.c:5483) r10:8146137c r9:00000000 r8:00000001 r7:00000000 r6:00000000 r5:00000000 r4:ff7c9dec [<802bfebc>] (lock_acquire) from [<81381eb4>] (do_write_seqcount_begin_nested include/linux/seqlock.h:520 [inline]) [<802bfebc>] (lock_acquire) from [<81381eb4>] (do_write_seqcount_begin include/linux/seqlock.h:545 [inline]) [<802bfebc>] (lock_acquire) from [<81381eb4>] (u64_stats_update_begin include/linux/u64_stats_sync.h:129 [inline]) [<802bfebc>] (lock_acquire) from [<81381eb4>] (__bpf_prog_run_save_cb include/linux/filter.h:727 [inline]) [<802bfebc>] (lock_acquire) from [<81381eb4>] (bpf_prog_run_save_cb include/linux/filter.h:741 [inline]) [<802bfebc>] (lock_acquire) from [<81381eb4>] (sk_filter_trim_cap+0x26c/0x434 net/core/filter.c:149) r10:a4095dd0 r9:ff7c9dd0 r8:e44be000 r7:8146137c r6:00000001 r5:8611ba80 r4:00000000 [<81381c48>] (sk_filter_trim_cap) from [<8146137c>] (sk_filter include/linux/filter.h:867 [inline]) [<81381c48>] (sk_filter_trim_cap) from [<8146137c>] (do_one_broadcast net/netlink/af_netlink.c:1468 [inline]) [<81381c48>] (sk_filter_trim_cap) from [<8146137c>] (netlink_broadcast_filtered+0x27c/0x4fc net/netlink/af_netlink.c:1520) r10:00000001 r9:833d6b1c r8:00000000 r7:8572f864 r6:8611ba80 r5:8698d800 r4:8572f800 [<81461100>] (netlink_broadcast_filtered) from [<81463e60>] (netlink_broadcast net/netlink/af_netlink.c:1544 [inline]) [<81461100>] (netlink_broadcast_filtered) from [<81463e60>] (netlink_sendmsg+0x3d0/0x478 net/netlink/af_netlink.c:1925) r10:00000000 r9:00000002 r8:8698d800 r7:000000b7 r6:8611b900 r5:861e5f50 r4:86aa3000 [<81463a90>] (netlink_sendmsg) from [<81321f54>] (sock_sendmsg_nosec net/socket.c:654 [inline]) [<81463a90>] (netlink_sendmsg) from [<81321f54>] (sock_sendmsg+0x3c/0x4c net/socket.c:674) r10:00000000 r9:861e5dd4 r8:00000000 r7:86570000 r6:00000000 r5:86570000 r4:861e5f50 [<81321f18>] (sock_sendmsg) from [<813234d0>] (____sys_sendmsg+0x230/0x29c net/socket.c:2350) r5:00000040 r4:861e5f50 [<813232a0>] (____sys_sendmsg) from [<8132549c>] (___sys_sendmsg+0xac/0xe4 net/socket.c:2404) r10:00000128 r9:861e4000 r8:00000000 r7:00000000 r6:86570000 r5:861e5f50 r4:00000000 [<813253f0>] (___sys_sendmsg) from [<81325684>] (__sys_sendmsg net/socket.c:2433 [inline]) [<813253f0>] (___sys_sendmsg) from [<81325684>] (__do_sys_sendmsg net/socket.c:2442 [inline]) [<813253f0>] (___sys_sendmsg) from [<81325684>] (sys_sendmsg+0x58/0xa0 net/socket.c:2440) r8:80200224 r7:00000128 r6:00000000 r5:7eaa541c r4:86570000 [<8132562c>] (sys_sendmsg) from [<80200060>] (ret_fast_syscall+0x0/0x2c arch/arm/mm/proc-v7.S:64) Exception stack(0x861e5fa8 to 0x861e5ff0) 5fa0: 00000000 00000000 0000000c 7eaa541c 00000000 00000000 5fc0: 00000000 00000000 76fbf840 00000128 00000000 0000008f 7eaa541c 000563f8 5fe0: 00056110 7eaa53e0 00036cec 76c9bf44 r6:76fbf840 r5:00000000 r4:00000000
Fixes: 492ecee892c2 ("bpf: enable program stats") Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20211026214133.3114279-2-eric.dumazet@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/filter.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/linux/filter.h b/include/linux/filter.h index ef03ff34234d8..28391de6cc445 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -613,13 +613,14 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, if (static_branch_unlikely(&bpf_stats_enabled_key)) { struct bpf_prog_stats *stats; u64 start = sched_clock(); + unsigned long flags;
ret = dfunc(ctx, prog->insnsi, prog->bpf_func); stats = this_cpu_ptr(prog->stats); - u64_stats_update_begin(&stats->syncp); + flags = u64_stats_update_begin_irqsave(&stats->syncp); stats->cnt++; stats->nsecs += sched_clock() - start; - u64_stats_update_end(&stats->syncp); + u64_stats_update_end_irqrestore(&stats->syncp, flags); } else { ret = dfunc(ctx, prog->insnsi, prog->bpf_func); }
From: Eric Dumazet edumazet@google.com
[ Upstream commit d979617aa84d96acca44c2f5778892b4565e322f ]
It seems update_prog_stats() suffers from same issue fixed in the prior patch:
As it can run while interrupts are enabled, it could be re-entered and the u64_stats syncp could be mangled.
Fixes: fec56f5890d9 ("bpf: Introduce BPF trampoline") Signed-off-by: Eric Dumazet edumazet@google.com Signed-off-by: Alexei Starovoitov ast@kernel.org Link: https://lore.kernel.org/bpf/20211026214133.3114279-3-eric.dumazet@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/trampoline.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index fe1e857324e66..d3a307a8c42b9 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -585,11 +585,13 @@ static void notrace update_prog_stats(struct bpf_prog *prog, * Hence check that 'start' is valid. */ start > NO_START_TIME) { + unsigned long flags; + stats = this_cpu_ptr(prog->stats); - u64_stats_update_begin(&stats->syncp); + flags = u64_stats_update_begin_irqsave(&stats->syncp); stats->cnt++; stats->nsecs += sched_clock() - start; - u64_stats_update_end(&stats->syncp); + u64_stats_update_end_irqrestore(&stats->syncp, flags); } }
From: Loic Poulain loic.poulain@linaro.org
[ Upstream commit d707f812bb0513ea0030d0c9fe2a456bae5a4583 ]
The channel scan list must be updated before triggering a hardware scan so that firmware takes into account the regulatory info for each single channel such as active/passive config, power, DFS, etc... Without this the firmware uses its own internal default channel configuration, which is not aligned with mac80211 regulatory rules, and misses several channels (e.g. 144).
Fixes: 2f3bef4b247e ("wcn36xx: Add hardware scan offload support") Signed-off-by: Loic Poulain loic.poulain@linaro.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/1635175328-25642-1-git-send-email-loic.poulain@lin... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/wcn36xx/hal.h | 32 ++++++++++ drivers/net/wireless/ath/wcn36xx/main.c | 1 + drivers/net/wireless/ath/wcn36xx/smd.c | 82 +++++++++++++++++++++++++ drivers/net/wireless/ath/wcn36xx/smd.h | 1 + 4 files changed, 116 insertions(+)
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h index 455143c4164ee..de3bca043c2b3 100644 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ b/drivers/net/wireless/ath/wcn36xx/hal.h @@ -359,6 +359,8 @@ enum wcn36xx_hal_host_msg_type { WCN36XX_HAL_START_SCAN_OFFLOAD_RSP = 205, WCN36XX_HAL_STOP_SCAN_OFFLOAD_REQ = 206, WCN36XX_HAL_STOP_SCAN_OFFLOAD_RSP = 207, + WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ = 208, + WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP = 209, WCN36XX_HAL_SCAN_OFFLOAD_IND = 210,
WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233, @@ -1353,6 +1355,36 @@ struct wcn36xx_hal_stop_scan_offload_rsp_msg { u32 status; } __packed;
+#define WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK 0x000000ff +#define WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK 0x0000ff00 +#define WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK 0x00ff0000 +#define WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK 0xff000000 +#define WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK 0x000000ff +#define WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE BIT(7) +#define WCN36XX_HAL_CHAN_INFO_FLAG_DFS BIT(10) +#define WCN36XX_HAL_CHAN_INFO_FLAG_HT BIT(11) +#define WCN36XX_HAL_CHAN_INFO_FLAG_VHT BIT(12) +#define WCN36XX_HAL_CHAN_INFO_PHY_11A 0 +#define WCN36XX_HAL_CHAN_INFO_PHY_11BG 1 +#define WCN36XX_HAL_DEFAULT_ANT_GAIN 6 +#define WCN36XX_HAL_DEFAULT_MIN_POWER 6 + +struct wcn36xx_hal_channel_param { + u32 mhz; + u32 band_center_freq1; + u32 band_center_freq2; + u32 channel_info; + u32 reg_info_1; + u32 reg_info_2; +} __packed; + +struct wcn36xx_hal_update_channel_list_req_msg { + struct wcn36xx_hal_msg_header header; + + u8 num_channel; + struct wcn36xx_hal_channel_param channels[80]; +} __packed; + enum wcn36xx_hal_rate_index { HW_RATE_INDEX_1MBPS = 0x82, HW_RATE_INDEX_2MBPS = 0x84, diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 5974b01f2fd92..5d82aca370a72 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -671,6 +671,7 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
mutex_unlock(&wcn->scan_lock);
+ wcn36xx_smd_update_channel_list(wcn, &hw_req->req); return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req); }
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index f6bea896abe85..70bffe3d87a12 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -16,6 +16,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/bitfield.h> #include <linux/etherdevice.h> #include <linux/firmware.h> #include <linux/bitops.h> @@ -927,6 +928,86 @@ out: return ret; }
+int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req) +{ + struct wcn36xx_hal_update_channel_list_req_msg *msg_body; + int ret, i; + + msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL); + if (!msg_body) + return -ENOMEM; + + INIT_HAL_MSG((*msg_body), WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ); + + msg_body->num_channel = min_t(u8, req->n_channels, sizeof(msg_body->channels)); + for (i = 0; i < msg_body->num_channel; i++) { + struct wcn36xx_hal_channel_param *param = &msg_body->channels[i]; + u32 min_power = WCN36XX_HAL_DEFAULT_MIN_POWER; + u32 ant_gain = WCN36XX_HAL_DEFAULT_ANT_GAIN; + + param->mhz = req->channels[i]->center_freq; + param->band_center_freq1 = req->channels[i]->center_freq; + param->band_center_freq2 = 0; + + if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_PASSIVE; + + if (req->channels[i]->flags & IEEE80211_CHAN_RADAR) + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_DFS; + + if (req->channels[i]->band == NL80211_BAND_5GHZ) { + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_HT; + param->channel_info |= WCN36XX_HAL_CHAN_INFO_FLAG_VHT; + param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11A; + } else { + param->channel_info |= WCN36XX_HAL_CHAN_INFO_PHY_11BG; + } + + if (min_power > req->channels[i]->max_power) + min_power = req->channels[i]->max_power; + + if (req->channels[i]->max_antenna_gain) + ant_gain = req->channels[i]->max_antenna_gain; + + u32p_replace_bits(¶m->reg_info_1, min_power, + WCN36XX_HAL_CHAN_REG1_MIN_PWR_MASK); + u32p_replace_bits(¶m->reg_info_1, req->channels[i]->max_power, + WCN36XX_HAL_CHAN_REG1_MAX_PWR_MASK); + u32p_replace_bits(¶m->reg_info_1, req->channels[i]->max_reg_power, + WCN36XX_HAL_CHAN_REG1_REG_PWR_MASK); + u32p_replace_bits(¶m->reg_info_1, 0, + WCN36XX_HAL_CHAN_REG1_CLASS_ID_MASK); + u32p_replace_bits(¶m->reg_info_2, ant_gain, + WCN36XX_HAL_CHAN_REG2_ANT_GAIN_MASK); + + wcn36xx_dbg(WCN36XX_DBG_HAL, + "%s: freq=%u, channel_info=%08x, reg_info1=%08x, reg_info2=%08x\n", + __func__, param->mhz, param->channel_info, param->reg_info_1, + param->reg_info_2); + } + + mutex_lock(&wcn->hal_mutex); + + PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body)); + + ret = wcn36xx_smd_send_and_wait(wcn, msg_body->header.len); + if (ret) { + wcn36xx_err("Sending hal_update_channel_list failed\n"); + goto out; + } + + ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); + if (ret) { + wcn36xx_err("hal_update_channel_list response failed err=%d\n", ret); + goto out; + } + +out: + kfree(msg_body); + mutex_unlock(&wcn->hal_mutex); + return ret; +} + static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len) { struct wcn36xx_hal_switch_channel_rsp_msg *rsp; @@ -3082,6 +3163,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_GTK_OFFLOAD_RSP: case WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP: case WCN36XX_HAL_HOST_RESUME_RSP: + case WCN36XX_HAL_UPDATE_CHANNEL_LIST_RSP: memcpy(wcn->hal_buf, buf, len); wcn->hal_rsp_len = len; complete(&wcn->hal_rsp_compl); diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h index d8bded03945d4..d3774568d885e 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ b/drivers/net/wireless/ath/wcn36xx/smd.h @@ -70,6 +70,7 @@ int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t cha int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); int wcn36xx_smd_stop_hw_scan(struct wcn36xx *wcn); +int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_request *req); int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index);
From: Lang Yu lang.yu@amd.com
[ Upstream commit a5c5d8d50ecf5874be90a76e1557279ff8a30c9e ]
amdgpu_fence_driver_sw_fini() should be executed before amdgpu_device_ip_fini(), otherwise fence driver resource won't be properly freed as adev->rings have been tore down.
Fixes: 72c8c97b1522 ("drm/amdgpu: Split amdgpu_device_fini into early and late")
Signed-off-by: Lang Yu lang.yu@amd.com Reviewed-by: Andrey Grodzovsky andrey.grodzovsky@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index f7a98e9e68d88..c1e34aa5925b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3877,8 +3877,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev)
void amdgpu_device_fini_sw(struct amdgpu_device *adev) { - amdgpu_device_ip_fini(adev); amdgpu_fence_driver_sw_fini(adev); + amdgpu_device_ip_fini(adev); release_firmware(adev->firmware.gpu_info_fw); adev->firmware.gpu_info_fw = NULL; adev->accel_working = false;
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 403475be6d8b122c3e6b8a47e075926d7299e5ef ]
The DMA mask on SI parts is 40 bits not 44. Copy paste typo.
Fixes: 244511f386ccb9 ("drm/amdgpu: simplify and cleanup setting the dma mask") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1762 Acked-by: Christian König christian.koenig@amd.com Tested-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index 0e81e03e9b498..0fe714f54cca9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -841,12 +841,12 @@ static int gmc_v6_0_sw_init(void *handle)
adev->gmc.mc_mask = 0xffffffffffULL;
- r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44)); + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); if (r) { dev_warn(adev->dev, "No suitable DMA available.\n"); return r; } - adev->need_swiotlb = drm_need_swiotlb(44); + adev->need_swiotlb = drm_need_swiotlb(40);
r = gmc_v6_0_init_microcode(adev); if (r) {
From: Kumar Kartikeya Dwivedi memxor@gmail.com
[ Upstream commit c3fc706e94f5653def2783ffcd809a38676b7551 ]
Similar to the fix in commit: e31eec77e4ab ("bpf: selftests: Fix fd cleanup in get_branch_snapshot")
We use designated initializer to set fds to -1 without breaking on future changes to MAX_SERVER constant denoting the array size.
The particular close(0) occurs on non-reuseport tests, so it can be seen with -n 115/{2,3} but not 115/4. This can cause problems with future tests if they depend on BTF fd never being acquired as fd 0, breaking internal libbpf assumptions.
Fixes: 0ab5539f8584 ("selftests/bpf: Tests for BPF_SK_LOOKUP attach point") Signed-off-by: Kumar Kartikeya Dwivedi memxor@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Reviewed-by: Jakub Sitnicki jakub@cloudflare.com Acked-by: Song Liu songliubraving@fb.com Link: https://lore.kernel.org/bpf/20211028063501.2239335-8-memxor@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/sk_lookup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sk_lookup.c b/tools/testing/selftests/bpf/prog_tests/sk_lookup.c index aee41547e7f45..6db07401bc493 100644 --- a/tools/testing/selftests/bpf/prog_tests/sk_lookup.c +++ b/tools/testing/selftests/bpf/prog_tests/sk_lookup.c @@ -598,7 +598,7 @@ close:
static void run_lookup_prog(const struct test *t) { - int server_fds[MAX_SERVERS] = { -1 }; + int server_fds[] = { [0 ... MAX_SERVERS - 1] = -1 }; int client_fd, reuse_conn_fd = -1; struct bpf_link *lookup_link; int i, err; @@ -1053,7 +1053,7 @@ static void run_sk_assign(struct test_sk_lookup *skel, struct bpf_program *lookup_prog, const char *remote_ip, const char *local_ip) { - int server_fds[MAX_SERVERS] = { -1 }; + int server_fds[] = { [0 ... MAX_SERVERS - 1] = -1 }; struct bpf_sk_lookup ctx; __u64 server_cookie; int i, err;
From: Kumar Kartikeya Dwivedi memxor@gmail.com
[ Upstream commit efadf2ad17a2d5dc90bda4e6e8b2f96af4c62dae ]
The allocated ring buffer is never freed, do so in the cleanup path.
Fixes: f446b570ac7e ("bpf/selftests: Update the IMA test to use BPF ring buffer") Signed-off-by: Kumar Kartikeya Dwivedi memxor@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Acked-by: Andrii Nakryiko andrii@kernel.org Acked-by: Song Liu songliubraving@fb.com Link: https://lore.kernel.org/bpf/20211028063501.2239335-9-memxor@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/prog_tests/test_ima.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/test_ima.c b/tools/testing/selftests/bpf/prog_tests/test_ima.c index 0252f61d611a9..97d8a6f84f4ab 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_ima.c +++ b/tools/testing/selftests/bpf/prog_tests/test_ima.c @@ -43,7 +43,7 @@ static int process_sample(void *ctx, void *data, size_t len) void test_test_ima(void) { char measured_dir_template[] = "/tmp/ima_measuredXXXXXX"; - struct ring_buffer *ringbuf; + struct ring_buffer *ringbuf = NULL; const char *measured_dir; char cmd[256];
@@ -85,5 +85,6 @@ close_clean: err = system(cmd); CHECK(err, "failed to run command", "%s, errno = %d\n", cmd, errno); close_prog: + ring_buffer__free(ringbuf); ima__destroy(skel); }
From: Xin Long lucien.xin@gmail.com
[ Upstream commit 40171248bb8934537fec8fbaf718e57c8add187c ]
Currently when PLPMTUD enters Error state, transport pathmtu will be set to MIN_PLPMTU(512) while probe is continuing with BASE_PLPMTU(1200). It will cause pathmtu to stay in a very small value, even if the real pmtu is some value like 1000.
RFC8899 doesn't clearly say how to set the value in Error state. But one possibility could be keep using BASE_PLPMTU for the real pmtu, but allow to do IP fragmentation when it's in Error state.
As it says in rfc8899#section-5.4:
Some paths could be unable to sustain packets of the BASE_PLPMTU size. The Error State could be implemented to provide robustness to such paths. This allows fallback to a smaller than desired PLPMTU rather than suffer connectivity failure. This could utilize methods such as endpoint IP fragmentation to enable the PL sender to communicate using packets smaller than the BASE_PLPMTU.
This patch is to set pmtu to BASE_PLPMTU instead of MIN_PLPMTU for Error state in sctp_transport_pl_send/toobig(), and set packet ipfragok for non-probe packets when it's in Error state.
Fixes: 1dc68c194571 ("sctp: do state transition when PROBE_COUNT == MAX_PROBES on HB send path") Reported-by: Ying Xu yinxu@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/sctp/output.c | 13 ++++++++----- net/sctp/transport.c | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/net/sctp/output.c b/net/sctp/output.c index 4dfb5ea82b05b..cdfdbd353c678 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -581,13 +581,16 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list); sk = chunk->skb->sk;
- /* check gso */ if (packet->size > tp->pathmtu && !packet->ipfragok && !chunk->pmtu_probe) { - if (!sk_can_gso(sk)) { - pr_err_once("Trying to GSO but underlying device doesn't support it."); - goto out; + if (tp->pl.state == SCTP_PL_ERROR) { /* do IP fragmentation if in Error state */ + packet->ipfragok = 1; + } else { + if (!sk_can_gso(sk)) { /* check gso */ + pr_err_once("Trying to GSO but underlying device doesn't support it."); + goto out; + } + gso = 1; } - gso = 1; }
/* alloc head skb */ diff --git a/net/sctp/transport.c b/net/sctp/transport.c index a3d3ca6dd63dd..1f2dfad768d52 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -269,7 +269,7 @@ bool sctp_transport_pl_send(struct sctp_transport *t) if (t->pl.probe_size == SCTP_BASE_PLPMTU) { /* BASE_PLPMTU Confirmation Failed */ t->pl.state = SCTP_PL_ERROR; /* Base -> Error */
- t->pl.pmtu = SCTP_MIN_PLPMTU; + t->pl.pmtu = SCTP_BASE_PLPMTU; t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); sctp_assoc_sync_pmtu(t->asoc); } @@ -366,7 +366,7 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu) if (pmtu >= SCTP_MIN_PLPMTU && pmtu < SCTP_BASE_PLPMTU) { t->pl.state = SCTP_PL_ERROR; /* Base -> Error */
- t->pl.pmtu = SCTP_MIN_PLPMTU; + t->pl.pmtu = SCTP_BASE_PLPMTU; t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); } } else if (t->pl.state == SCTP_PL_SEARCH) {
From: Xin Long lucien.xin@gmail.com
[ Upstream commit c6ea04ea692fa0d8e7faeb133fcd28e3acf470a0 ]
sctp_transport_pl_update() is called when transport update its dst and pathmtu, instead of stopping the PLPMTUD probe timer, PLPMTUD should start over and reset the probe timer. Otherwise, the PLPMTUD service would stop.
Fixes: 92548ec2f1f9 ("sctp: add the probe timer in transport for PLPMTUD") 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 --- include/net/sctp/sctp.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 69bab88ad66b1..bc00410223b03 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -653,12 +653,10 @@ static inline void sctp_transport_pl_update(struct sctp_transport *t) if (t->pl.state == SCTP_PL_DISABLED) return;
- if (del_timer(&t->probe_timer)) - sctp_transport_put(t); - t->pl.state = SCTP_PL_BASE; t->pl.pmtu = SCTP_BASE_PLPMTU; t->pl.probe_size = SCTP_BASE_PLPMTU; + sctp_transport_reset_probe_timer(t); }
static inline bool sctp_transport_pl_enabled(struct sctp_transport *t)
From: Xin Long lucien.xin@gmail.com
[ Upstream commit cc4665ca646c96181a7c00198aa72c59e0c576e8 ]
sctp_transport_pl_hlen() is called to calculate the outer header length for PL. However, as the Figure in rfc8899#section-4.4:
Any additional headers .--- MPS -----. | | | v v v +------------------------------+ | IP | ** | PL | protocol data | +------------------------------+
<----- PLPMTU -----> <---------- PMTU -------------->
Outer header are IP + Any additional headers, which doesn't include Packetization Layer itself header, namely sctphdr, whereas sctphdr is counted by __sctp_mtu_payload().
The incorrect calculation caused the link pathmtu to be set larger than expected by t->pl.pmtu + sctp_transport_pl_hlen(). This patch is to fix it by subtracting sctphdr len in sctp_transport_pl_hlen().
Fixes: d9e2e410ae30 ("sctp: add the constants/variables and states and some APIs for transport") 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 --- include/net/sctp/sctp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index bc00410223b03..189fdb9db1622 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -626,7 +626,8 @@ static inline __u32 sctp_min_frag_point(struct sctp_sock *sp, __u16 datasize)
static inline int sctp_transport_pl_hlen(struct sctp_transport *t) { - return __sctp_mtu_payload(sctp_sk(t->asoc->base.sk), t, 0, 0); + return __sctp_mtu_payload(sctp_sk(t->asoc->base.sk), t, 0, 0) - + sizeof(struct sctphdr); }
static inline void sctp_transport_pl_reset(struct sctp_transport *t)
From: Xin Long lucien.xin@gmail.com
[ Upstream commit 75cf662c64dd8543f56c329c69eba18141c8fd9f ]
sctp_transport_pl_toobig() supposes to return true only if there's pathmtu update, so that in sctp_icmp_frag_needed() it would call sctp_assoc_sync_pmtu() and sctp_retransmit(). This patch is to fix these return places in sctp_transport_pl_toobig().
Fixes: 836964083177 ("sctp: do state transition when receiving an icmp TOOBIG packet") 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/sctp/transport.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 1f2dfad768d52..133f1719bf1b7 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -368,6 +368,7 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu)
t->pl.pmtu = SCTP_BASE_PLPMTU; t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); + return true; } } else if (t->pl.state == SCTP_PL_SEARCH) { if (pmtu >= SCTP_BASE_PLPMTU && pmtu < t->pl.pmtu) { @@ -378,11 +379,10 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu) t->pl.probe_high = 0; t->pl.pmtu = SCTP_BASE_PLPMTU; t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); + return true; } else if (pmtu > t->pl.pmtu && pmtu < t->pl.probe_size) { t->pl.probe_size = pmtu; t->pl.probe_count = 0; - - return false; } } else if (t->pl.state == SCTP_PL_COMPLETE) { if (pmtu >= SCTP_BASE_PLPMTU && pmtu < t->pl.pmtu) { @@ -393,10 +393,11 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu) t->pl.probe_high = 0; t->pl.pmtu = SCTP_BASE_PLPMTU; t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); + return true; } }
- return true; + return false; }
bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
From: Shyam Sundar S K Shyam-sundar.S-k@amd.com
[ Upstream commit daf182d360e509a494db18666799f4e85d83dda0 ]
For each rate change command submission, the FW has to do a phy power off sequence internally. For this to happen correctly, the PLL re-initialization control setting has to be turned off before sending mailbox commands and re-enabled once the command submission is complete.
Without the PLL control setting, the link up takes longer time in a fixed phy configuration.
Fixes: 47f164deab22 ("amd-xgbe: Add PCI device support") Co-developed-by: Sudheesh Mavila sudheesh.mavila@amd.com Signed-off-by: Sudheesh Mavila sudheesh.mavila@amd.com Signed-off-by: Shyam Sundar S K Shyam-sundar.S-k@amd.com Acked-by: Tom Lendacky thomas.lendacky@amd.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amd/xgbe/xgbe-common.h | 8 ++++++++ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 20 +++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index b2cd3bdba9f89..533b8519ec352 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -1331,6 +1331,10 @@ #define MDIO_VEND2_PMA_CDR_CONTROL 0x8056 #endif
+#ifndef MDIO_VEND2_PMA_MISC_CTRL0 +#define MDIO_VEND2_PMA_MISC_CTRL0 0x8090 +#endif + #ifndef MDIO_CTRL1_SPEED1G #define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) #endif @@ -1389,6 +1393,10 @@ #define XGBE_PMA_RX_RST_0_RESET_ON 0x10 #define XGBE_PMA_RX_RST_0_RESET_OFF 0x00
+#define XGBE_PMA_PLL_CTRL_MASK BIT(15) +#define XGBE_PMA_PLL_CTRL_ENABLE BIT(15) +#define XGBE_PMA_PLL_CTRL_DISABLE 0x0000 + /* Bit setting and getting macros * The get macro will extract the current bit field value from within * the variable diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index 18e48b3bc402b..213769054391c 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -1977,12 +1977,26 @@ static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata) } }
+static void xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable) +{ + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0, + XGBE_PMA_PLL_CTRL_MASK, + enable ? XGBE_PMA_PLL_CTRL_ENABLE + : XGBE_PMA_PLL_CTRL_DISABLE); + + /* Wait for command to complete */ + usleep_range(100, 200); +} + static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd, unsigned int sub_cmd) { unsigned int s0 = 0; unsigned int wait;
+ /* Disable PLL re-initialization during FW command processing */ + xgbe_phy_pll_ctrl(pdata, false); + /* Log if a previous command did not complete */ if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) { netif_dbg(pdata, link, pdata->netdev, @@ -2003,7 +2017,7 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, wait = XGBE_RATECHANGE_COUNT; while (wait--) { if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) - return; + goto reenable_pll;
usleep_range(1000, 2000); } @@ -2013,6 +2027,10 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
/* Reset on error */ xgbe_phy_rx_reset(pdata); + +reenable_pll: + /* Enable PLL re-initialization */ + xgbe_phy_pll_ctrl(pdata, true); }
static void xgbe_phy_rrc(struct xgbe_prv_data *pdata)
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit f281d010b87454e72475b668ad66e34961f744e0 ]
In the unlikely event where 'devm_kzalloc()' fails and 'kzalloc()' succeeds, 'port' would be leaking.
Test each allocation separately to avoid the leak.
Fixes: 3a3d2f6a4c64 ("ipmi: kcs_bmc: Add serio adaptor") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Message-Id: ecbfa15e94e64f4b878ecab1541ea46c74807670.1631048724.git.christophe.jaillet@wanadoo.fr Reviewed-by: Andrew Jeffery andrew@aj.id.au Signed-off-by: Corey Minyard cminyard@mvista.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/ipmi/kcs_bmc_serio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/char/ipmi/kcs_bmc_serio.c b/drivers/char/ipmi/kcs_bmc_serio.c index 7948cabde50b4..7e2067628a6ce 100644 --- a/drivers/char/ipmi/kcs_bmc_serio.c +++ b/drivers/char/ipmi/kcs_bmc_serio.c @@ -73,10 +73,12 @@ static int kcs_bmc_serio_add_device(struct kcs_bmc_device *kcs_bmc) struct serio *port;
priv = devm_kzalloc(kcs_bmc->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM;
/* Use kzalloc() as the allocation is cleaned up with kfree() via serio_unregister_port() */ port = kzalloc(sizeof(*port), GFP_KERNEL); - if (!(priv && port)) + if (!port) return -ENOMEM;
port->id.type = SERIO_8042;
From: Yinjun Zhang yinjun.zhang@corigine.com
[ Upstream commit f8d384a640dd32aaf0a05fec137ccbf0e986b09f ]
Each rx/tx ring has a related dim work, when rx/tx ring number is decreased by `ethtool -L`, the corresponding rx_ring or tx_ring is assigned NULL, while its related work is not destroyed. When scheduled, the work will access NULL pointer.
Fixes: 9d32e4e7e9e1 ("nfp: add support for coalesce adaptive feature") Signed-off-by: Yinjun Zhang yinjun.zhang@corigine.com Signed-off-by: Louis Peens louis.peens@corigine.com Signed-off-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 5bfa22accf2c9..f8b880c8e5148 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -2067,7 +2067,7 @@ static int nfp_net_poll(struct napi_struct *napi, int budget) if (napi_complete_done(napi, pkts_polled)) nfp_net_irq_unmask(r_vec->nfp_net, r_vec->irq_entry);
- if (r_vec->nfp_net->rx_coalesce_adapt_on) { + if (r_vec->nfp_net->rx_coalesce_adapt_on && r_vec->rx_ring) { struct dim_sample dim_sample = {}; unsigned int start; u64 pkts, bytes; @@ -2082,7 +2082,7 @@ static int nfp_net_poll(struct napi_struct *napi, int budget) net_dim(&r_vec->rx_dim, dim_sample); }
- if (r_vec->nfp_net->tx_coalesce_adapt_on) { + if (r_vec->nfp_net->tx_coalesce_adapt_on && r_vec->tx_ring) { struct dim_sample dim_sample = {}; unsigned int start; u64 pkts, bytes;
From: Yinjun Zhang yinjun.zhang@corigine.com
[ Upstream commit 17e712c6a1bade9dac02a7bf2b464746faa7e9a0 ]
When port is linked down, the process which has acquired rtnl_lock will wait for the in-progress dim work to finish, and the work also acquires rtnl_lock, which may cause deadlock.
Currently IRQ_MOD registers can be configured by `ethtool -C` and dim work, and which will take effect depends on the execution order, rtnl_lock is useless here, so remove them.
Fixes: 9d32e4e7e9e1 ("nfp: add support for coalesce adaptive feature") Signed-off-by: Yinjun Zhang yinjun.zhang@corigine.com Signed-off-by: Louis Peens louis.peens@corigine.com Signed-off-by: Simon Horman simon.horman@corigine.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index f8b880c8e5148..850bfdf83d0a4 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -3016,10 +3016,8 @@ static void nfp_net_rx_dim_work(struct work_struct *work)
/* copy RX interrupt coalesce parameters */ value = (moder.pkts << 16) | (factor * moder.usec); - rtnl_lock(); nn_writel(nn, NFP_NET_CFG_RXR_IRQ_MOD(r_vec->rx_ring->idx), value); (void)nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_IRQMOD); - rtnl_unlock();
dim->state = DIM_START_MEASURE; } @@ -3047,10 +3045,8 @@ static void nfp_net_tx_dim_work(struct work_struct *work)
/* copy TX interrupt coalesce parameters */ value = (moder.pkts << 16) | (factor * moder.usec); - rtnl_lock(); nn_writel(nn, NFP_NET_CFG_TXR_IRQ_MOD(r_vec->tx_ring->idx), value); (void)nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_IRQMOD); - rtnl_unlock();
dim->state = DIM_START_MEASURE; }
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
[ Upstream commit fd8d9731bcdfb22d28e45bce789bcb211c868c78 ]
mvneta does not support asymetric pause modes, and it flags this by the lack of AsymPause in the supported field. When setting pause modes, we check that pause->rx_pause == pause->tx_pause, but only when pause autoneg is enabled. When pause autoneg is disabled, we still allow pause->rx_pause != pause->tx_pause, which is incorrect when the MAC does not support asymetric pause, and causes mvneta to issue a warning.
Fix this by removing the test for pause->autoneg, so we always check that pause->rx_pause == pause->tx_pause for network devices that do not support AsymPause.
Fixes: 9525ae83959b ("phylink: add phylink infrastructure") Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phylink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 5a58c77d00022..7ec3105010ac1 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1727,7 +1727,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, return -EOPNOTSUPP;
if (!phylink_test(pl->supported, Asym_Pause) && - !pause->autoneg && pause->rx_pause != pause->tx_pause) + pause->rx_pause != pause->tx_pause) return -EINVAL;
pause_state = 0;
From: Ivan Vecera ivecera@redhat.com
[ Upstream commit 829e050eea69c7442441b714b6f5b339b5b8c367 ]
Function br_get_link_af_size_filtered() calls br_cfm_{,peer}_mep_count() that return a count. When BRIDGE_CFM is not enabled these functions simply return -EOPNOTSUPP but do not modify count parameter and calling function then works with uninitialized variables. Modify these inline functions to return zero in count parameter.
Fixes: b6d0425b816e ("bridge: cfm: Netlink Notifications.") Cc: Henrik Bjoernlund henrik.bjoernlund@microchip.com Signed-off-by: Ivan Vecera ivecera@redhat.com Acked-by: Nikolay Aleksandrov nikolay@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/bridge/br_private.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 37ca76406f1e8..fd5e7e74573ce 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -1911,11 +1911,13 @@ static inline int br_cfm_status_fill_info(struct sk_buff *skb,
static inline int br_cfm_mep_count(struct net_bridge *br, u32 *count) { + *count = 0; return -EOPNOTSUPP; }
static inline int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count) { + *count = 0; return -EOPNOTSUPP; } #endif
From: Nikolay Aleksandrov nikolay@nvidia.com
[ Upstream commit 34d7ecb3d4f772eb00ce1f7195ae30886ddf4d2e ]
When I fixed IGMPv3/MLDv2 to use the bridge's multicast_membership_interval value which is chosen by user-space instead of calculating it based on multicast_query_interval and multicast_query_response_interval I forgot to update the selftests relying on that behaviour. Now we have to manually set the expected GMI value to perform the tests correctly and get proper results (similar to IGMPv2 behaviour).
Fixes: fac3cb82a54a ("net: bridge: mcast: use multicast_membership_interval for IGMPv3") Signed-off-by: Nikolay Aleksandrov nikolay@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../testing/selftests/net/forwarding/bridge_igmp.sh | 12 +++++++++--- tools/testing/selftests/net/forwarding/bridge_mld.sh | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/tools/testing/selftests/net/forwarding/bridge_igmp.sh b/tools/testing/selftests/net/forwarding/bridge_igmp.sh index 675eff45b0371..1162836f8f329 100755 --- a/tools/testing/selftests/net/forwarding/bridge_igmp.sh +++ b/tools/testing/selftests/net/forwarding/bridge_igmp.sh @@ -482,10 +482,15 @@ v3exc_timeout_test() local X=("192.0.2.20" "192.0.2.30")
# GMI should be 3 seconds - ip link set dev br0 type bridge mcast_query_interval 100 mcast_query_response_interval 100 + ip link set dev br0 type bridge mcast_query_interval 100 \ + mcast_query_response_interval 100 \ + mcast_membership_interval 300
v3exclude_prepare $h1 $ALL_MAC $ALL_GROUP - ip link set dev br0 type bridge mcast_query_interval 500 mcast_query_response_interval 500 + ip link set dev br0 type bridge mcast_query_interval 500 \ + mcast_query_response_interval 500 \ + mcast_membership_interval 1500 + $MZ $h1 -c 1 -b $ALL_MAC -B $ALL_GROUP -t ip "proto=2,p=$MZPKT_ALLOW2" -q sleep 3 bridge -j -d -s mdb show dev br0 \ @@ -517,7 +522,8 @@ v3exc_timeout_test() log_test "IGMPv3 group $TEST_GROUP exclude timeout"
ip link set dev br0 type bridge mcast_query_interval 12500 \ - mcast_query_response_interval 1000 + mcast_query_response_interval 1000 \ + mcast_membership_interval 26000
v3cleanup $swp1 $TEST_GROUP } diff --git a/tools/testing/selftests/net/forwarding/bridge_mld.sh b/tools/testing/selftests/net/forwarding/bridge_mld.sh index ffdcfa87ca2ba..e2b9ff773c6b6 100755 --- a/tools/testing/selftests/net/forwarding/bridge_mld.sh +++ b/tools/testing/selftests/net/forwarding/bridge_mld.sh @@ -479,10 +479,15 @@ mldv2exc_timeout_test() local X=("2001:db8:1::20" "2001:db8:1::30")
# GMI should be 3 seconds - ip link set dev br0 type bridge mcast_query_interval 100 mcast_query_response_interval 100 + ip link set dev br0 type bridge mcast_query_interval 100 \ + mcast_query_response_interval 100 \ + mcast_membership_interval 300
mldv2exclude_prepare $h1 - ip link set dev br0 type bridge mcast_query_interval 500 mcast_query_response_interval 500 + ip link set dev br0 type bridge mcast_query_interval 500 \ + mcast_query_response_interval 500 \ + mcast_membership_interval 1500 + $MZ $h1 -c 1 $MZPKT_ALLOW2 -q sleep 3 bridge -j -d -s mdb show dev br0 \ @@ -514,7 +519,8 @@ mldv2exc_timeout_test() log_test "MLDv2 group $TEST_GROUP exclude timeout"
ip link set dev br0 type bridge mcast_query_interval 12500 \ - mcast_query_response_interval 1000 + mcast_query_response_interval 1000 \ + mcast_membership_interval 26000
mldv2cleanup $swp1 }
From: Daniel Jordan daniel.m.jordan@oracle.com
[ Upstream commit 68b6dea802cea0dbdd8bd7ccc60716b5a32a5d8a ]
These three events can race when pcrypt is used multiple times in a template ("pcrypt(pcrypt(...))"):
1. [taskA] The caller makes the crypto request via crypto_aead_encrypt() 2. [kworkerB] padata serializes the inner pcrypt request 3. [kworkerC] padata serializes the outer pcrypt request
3 might finish before the call to crypto_aead_encrypt() returns in 1, resulting in two possible issues.
First, a use-after-free of the crypto request's memory when, for example, taskA writes to the outer pcrypt request's padata->info in pcrypt_aead_enc() after kworkerC completes the request.
Second, the outer pcrypt request overwrites the inner pcrypt request's return code with -EINPROGRESS, making a successful request appear to fail. For instance, kworkerB writes the outer pcrypt request's padata->info in pcrypt_aead_done() and then taskA overwrites it in pcrypt_aead_enc().
Avoid both situations by delaying the write of padata->info until after the inner crypto request's return code is checked. This prevents the use-after-free by not touching the crypto request's memory after the next-inner crypto request is made, and stops padata->info from being overwritten.
Fixes: 5068c7a883d16 ("crypto: pcrypt - Add pcrypt crypto parallelization wrapper") Reported-by: syzbot+b187b77c8474f9648fae@syzkaller.appspotmail.com Signed-off-by: Daniel Jordan daniel.m.jordan@oracle.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/pcrypt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index d569c7ed6c800..9d10b846ccf73 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c @@ -78,12 +78,14 @@ static void pcrypt_aead_enc(struct padata_priv *padata) { struct pcrypt_request *preq = pcrypt_padata_request(padata); struct aead_request *req = pcrypt_request_ctx(preq); + int ret;
- padata->info = crypto_aead_encrypt(req); + ret = crypto_aead_encrypt(req);
- if (padata->info == -EINPROGRESS) + if (ret == -EINPROGRESS) return;
+ padata->info = ret; padata_do_serial(padata); }
@@ -123,12 +125,14 @@ static void pcrypt_aead_dec(struct padata_priv *padata) { struct pcrypt_request *preq = pcrypt_padata_request(padata); struct aead_request *req = pcrypt_request_ctx(preq); + int ret;
- padata->info = crypto_aead_decrypt(req); + ret = crypto_aead_decrypt(req);
- if (padata->info == -EINPROGRESS) + if (ret == -EINPROGRESS) return;
+ padata->info = ret; padata_do_serial(padata); }
From: Andrea Righi andrea.righi@canonical.com
[ Upstream commit f48ad69097fe79d1de13c4d8fef556d4c11c5e68 ]
Make sure to use pclose() to properly close the pipe opened by popen().
Fixes: 81f77fd0deeb ("bpf: add selftest for stackmap with BPF_F_STACK_BUILD_ID") Signed-off-by: Andrea Righi andrea.righi@canonical.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Shuah Khan skhan@linuxfoundation.org Acked-by: Martin KaFai Lau kafai@fb.com Link: https://lore.kernel.org/bpf/20211026143409.42666-1-andrea.righi@canonical.co... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_progs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index cc1cd240445d2..e3fea6f281e4b 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -370,7 +370,7 @@ int extract_build_id(char *build_id, size_t size)
if (getline(&line, &len, fp) == -1) goto err; - fclose(fp); + pclose(fp);
if (len > size) len = size; @@ -379,7 +379,7 @@ int extract_build_id(char *build_id, size_t size) free(line); return 0; err: - fclose(fp); + pclose(fp); return -1; }
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 42dcfd850e514b229d616a53dec06d0f2533217c ]
Commit c6af0c227a22 ("ip: support SO_MARK cmsg") added propagation of SO_MARK from cmsg to skb->mark. For IPv4 and raw sockets the mark also affects route lookup, but in case of IPv6 the flow info is initialized before cmsg is parsed.
Fixes: c6af0c227a22 ("ip: support SO_MARK cmsg") Reported-and-tested-by: Xintong Hu huxintong@fb.com Signed-off-by: Jakub Kicinski kuba@kernel.org Reviewed-by: David Ahern dsahern@kernel.org 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 --- net/ipv6/udp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 8d785232b4796..be6dc64ece29f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1435,7 +1435,6 @@ do_udp_sendmsg: if (!fl6.flowi6_oif) fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
- fl6.flowi6_mark = ipc6.sockc.mark; fl6.flowi6_uid = sk->sk_uid;
if (msg->msg_controllen) { @@ -1471,6 +1470,7 @@ do_udp_sendmsg: ipc6.opt = opt;
fl6.flowi6_proto = sk->sk_protocol; + fl6.flowi6_mark = ipc6.sockc.mark; fl6.daddr = *daddr; if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) fl6.saddr = np->saddr;
From: Sukadev Bhattiprolu sukadev@linux.ibm.com
[ Upstream commit 8878e46fcfd46b19964bd90e13b25dd94cbfc9be ]
If adapter's resetting bit is on, discard the packet but don't stop the transmit queue - instead leave that to the reset code. With this change, it is possible that we may get several calls to ibmvnic_xmit() that simply discard packets and return.
But if we stop the queue here, we might end up doing so just after __ibmvnic_open() started the queues (during a hard/soft reset) and before the ->resetting bit was cleared. If that happens, there will be no one to restart queue and transmissions will be blocked indefinitely.
This can cause a TIMEOUT reset and with auto priority failover enabled, an unnecessary FAILOVER reset to less favored backing device and then a FAILOVER back to the most favored backing device. If we hit the window repeatedly, we can get stuck in a loop of TIMEOUT, FAILOVER, FAILOVER resets leaving the adapter unusable for extended periods of time.
Fixes: 7f5b030830fe ("ibmvnic: Free skb's in cases of failure in transmit") Reported-by: Abdul Haleem abdhalee@in.ibm.com Reported-by: Vaishnavi Bhat vaish123@in.ibm.com Signed-off-by: Sukadev Bhattiprolu sukadev@linux.ibm.com Reviewed-by: Dany Madden drt@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ibm/ibmvnic.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 6aa6ff89a7651..7438138c3766a 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -1724,8 +1724,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) ind_bufp = &tx_scrq->ind_buf;
if (test_bit(0, &adapter->resetting)) { - if (!netif_subqueue_stopped(netdev, skb)) - netif_stop_subqueue(netdev, queue_num); dev_kfree_skb_any(skb);
tx_send_failed++;
From: Sukadev Bhattiprolu sukadev@linux.ibm.com
[ Upstream commit 6e20d00158f31f7631d68b86996b7e951c4451c8 ]
Soon after registering a CRQ it is possible that we get a fail over or maybe a CRQ_INIT from the VIOS while interrupts were disabled.
Look for any such CRQs after enabling interrupts.
Otherwise we can intermittently fail to bring up ibmvnic adapters during boot, specially in kexec/kdump kernels.
Fixes: 032c5e82847a ("Driver for IBM System i/p VNIC protocol") Reported-by: Vaishnavi Bhat vaish123@in.ibm.com Signed-off-by: Sukadev Bhattiprolu sukadev@linux.ibm.com Reviewed-by: Dany Madden drt@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ibm/ibmvnic.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 7438138c3766a..84961a83803b7 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -5412,6 +5412,9 @@ static int init_crq_queue(struct ibmvnic_adapter *adapter) crq->cur = 0; spin_lock_init(&crq->lock);
+ /* process any CRQs that were queued before we enabled interrupts */ + tasklet_schedule(&adapter->tasklet); + return retrc;
req_irq_failed:
From: Sukadev Bhattiprolu sukadev@linux.ibm.com
[ Upstream commit 6b278c0cb378079f3c0c61ae4a369c09ff1a4188 ]
If we get CRQ_INIT, we set errno to -EIO and first call complete() to notify the waiter. Then we try to schedule a FAILOVER reset. If this occurs while adapter is in PROBING state, ibmvnic_reset() changes the error code to EAGAIN and returns without scheduling the FAILOVER. The purpose of setting error code to EAGAIN is to ask the waiter to retry.
But due to the earlier complete() call, the waiter may already have seen the -EIO response and decided not to retry. This can cause intermittent failures when bringing up ibmvnic adapters during boot, specially in in kexec/kdump kernels.
Defer the complete() call until after scheduling the reset.
Also streamline the error code to EAGAIN. Don't see why we need EIO sometimes. All 3 callers of ibmvnic_reset_init() can handle EAGAIN.
Fixes: 17c8705838a5 ("ibmvnic: Return error code if init interrupted by transport event") Reported-by: Vaishnavi Bhat vaish123@in.ibm.com Signed-off-by: Sukadev Bhattiprolu sukadev@linux.ibm.com Reviewed-by: Dany Madden drt@linux.ibm.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ibm/ibmvnic.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 84961a83803b7..352ffe982d849 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -2565,7 +2565,7 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
if (adapter->state == VNIC_PROBING) { netdev_warn(netdev, "Adapter reset during probe\n"); - adapter->init_done_rc = EAGAIN; + adapter->init_done_rc = -EAGAIN; ret = EAGAIN; goto err; } @@ -5067,11 +5067,6 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, */ adapter->login_pending = false;
- if (!completion_done(&adapter->init_done)) { - complete(&adapter->init_done); - adapter->init_done_rc = -EIO; - } - if (adapter->state == VNIC_DOWN) rc = ibmvnic_reset(adapter, VNIC_RESET_PASSIVE_INIT); else @@ -5092,6 +5087,13 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq, rc); adapter->failover_pending = false; } + + if (!completion_done(&adapter->init_done)) { + complete(&adapter->init_done); + if (!adapter->init_done_rc) + adapter->init_done_rc = -EAGAIN; + } + break; case IBMVNIC_CRQ_INIT_COMPLETE: dev_info(dev, "Partner initialization complete\n"); @@ -5559,7 +5561,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) }
rc = ibmvnic_reset_init(adapter, false); - } while (rc == EAGAIN); + } while (rc == -EAGAIN);
/* We are ignoring the error from ibmvnic_reset_init() assuming that the * partner is not ready. CRQ is not active. When the partner becomes
From: Geliang Tang geliang.tang@suse.com
[ Upstream commit 7c909a98042ce403c8497c5d6ff94dd53bdd2131 ]
In listener_ns, we should pass srv_proto argument to mptcp_connect command, not cl_proto.
Fixes: 7d1e6f1639044 ("selftests: mptcp: add testcase for active-back") Signed-off-by: Geliang Tang geliang.tang@suse.com Signed-off-by: Matthieu Baerts matthieu.baerts@tessares.net Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/mptcp/mptcp_join.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index 255793c5ac4ff..586af88194e56 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -297,7 +297,7 @@ do_transfer() if [ "$test_link_fail" -eq 2 ];then timeout ${timeout_test} \ ip netns exec ${listener_ns} \ - $mptcp_connect -t ${timeout_poll} -l -p $port -s ${cl_proto} \ + $mptcp_connect -t ${timeout_poll} -l -p $port -s ${srv_proto} \ ${local_addr} < "$sinfail" > "$sout" & else timeout ${timeout_test} \
From: Liu Jian liujian56@huawei.com
[ Upstream commit 7303524e04af49a47991e19f895c3b8cdc3796c7 ]
If sockmap enable strparser, there are lose offset info in sk_psock_skb_ingress(). If the length determined by parse_msg function is not skb->len, the skb will be converted to sk_msg multiple times, and userspace app will get the data multiple times.
Fix this by get the offset and length from strp_msg. And as Cong suggested, add one bit in skb->_sk_redir to distinguish enable or disable strparser.
Fixes: 604326b41a6fb ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: Liu Jian liujian56@huawei.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Cong Wang cong.wang@bytedance.com Acked-by: John Fastabend john.fastabend@gmail.com Link: https://lore.kernel.org/bpf/20211029141216.211899-1-liujian56@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/skmsg.h | 18 ++++++++++++++++-- net/core/skmsg.c | 43 +++++++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 12 deletions(-)
diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index 1ce9a9eb223b6..b4256847c7079 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -509,8 +509,22 @@ static inline bool sk_psock_strp_enabled(struct sk_psock *psock)
#if IS_ENABLED(CONFIG_NET_SOCK_MSG)
-/* We only have one bit so far. */ -#define BPF_F_PTR_MASK ~(BPF_F_INGRESS) +#define BPF_F_STRPARSER (1UL << 1) + +/* We only have two bits so far. */ +#define BPF_F_PTR_MASK ~(BPF_F_INGRESS | BPF_F_STRPARSER) + +static inline bool skb_bpf_strparser(const struct sk_buff *skb) +{ + unsigned long sk_redir = skb->_sk_redir; + + return sk_redir & BPF_F_STRPARSER; +} + +static inline void skb_bpf_set_strparser(struct sk_buff *skb) +{ + skb->_sk_redir |= BPF_F_STRPARSER; +}
static inline bool skb_bpf_ingress(const struct sk_buff *skb) { diff --git a/net/core/skmsg.c b/net/core/skmsg.c index a86ef7e844f8c..1ae52ac943f62 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -508,6 +508,7 @@ static struct sk_msg *sk_psock_create_ingress_msg(struct sock *sk, }
static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, + u32 off, u32 len, struct sk_psock *psock, struct sock *sk, struct sk_msg *msg) @@ -521,11 +522,11 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, */ if (skb_linearize(skb)) return -EAGAIN; - num_sge = skb_to_sgvec(skb, msg->sg.data, 0, skb->len); + num_sge = skb_to_sgvec(skb, msg->sg.data, off, len); if (unlikely(num_sge < 0)) return num_sge;
- copied = skb->len; + copied = len; msg->sg.start = 0; msg->sg.size = copied; msg->sg.end = num_sge; @@ -536,9 +537,11 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb, return copied; }
-static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb); +static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb, + u32 off, u32 len);
-static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) +static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb, + u32 off, u32 len) { struct sock *sk = psock->sk; struct sk_msg *msg; @@ -549,7 +552,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) * correctly. */ if (unlikely(skb->sk == sk)) - return sk_psock_skb_ingress_self(psock, skb); + return sk_psock_skb_ingress_self(psock, skb, off, len); msg = sk_psock_create_ingress_msg(sk, skb); if (!msg) return -EAGAIN; @@ -561,7 +564,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) * into user buffers. */ skb_set_owner_r(skb, sk); - err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg); + err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg); if (err < 0) kfree(msg); return err; @@ -571,7 +574,8 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) * skb. In this case we do not need to check memory limits or skb_set_owner_r * because the skb is already accounted for here. */ -static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb) +static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb, + u32 off, u32 len) { struct sk_msg *msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_ATOMIC); struct sock *sk = psock->sk; @@ -581,7 +585,7 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb return -EAGAIN; sk_msg_init(msg); skb_set_owner_r(skb, sk); - err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg); + err = sk_psock_skb_ingress_enqueue(skb, off, len, psock, sk, msg); if (err < 0) kfree(msg); return err; @@ -595,7 +599,7 @@ static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, return -EAGAIN; return skb_send_sock(psock->sk, skb, off, len); } - return sk_psock_skb_ingress(psock, skb); + return sk_psock_skb_ingress(psock, skb, off, len); }
static void sk_psock_skb_state(struct sk_psock *psock, @@ -638,6 +642,12 @@ static void sk_psock_backlog(struct work_struct *work) while ((skb = skb_dequeue(&psock->ingress_skb))) { len = skb->len; off = 0; + if (skb_bpf_strparser(skb)) { + struct strp_msg *stm = strp_msg(skb); + + off = stm->offset; + len = stm->full_len; + } start: ingress = skb_bpf_ingress(skb); skb_bpf_redirect_clear(skb); @@ -877,6 +887,7 @@ static int sk_psock_skb_redirect(struct sk_psock *from, struct sk_buff *skb) * return code, but then didn't set a redirect interface. */ if (unlikely(!sk_other)) { + skb_bpf_redirect_clear(skb); sock_drop(from->sk, skb); return -EIO; } @@ -944,6 +955,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb, { struct sock *sk_other; int err = 0; + u32 len, off;
switch (verdict) { case __SK_PASS: @@ -951,6 +963,7 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb, sk_other = psock->sk; if (sock_flag(sk_other, SOCK_DEAD) || !sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) { + skb_bpf_redirect_clear(skb); goto out_free; }
@@ -963,7 +976,15 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb, * retrying later from workqueue. */ if (skb_queue_empty(&psock->ingress_skb)) { - err = sk_psock_skb_ingress_self(psock, skb); + len = skb->len; + off = 0; + if (skb_bpf_strparser(skb)) { + struct strp_msg *stm = strp_msg(skb); + + off = stm->offset; + len = stm->full_len; + } + err = sk_psock_skb_ingress_self(psock, skb, off, len); } if (err < 0) { spin_lock_bh(&psock->ingress_lock); @@ -1029,6 +1050,8 @@ static void sk_psock_strp_read(struct strparser *strp, struct sk_buff *skb) skb_dst_drop(skb); skb_bpf_redirect_clear(skb); ret = bpf_prog_run_pin_on_cpu(prog, skb); + if (ret == SK_PASS) + skb_bpf_set_strparser(skb); ret = sk_psock_map_verd(ret, skb_bpf_redirect_fetch(skb)); skb->sk = NULL; }
From: Dan Schatzberg schatzberg.dan@gmail.com
[ Upstream commit 81c49d39aea8a10e6d05d3aa1cb65ceb721e19b0 ]
In account_guest_time in kernel/sched/cputime.c guest time is attributed to both CPUTIME_NICE and CPUTIME_USER in addition to CPUTIME_GUEST_NICE and CPUTIME_GUEST respectively. Therefore, adding both to calculate usage results in double counting any guest time at the rootcg.
Fixes: 936f2a70f207 ("cgroup: add cpu.stat file to root cgroup") Signed-off-by: Dan Schatzberg schatzberg.dan@gmail.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cgroup/rstat.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c index b264ab5652ba9..1486768f23185 100644 --- a/kernel/cgroup/rstat.c +++ b/kernel/cgroup/rstat.c @@ -433,8 +433,6 @@ static void root_cgroup_cputime(struct task_cputime *cputime) cputime->sum_exec_runtime += user; cputime->sum_exec_runtime += sys; cputime->sum_exec_runtime += cpustat[CPUTIME_STEAL]; - cputime->sum_exec_runtime += cpustat[CPUTIME_GUEST]; - cputime->sum_exec_runtime += cpustat[CPUTIME_GUEST_NICE]; } }
From: Alexei Starovoitov ast@kernel.org
[ Upstream commit b9979db8340154526d9ab38a1883d6f6ba9b6d47 ]
Before this fix: 166: (b5) if r2 <= 0x1 goto pc+22 from 166 to 189: R2=invP(id=1,umax_value=1,var_off=(0x0; 0xffffffff))
After this fix: 166: (b5) if r2 <= 0x1 goto pc+22 from 166 to 189: R2=invP(id=1,umax_value=1,var_off=(0x0; 0x1))
While processing BPF_JLE the reg_set_min_max() would set true_reg->umax_value = 1 and call __reg_combine_64_into_32(true_reg).
Without the fix it would not pass the condition: if (__reg64_bound_u32(reg->umin_value) && __reg64_bound_u32(reg->umax_value))
since umin_value == 0 at this point. Before commit 10bf4e83167c the umin was incorrectly ingored. The commit 10bf4e83167c fixed the correctness issue, but pessimized propagation of 64-bit min max into 32-bit min max and corresponding var_off.
Fixes: 10bf4e83167c ("bpf: Fix propagation of 32 bit unsigned bounds from 64 bit bounds") Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20211101222153.78759-1-alexei.starovoitov@gmail.... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 2 +- tools/testing/selftests/bpf/verifier/array_access.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index e76b559179054..055012faca94e 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1411,7 +1411,7 @@ static bool __reg64_bound_s32(s64 a)
static bool __reg64_bound_u32(u64 a) { - return a > U32_MIN && a < U32_MAX; + return a >= U32_MIN && a <= U32_MAX; }
static void __reg_combine_64_into_32(struct bpf_reg_state *reg) diff --git a/tools/testing/selftests/bpf/verifier/array_access.c b/tools/testing/selftests/bpf/verifier/array_access.c index 1b1c798e92489..1b138cd2b187d 100644 --- a/tools/testing/selftests/bpf/verifier/array_access.c +++ b/tools/testing/selftests/bpf/verifier/array_access.c @@ -186,7 +186,7 @@ }, .fixup_map_hash_48b = { 3 }, .errstr_unpriv = "R0 leaks addr", - .errstr = "R0 unbounded memory access", + .errstr = "invalid access to map value, value_size=48 off=44 size=8", .result_unpriv = REJECT, .result = REJECT, .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
From: Alexei Starovoitov ast@kernel.org
[ Upstream commit 388e2c0b978339dee9b0a81a2e546f8979e021e2 ]
Similar to unsigned bounds propagation fix signed bounds. The 'Fixes' tag is a hint. There is no security bug here. The verifier was too conservative.
Fixes: 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking") Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20211101222153.78759-2-alexei.starovoitov@gmail.... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 055012faca94e..ddba80554fef3 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1406,7 +1406,7 @@ static void __reg_combine_32_into_64(struct bpf_reg_state *reg)
static bool __reg64_bound_s32(s64 a) { - return a > S32_MIN && a < S32_MAX; + return a >= S32_MIN && a <= S32_MAX; }
static bool __reg64_bound_u32(u64 a)
From: Frank Rowand frank.rowand@sony.com
[ Upstream commit e85860e5bc077865a04f0a88d0b0335d3200484a ]
The console message text for gpio hog errors does not match what unittest expects.
Fixes: f4056e705b2ef ("of: unittest: add overlay gpio test to catch gpio hog problem") Signed-off-by: Frank Rowand frank.rowand@sony.com Link: https://lore.kernel.org/r/20211029013225.2048695-1-frowand.list@gmail.com Signed-off-by: Rob Herring robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/unittest.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 8c056972a6ddc..5b85a2a3792ae 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1688,19 +1688,19 @@ static void __init of_unittest_overlay_gpio(void) */
EXPECT_BEGIN(KERN_INFO, - "GPIO line <<int>> (line-B-input) hogged as input\n"); + "gpio-<<int>> (line-B-input): hogged as input\n");
EXPECT_BEGIN(KERN_INFO, - "GPIO line <<int>> (line-A-input) hogged as input\n"); + "gpio-<<int>> (line-A-input): hogged as input\n");
ret = platform_driver_register(&unittest_gpio_driver); if (unittest(ret == 0, "could not register unittest gpio driver\n")) return;
EXPECT_END(KERN_INFO, - "GPIO line <<int>> (line-A-input) hogged as input\n"); + "gpio-<<int>> (line-A-input): hogged as input\n"); EXPECT_END(KERN_INFO, - "GPIO line <<int>> (line-B-input) hogged as input\n"); + "gpio-<<int>> (line-B-input): hogged as input\n");
unittest(probe_pass_count + 2 == unittest_gpio_probe_pass_count, "unittest_gpio_probe() failed or not called\n"); @@ -1727,7 +1727,7 @@ static void __init of_unittest_overlay_gpio(void) chip_request_count = unittest_gpio_chip_request_count;
EXPECT_BEGIN(KERN_INFO, - "GPIO line <<int>> (line-D-input) hogged as input\n"); + "gpio-<<int>> (line-D-input): hogged as input\n");
/* overlay_gpio_03 contains gpio node and child gpio hog node */
@@ -1735,7 +1735,7 @@ static void __init of_unittest_overlay_gpio(void) "Adding overlay 'overlay_gpio_03' failed\n");
EXPECT_END(KERN_INFO, - "GPIO line <<int>> (line-D-input) hogged as input\n"); + "gpio-<<int>> (line-D-input): hogged as input\n");
unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count, "unittest_gpio_probe() failed or not called\n"); @@ -1774,7 +1774,7 @@ static void __init of_unittest_overlay_gpio(void) */
EXPECT_BEGIN(KERN_INFO, - "GPIO line <<int>> (line-C-input) hogged as input\n"); + "gpio-<<int>> (line-C-input): hogged as input\n");
/* overlay_gpio_04b contains child gpio hog node */
@@ -1782,7 +1782,7 @@ static void __init of_unittest_overlay_gpio(void) "Adding overlay 'overlay_gpio_04b' failed\n");
EXPECT_END(KERN_INFO, - "GPIO line <<int>> (line-C-input) hogged as input\n"); + "gpio-<<int>> (line-C-input): hogged as input\n");
unittest(chip_request_count + 1 == unittest_gpio_chip_request_count, "unittest_gpio_chip_request() called %d times (expected 1 time)\n",
From: Hector.Yuan hector.yuan@mediatek.com
[ Upstream commit 4a08e3271c55f8b5d56906a8aa5bd041911cf897 ]
Pass cpu to parse_perf_domain() instead of pcpu.
Fixes: 8486a32dd484 ("cpufreq: Add of_perf_domain_get_sharing_cpumask") Signed-off-by: Hector.Yuan hector.yuan@mediatek.com [ Viresh: Massaged changelog ] Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/cpufreq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index ff88bb3e44fca..66a1f495f01a6 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -1041,7 +1041,7 @@ static inline int of_perf_domain_get_sharing_cpumask(int pcpu, const char *list_ if (cpu == pcpu) continue;
- ret = parse_perf_domain(pcpu, list_name, cell_name); + ret = parse_perf_domain(cpu, list_name, cell_name); if (ret < 0) continue;
From: Pavel Skripkin paskripkin@gmail.com
[ Upstream commit 393db0f6827f96054a769ba3a38aa382d137d3c7 ]
Before returning with an error we should free allocated buffers, since they are not assigned to anywhere.
Fixes: 15865124feed ("staging: r8188eu: introduce new core dir for RTL8188eu driver") Signed-off-by: Pavel Skripkin paskripkin@gmail.com Link: https://lore.kernel.org/r/ee783fbb71abb549505b84542223be7a7c905eea.163069237... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/r8188eu/core/rtw_mlme.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c index 1115ff5d865ad..bd991d7ed8090 100644 --- a/drivers/staging/r8188eu/core/rtw_mlme.c +++ b/drivers/staging/r8188eu/core/rtw_mlme.c @@ -1722,6 +1722,8 @@ int rtw_set_key(struct adapter *adapter, struct security_priv *psecuritypriv, in psetkeyparm->grpkey = 1; break; default: + kfree(psetkeyparm); + kfree(pcmd); res = _FAIL; goto exit; }
From: Dongjin Kim tobetter@gmail.com
[ Upstream commit 9d02214f8332d5dbbcce3d6c5c915e54d43a0c46 ]
This patch is to fix an issue that the ethernet link doesn't come up when using ip link set down/up: [ 11.428114] meson8b-dwmac ff3f0000.ethernet eth0: Link is Down [ 14.428595] meson8b-dwmac ff3f0000.ethernet eth0: PHY [0.0:00] driver [RTL8211F Gigabit Ethernet] (irq=31) [ 14.428610] meson8b-dwmac ff3f0000.ethernet: Failed to reset the dma [ 14.428974] meson8b-dwmac ff3f0000.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed [ 14.711185] meson8b-dwmac ff3f0000.ethernet eth0: stmmac_open: Hw setup failed
This fix refers to two commits applied for ODROID-N2 (G12B). commit 658e4129bb81 ("arm64: dts: meson: g12b: odroid-n2: add the Ethernet PHY reset line") commit 1c7412530d5d0 ("arm64: dts: meson: g12b: odroid-n2: fix PHY deassert timing requirements")
Fixes: 88d537bc92ca ("arm64: dts: meson: convert meson-sm1-odroid-c4 to dtsi") Signed-off-by: Dongjin Kim tobetter@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com [narmstrong: added fixes tag and typo in commit log] Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/YScKYFWlYymgGw3l@anyang-linuxfactory-or-kr Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi index fd0ad85c165ba..45e7fcb062f96 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi @@ -263,6 +263,10 @@ reg = <0>; max-speed = <1000>;
+ reset-assert-us = <10000>; + reset-deassert-us = <80000>; + reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + interrupt-parent = <&gpio_intc>; /* MAC_INTR on GPIOZ_14 */ interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
From: Alexandru Ardelean aardelean@deviqon.com
[ Upstream commit 9f0b3e0cc0c88618aa9e5cecef747b1337ae0a5d ]
Up until commit ea7e586bdd331 ("iio: st_sensors: move regulator retrieveal to core") only the ST pressure driver seems to have had any regulator disable. After that commit, the regulator handling was moved into the common st_sensors logic.
In all instances of this regulator handling, the regulators were disabled before unregistering the IIO device. This can cause issues where the device would be powered down and still be available to userspace, allowing it to send invalid/garbage data.
This change moves the st_sensors_power_disable() after the common probe functions. These common probe functions also handle unregistering the IIO device.
Fixes: 774487611c949 ("iio: pressure-core: st: Provide support for the Vdd power supply") Fixes: ea7e586bdd331 ("iio: st_sensors: move regulator retrieveal to core") Cc: Lee Jones lee.jones@linaro.org Cc: Denis CIOCCA denis.ciocca@st.com Reviewed-by: Linus Walleij linus.walleij@linaro.org Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Alexandru Ardelean aardelean@deviqon.com Link: https://lore.kernel.org/r/20210823112204.243255-2-aardelean@deviqon.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/accel/st_accel_i2c.c | 4 ++-- drivers/iio/accel/st_accel_spi.c | 4 ++-- drivers/iio/gyro/st_gyro_i2c.c | 4 ++-- drivers/iio/gyro/st_gyro_spi.c | 4 ++-- drivers/iio/magnetometer/st_magn_i2c.c | 4 ++-- drivers/iio/magnetometer/st_magn_spi.c | 4 ++-- drivers/iio/pressure/st_pressure_i2c.c | 4 ++-- drivers/iio/pressure/st_pressure_spi.c | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c index f711756e41e3d..cba57459e90ab 100644 --- a/drivers/iio/accel/st_accel_i2c.c +++ b/drivers/iio/accel/st_accel_i2c.c @@ -193,10 +193,10 @@ static int st_accel_i2c_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client);
- st_sensors_power_disable(indio_dev); - st_accel_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c index bb45d9ff95b85..5167fae1ee8ec 100644 --- a/drivers/iio/accel/st_accel_spi.c +++ b/drivers/iio/accel/st_accel_spi.c @@ -143,10 +143,10 @@ static int st_accel_spi_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi);
- st_sensors_power_disable(indio_dev); - st_accel_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 3ef86e16ee656..a8164fe48b857 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c @@ -106,10 +106,10 @@ static int st_gyro_i2c_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client);
- st_sensors_power_disable(indio_dev); - st_gyro_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index 41d835493347c..9d8916871b4bf 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c @@ -110,10 +110,10 @@ static int st_gyro_spi_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi);
- st_sensors_power_disable(indio_dev); - st_gyro_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/magnetometer/st_magn_i2c.c b/drivers/iio/magnetometer/st_magn_i2c.c index 2dfe4ee99591b..fa78f0a3b53ea 100644 --- a/drivers/iio/magnetometer/st_magn_i2c.c +++ b/drivers/iio/magnetometer/st_magn_i2c.c @@ -102,10 +102,10 @@ static int st_magn_i2c_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client);
- st_sensors_power_disable(indio_dev); - st_magn_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/magnetometer/st_magn_spi.c b/drivers/iio/magnetometer/st_magn_spi.c index fba9787963952..ff43cbf61b056 100644 --- a/drivers/iio/magnetometer/st_magn_spi.c +++ b/drivers/iio/magnetometer/st_magn_spi.c @@ -96,10 +96,10 @@ static int st_magn_spi_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi);
- st_sensors_power_disable(indio_dev); - st_magn_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c index 52fa98f24478d..6215de677017e 100644 --- a/drivers/iio/pressure/st_pressure_i2c.c +++ b/drivers/iio/pressure/st_pressure_i2c.c @@ -119,10 +119,10 @@ static int st_press_i2c_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client);
- st_sensors_power_disable(indio_dev); - st_press_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index ee393df54cee8..5001aae8f00b8 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -102,10 +102,10 @@ static int st_press_spi_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi);
- st_sensors_power_disable(indio_dev); - st_press_common_remove(indio_dev);
+ st_sensors_power_disable(indio_dev); + return 0; }
From: Junji Wei weijunji@bytedance.com
[ Upstream commit dcd3f985b20ffcc375f82ca0ca9f241c7025eb5e ]
The port->attr.port_cap_flags should be set to enum ib_port_capability_mask_bits in ib_mad.h, not RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP.
Fixes: 8700e3e7c485 ("Soft RoCE driver") Link: https://lore.kernel.org/r/20210831083223.65797-1-weijunji@bytedance.com Signed-off-by: Junji Wei weijunji@bytedance.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/sw/rxe/rxe_param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_param.h b/drivers/infiniband/sw/rxe/rxe_param.h index 742e6ec93686c..b5a70cbe94aac 100644 --- a/drivers/infiniband/sw/rxe/rxe_param.h +++ b/drivers/infiniband/sw/rxe/rxe_param.h @@ -113,7 +113,7 @@ enum rxe_device_param { /* default/initial rxe port parameters */ enum rxe_port_param { RXE_PORT_GID_TBL_LEN = 1024, - RXE_PORT_PORT_CAP_FLAGS = RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP, + RXE_PORT_PORT_CAP_FLAGS = IB_PORT_CM_SUP, RXE_PORT_MAX_MSG_SZ = 0x800000, RXE_PORT_BAD_PKEY_CNTR = 0, RXE_PORT_QKEY_VIOL_CNTR = 0,
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit c5e1df3276d7a500678da9453be31a66ad115150 ]
Thix fixes: arch/arm/boot/dts/bcm4708-netgear-r6250.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]} arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]} arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 402653184]]} arch/arm/boot/dts/bcm4709-linksys-ea9200.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]} arch/arm/boot/dts/bcm4709-netgear-r7000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]} arch/arm/boot/dts/bcm4709-netgear-r8000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 134217728]]} arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]} arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728], [2281701376, 402653184]]} arch/arm/boot/dts/bcm53016-meraki-mr32.dt.yaml: /: memory: False schema does not allow {'reg': [[0, 134217728]], 'device_type': ['memory']} arch/arm/boot/dts/bcm94708.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]} arch/arm/boot/dts/bcm94709.dt.yaml: /: memory: False schema does not allow {'device_type': ['memory'], 'reg': [[0, 134217728]]}
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/bcm4708-netgear-r6250.dts | 2 +- arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts | 2 +- arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts | 2 +- arch/arm/boot/dts/bcm4709-linksys-ea9200.dts | 2 +- arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 2 +- arch/arm/boot/dts/bcm4709-netgear-r8000.dts | 2 +- arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts | 2 +- arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts | 2 +- arch/arm/boot/dts/bcm53016-meraki-mr32.dts | 2 +- arch/arm/boot/dts/bcm94708.dts | 2 +- arch/arm/boot/dts/bcm94709.dts | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts index 61c7b137607e5..7900aac4f35a9 100644 --- a/arch/arm/boot/dts/bcm4708-netgear-r6250.dts +++ b/arch/arm/boot/dts/bcm4708-netgear-r6250.dts @@ -20,7 +20,7 @@ bootargs = "console=ttyS0,115200 earlycon"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x08000000>; diff --git a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts index 6c6bb7b17d27a..7546c8d07bcd7 100644 --- a/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts +++ b/arch/arm/boot/dts/bcm4709-asus-rt-ac87u.dts @@ -19,7 +19,7 @@ bootargs = "console=ttyS0,115200"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x08000000>; diff --git a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts index d29e7f80ea6aa..beae9eab9cb8c 100644 --- a/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts +++ b/arch/arm/boot/dts/bcm4709-buffalo-wxr-1900dhp.dts @@ -19,7 +19,7 @@ bootargs = "console=ttyS0,115200"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x18000000>; diff --git a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts index 9b6887d477d86..7879f7d7d9c33 100644 --- a/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts +++ b/arch/arm/boot/dts/bcm4709-linksys-ea9200.dts @@ -16,7 +16,7 @@ bootargs = "console=ttyS0,115200"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x08000000>; diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts index 7989a53597d4f..56d309dbc6b0d 100644 --- a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts +++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts @@ -19,7 +19,7 @@ bootargs = "console=ttyS0,115200"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x08000000>; diff --git a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts index 87b655be674c5..184e3039aa864 100644 --- a/arch/arm/boot/dts/bcm4709-netgear-r8000.dts +++ b/arch/arm/boot/dts/bcm4709-netgear-r8000.dts @@ -30,7 +30,7 @@ bootargs = "console=ttyS0,115200"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x08000000>; diff --git a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts index f806be5da7237..c2a266a439d05 100644 --- a/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts +++ b/arch/arm/boot/dts/bcm4709-tplink-archer-c9-v1.dts @@ -15,7 +15,7 @@ bootargs = "console=ttyS0,115200 earlycon"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; }; diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts index 452b8d0ab180e..b0d8a688141d3 100644 --- a/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts +++ b/arch/arm/boot/dts/bcm47094-luxul-xwc-2000.dts @@ -16,7 +16,7 @@ bootargs = "earlycon"; };
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>, <0x88000000 0x18000000>; diff --git a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts index 3b978dc8997a4..612d61852bfb9 100644 --- a/arch/arm/boot/dts/bcm53016-meraki-mr32.dts +++ b/arch/arm/boot/dts/bcm53016-meraki-mr32.dts @@ -20,7 +20,7 @@ bootargs = " console=ttyS0,115200n8 earlycon"; };
- memory { + memory@0 { reg = <0x00000000 0x08000000>; device_type = "memory"; }; diff --git a/arch/arm/boot/dts/bcm94708.dts b/arch/arm/boot/dts/bcm94708.dts index 3d13e46c69494..d9eb2040b9631 100644 --- a/arch/arm/boot/dts/bcm94708.dts +++ b/arch/arm/boot/dts/bcm94708.dts @@ -38,7 +38,7 @@ model = "NorthStar SVK (BCM94708)"; compatible = "brcm,bcm94708", "brcm,bcm4708";
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; }; diff --git a/arch/arm/boot/dts/bcm94709.dts b/arch/arm/boot/dts/bcm94709.dts index 5017b7b259cbe..618c812eef73e 100644 --- a/arch/arm/boot/dts/bcm94709.dts +++ b/arch/arm/boot/dts/bcm94709.dts @@ -38,7 +38,7 @@ model = "NorthStar SVK (BCM94709)"; compatible = "brcm,bcm94709", "brcm,bcm4709", "brcm,bcm4708";
- memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; };
From: Rafał Miłecki rafal@milecki.pl
[ Upstream commit 6c38c39ab2141f53786d73e706675e8819a3f2cb ]
According to the binding the correct clock name is "refclk".
Fixes: 2961f69f151c ("arm64: dts: broadcom: add BCM4908 and Asus GT-AC5300 early DTS files") 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi index a5a64d17d9ea6..f6b93bbb49228 100644 --- a/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm4908/bcm4908.dtsi @@ -292,7 +292,7 @@ reg = <0x640 0x18>; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; clocks = <&periph_clk>; - clock-names = "periph"; + clock-names = "refclk"; status = "okay"; };
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit af9617b419f77cf0b99702a7b2b0519da0d27715 ]
If we exit the for_each_of_cpu_node loop early, the reference on the current node must be decremented, otherwise there is a leak.
Fixes: f756e362d938 ("clk: mvebu: add CPU clock driver for Armada 7K/8K") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Link: https://lore.kernel.org/r/545df946044fc1fc05a4217cdf0054be7a79e49e.161916111... Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/mvebu/ap-cpu-clk.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c index 08ba59ec3fb17..71bdd7c3ff034 100644 --- a/drivers/clk/mvebu/ap-cpu-clk.c +++ b/drivers/clk/mvebu/ap-cpu-clk.c @@ -256,12 +256,15 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) int cpu, err;
err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) + if (WARN_ON(err)) { + of_node_put(dn); return err; + }
/* If cpu2 or cpu3 is enabled */ if (cpu & APN806_CLUSTER_NUM_MASK) { nclusters = 2; + of_node_put(dn); break; } } @@ -288,8 +291,10 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) int cpu, err;
err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) + if (WARN_ON(err)) { + of_node_put(dn); return err; + }
cluster_index = cpu & APN806_CLUSTER_NUM_MASK; cluster_index >>= APN806_CLUSTER_NUM_OFFSET; @@ -301,6 +306,7 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) parent = of_clk_get(np, cluster_index); if (IS_ERR(parent)) { dev_err(dev, "Could not get the clock parent\n"); + of_node_put(dn); return -EINVAL; } parent_name = __clk_get_name(parent); @@ -319,8 +325,10 @@ static int ap_cpu_clock_probe(struct platform_device *pdev) init.parent_names = &parent_name;
ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw); - if (ret) + if (ret) { + of_node_put(dn); return ret; + } ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw; }
From: Ajish Koshy Ajish.Koshy@microchip.com
[ Upstream commit b27a40534ef76a22628a5c12f98ea489823a8ba5 ]
Commit 1f02beff224e ("scsi: pm80xx: Remove global lock from outbound queue processing") introduced a lock per outbound queue. Prior to that change the driver was using a global lock for all outbound queues.
While processing the I/O responses and events the driver takes the outbound queue spinlock and is supposed to release it in pm8001_ccb_task_free_done() before calling command done(). Since the older code was using a global lock, pm8001_ccb_task_free_done() was releasing the global spin lock. The change that split the lock per outbound queue did not consider this and pm8001_ccb_task_free_done() was still releasing the global lock.
Link: https://lore.kernel.org/r/20210906170404.5682-3-Ajish.Koshy@microchip.com Fixes: 1f02beff224e ("scsi: pm80xx: Remove global lock from outbound queue processing") 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_sas.h | 3 +- drivers/scsi/pm8001/pm80xx_hwi.c | 53 ++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 62d08b535a4b6..e18f2b60371db 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -457,6 +457,7 @@ struct outbound_queue_table { __le32 producer_index; u32 consumer_idx; spinlock_t oq_lock; + unsigned long lock_flags; }; struct pm8001_hba_memspace { void __iomem *memvirtaddr; @@ -738,9 +739,7 @@ pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha, { pm8001_ccb_task_free(pm8001_ha, task, ccb, ccb_idx); smp_mb(); /*in order to force CPU ordering*/ - spin_unlock(&pm8001_ha->lock); task->task_done(task); - spin_lock(&pm8001_ha->lock); }
#endif diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 6ffe17b849ae8..ed02e1aaf868c 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -2379,7 +2379,8 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
/*See the comments for mpi_ssp_completion */ static void -mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) +mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, + struct outbound_queue_table *circularQ, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; @@ -2616,7 +2617,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2632,7 +2637,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2656,7 +2665,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2727,7 +2740,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_DS_NON_OPERATIONAL); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2747,7 +2764,11 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_DS_IN_ERROR); ts->resp = SAS_TASK_UNDELIVERED; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -2785,12 +2806,17 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } else { spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); } }
/*See the comments for mpi_ssp_completion */ -static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) +static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, + struct outbound_queue_table *circularQ, void *piomb) { struct sas_task *t; struct task_status_struct *ts; @@ -2890,7 +2916,11 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); ts->resp = SAS_TASK_COMPLETE; ts->stat = SAS_QUEUE_FULL; + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); return; } break; @@ -3002,7 +3032,11 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } else { spin_unlock_irqrestore(&t->task_state_lock, flags); + spin_unlock_irqrestore(&circularQ->oq_lock, + circularQ->lock_flags); pm8001_ccb_task_free_done(pm8001_ha, t, ccb, tag); + spin_lock_irqsave(&circularQ->oq_lock, + circularQ->lock_flags); } }
@@ -3902,7 +3936,8 @@ static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha, * @pm8001_ha: our hba card information * @piomb: IO message buffer */ -static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) +static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, + struct outbound_queue_table *circularQ, void *piomb) { __le32 pHeader = *(__le32 *)piomb; u32 opc = (u32)((le32_to_cpu(pHeader)) & 0xFFF); @@ -3944,11 +3979,11 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) break; case OPC_OUB_SATA_COMP: pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_COMP\n"); - mpi_sata_completion(pm8001_ha, piomb); + mpi_sata_completion(pm8001_ha, circularQ, piomb); break; case OPC_OUB_SATA_EVENT: pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SATA_EVENT\n"); - mpi_sata_event(pm8001_ha, piomb); + mpi_sata_event(pm8001_ha, circularQ, piomb); break; case OPC_OUB_SSP_EVENT: pm8001_dbg(pm8001_ha, MSG, "OPC_OUB_SSP_EVENT\n"); @@ -4117,7 +4152,6 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) void *pMsg1 = NULL; u8 bc; u32 ret = MPI_IO_STATUS_FAIL; - unsigned long flags; u32 regval;
if (vec == (pm8001_ha->max_q_num - 1)) { @@ -4134,7 +4168,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) } } circularQ = &pm8001_ha->outbnd_q_tbl[vec]; - spin_lock_irqsave(&circularQ->oq_lock, flags); + spin_lock_irqsave(&circularQ->oq_lock, circularQ->lock_flags); do { /* spurious interrupt during setup if kexec-ing and * driver doing a doorbell access w/ the pre-kexec oq @@ -4145,7 +4179,8 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) ret = pm8001_mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); if (MPI_IO_STATUS_SUCCESS == ret) { /* process the outbound message */ - process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4)); + process_one_iomb(pm8001_ha, circularQ, + (void *)(pMsg1 - 4)); /* free the message from the outbound circular buffer */ pm8001_mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc); @@ -4160,7 +4195,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) break; } } while (1); - spin_unlock_irqrestore(&circularQ->oq_lock, flags); + spin_unlock_irqrestore(&circularQ->oq_lock, circularQ->lock_flags); return ret; }
From: Quinn Tran qutran@marvell.com
[ Upstream commit 527d46e0b0147f2b32b78ba49c6a231835b24a41 ]
Authentication application may be running and in the past tried to probe driver (app_start) but was unsuccessful. This could be due to the bsg layer not being ready to service the request. On a successful link up, driver will use the netlink Link Up event to notify the app to retry the app_start call.
In another case, app does not poll for new NPIV host. This link up event would notify app of the presence of a new SCSI host.
Link: https://lore.kernel.org/r/20210908164622.19240-6-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_init.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5fc7697f0af4c..7e64e4730b259 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5335,15 +5335,14 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) "LOOP READY.\n"); ha->flags.fw_init_done = 1;
+ /* + * use link up to wake up app to get ready for + * authentication. + */ if (ha->flags.edif_enabled && - !(vha->e_dbell.db_flags & EDB_ACTIVE) && - N2N_TOPO(vha->hw)) { - /* - * use port online to wake up app to get ready - * for authentication - */ - qla2x00_post_aen_work(vha, FCH_EVT_PORT_ONLINE, 0); - } + !(vha->e_dbell.db_flags & EDB_ACTIVE)) + qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, + ha->link_data_rate);
/* * Process any ATIO queue entries that came in
From: James Smart jsmart2021@gmail.com
[ Upstream commit b507357f79171fb4fb4e732ca43a1f30bc5aab1d ]
Currently, we hold off unregistering with NVMe transport layer until GID_FT or ADISC completes upon receipt of RSCN. In the ADISC discovery routine, for nodes not found in the GID_FT response, the nodes are unregistered from the SCSI transport but not UNREG_RPI'd. Meaning outstanding WQEs continue to be outstanding and were not failed back to the OS. If an NVMe device, this mean there wasn't initial termination of the I/Os so they could be issued on a different NVMe path.
Fix by unregistering the RPI so that I/O is cancelled.
Link: https://lore.kernel.org/r/20210910233159.115896-8-jsmart2021@gmail.com Fixes: 0614568361b0 ("scsi: lpfc: Delay unregistering from transport until GIDFT or ADISC completes") Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_els.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 0a68e565147a7..666b0a1b558ac 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -6215,6 +6215,7 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) * from backend */ lpfc_nlp_unreg_node(vport, ndlp); + lpfc_unreg_rpi(vport, ndlp); continue; }
From: Jackie Liu liuyun01@kylinos.cn
[ Upstream commit 2aa717473ce96c93ae43a5dc8c23cedc8ce7dd9f ]
The s3c24xx_init_intc() returns an error pointer upon failure, not NULL. let's add an error pointer check in s3c24xx_handle_irq.
s3c_intc[0] is not NULL or ERR, we can simplify the code.
Fixes: 1f629b7a3ced ("ARM: S3C24XX: transform irq handling into a declarative form") Signed-off-by: Jackie Liu liuyun01@kylinos.cn Link: https://lore.kernel.org/r/20210901123557.1043953-1-liu.yun@linux.dev Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/mach-s3c/irq-s3c24xx.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-s3c/irq-s3c24xx.c b/arch/arm/mach-s3c/irq-s3c24xx.c index 3edc5f614eefc..c1c2f041ad3b1 100644 --- a/arch/arm/mach-s3c/irq-s3c24xx.c +++ b/arch/arm/mach-s3c/irq-s3c24xx.c @@ -361,11 +361,25 @@ static inline int s3c24xx_handle_intc(struct s3c_irq_intc *intc, static asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) { do { - if (likely(s3c_intc[0])) - if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) - continue; + /* + * For platform based machines, neither ERR nor NULL can happen here. + * The s3c24xx_handle_irq() will be set as IRQ handler iff this succeeds: + * + * s3c_intc[0] = s3c24xx_init_intc() + * + * If this fails, the next calls to s3c24xx_init_intc() won't be executed. + * + * For DT machine, s3c_init_intc_of() could set the IRQ handler without + * setting s3c_intc[0] only if it was called with num_ctrl=0. There is no + * such code path, so again the s3c_intc[0] will have a valid pointer if + * set_handle_irq() is called. + * + * Therefore in s3c24xx_handle_irq(), the s3c_intc[0] is always something. + */ + if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) + continue;
- if (s3c_intc[2]) + if (!IS_ERR_OR_NULL(s3c_intc[2])) if (s3c24xx_handle_intc(s3c_intc[2], regs, 64)) continue;
From: Alex Bee knaerzche@gmail.com
[ Upstream commit 932b4610f55b49f3a158b0db451137bab7ed0e1f ]
As can be seen in RK3328's TRM the register range for the GPU is 0xff300000 to 0xff330000. It would (and does in vendor kernel) overlap with the registers of the HEVC encoder (node/driver do not exist yet in upstream kernel). See already existing h265e_mmu node.
Fixes: 752fbc0c8da7 ("arm64: dts: rockchip: add rk3328 mali gpu node") Signed-off-by: Alex Bee knaerzche@gmail.com Link: https://lore.kernel.org/r/20210623115926.164861-1-knaerzche@gmail.com Signed-off-by: Heiko Stuebner heiko@sntech.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 8c821acb21ffb..da84be6f4715e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -599,7 +599,7 @@
gpu: gpu@ff300000 { compatible = "rockchip,rk3328-mali", "arm,mali-450"; - reg = <0x0 0xff300000 0x0 0x40000>; + reg = <0x0 0xff300000 0x0 0x30000>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>,
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit 8ccecf6c710b8c048eecc65709640642e5357d6e ]
According to YAML validation, and for a future patchset putting this xo_board reference clock to use as VCO reference parent, add the missing clock to dsi_phy0.
Fixes: 5a9fc531f6ec ("ARM: dts: msm8974: add display support") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210830175739.143401-1-marijn.suijten@somainline.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/qcom-msm8974.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index 78ec496d5bc30..2b01bc29ddf23 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1589,8 +1589,8 @@ #phy-cells = <0>; qcom,dsi-phy-index = <0>;
- clocks = <&mmcc MDSS_AHB_CLK>; - clock-names = "iface"; + clocks = <&mmcc MDSS_AHB_CLK>, <&xo_board>; + clock-names = "iface", "ref"; }; };
From: Selvin Xavier selvin.xavier@broadcom.com
[ Upstream commit 598d16fa1bf93431ad35bbab3ed1affe4fb7b562 ]
Fill the missing parameters for the FW command while querying SRQ.
Fixes: 37cb11acf1f7 ("RDMA/bnxt_re: Add SRQ support for Broadcom adapters") Link: https://lore.kernel.org/r/1631709163-2287-8-git-send-email-selvin.xavier@bro... Signed-off-by: Selvin Xavier selvin.xavier@broadcom.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/bnxt_re/qplib_fp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index d4d4959c2434c..bd153aa7e9ab3 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -707,12 +707,13 @@ int bnxt_qplib_query_srq(struct bnxt_qplib_res *res, int rc = 0;
RCFW_CMD_PREP(req, QUERY_SRQ, cmd_flags); - req.srq_cid = cpu_to_le32(srq->id);
/* Configure the request */ sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb)); if (!sbuf) return -ENOMEM; + req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS; + req.srq_cid = cpu_to_le32(srq->id); sb = sbuf->sb; rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, (void *)sbuf, 0);
From: Kishon Vijay Abraham I kishon@ti.com
[ Upstream commit 9af3ef954975c383eeb667aee207d9ce6fbef8c4 ]
commit 4e5833884f66 ("arm64: dts: ti: k3-j721e-main: Add PCIe device tree nodes") added "max-virtual-functions" to have 16 bit values. Fix "max-virtual-functions" in PCIe endpoint (EP) nodes to have 8 bit values instead of 16.
Fixes: 4e5833884f66 ("arm64: dts: ti: k3-j721e-main: Add PCIe device tree nodes") Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Aswath Govindraju a-govindraju@ti.com Signed-off-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/20210915055358.19997-2-kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi index cf3482376c1e6..43be5d23130b4 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi @@ -636,7 +636,7 @@ clocks = <&k3_clks 239 1>; clock-names = "fck"; max-functions = /bits/ 8 <6>; - max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; dma-coherent; };
@@ -684,7 +684,7 @@ clocks = <&k3_clks 240 1>; clock-names = "fck"; max-functions = /bits/ 8 <6>; - max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; dma-coherent; };
@@ -732,7 +732,7 @@ clocks = <&k3_clks 241 1>; clock-names = "fck"; max-functions = /bits/ 8 <6>; - max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; dma-coherent; };
@@ -780,7 +780,7 @@ clocks = <&k3_clks 242 1>; clock-names = "fck"; max-functions = /bits/ 8 <6>; - max-virtual-functions = /bits/ 16 <4 4 4 4 0 0>; + max-virtual-functions = /bits/ 8 <4 4 4 4 0 0>; dma-coherent; #address-cells = <2>; #size-cells = <2>;
From: Kishon Vijay Abraham I kishon@ti.com
[ Upstream commit 5f46633565b1c1e1840a927676065d72b442dac4 ]
commit 4e5833884f66 ("arm64: dts: ti: k3-j721e-main: Add PCIe device tree nodes") restricted PCIe bus numbers from 0 to 15 (due to SMMU restriction in J721E). However since SMMU is not enabled, allow the full supported bus numbers from 0 to 255.
Fixes: 4e5833884f66 ("arm64: dts: ti: k3-j721e-main: Add PCIe device tree nodes") Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Aswath Govindraju a-govindraju@ti.com Signed-off-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/20210915055358.19997-3-kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi index 43be5d23130b4..08c8d1b47dcd9 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi @@ -610,7 +610,7 @@ clock-names = "fck"; #address-cells = <3>; #size-cells = <2>; - bus-range = <0x0 0xf>; + bus-range = <0x0 0xff>; vendor-id = <0x104c>; device-id = <0xb00d>; msi-map = <0x0 &gic_its 0x0 0x10000>; @@ -658,7 +658,7 @@ clock-names = "fck"; #address-cells = <3>; #size-cells = <2>; - bus-range = <0x0 0xf>; + bus-range = <0x0 0xff>; vendor-id = <0x104c>; device-id = <0xb00d>; msi-map = <0x0 &gic_its 0x10000 0x10000>; @@ -706,7 +706,7 @@ clock-names = "fck"; #address-cells = <3>; #size-cells = <2>; - bus-range = <0x0 0xf>; + bus-range = <0x0 0xff>; vendor-id = <0x104c>; device-id = <0xb00d>; msi-map = <0x0 &gic_its 0x20000 0x10000>; @@ -754,7 +754,7 @@ clock-names = "fck"; #address-cells = <3>; #size-cells = <2>; - bus-range = <0x0 0xf>; + bus-range = <0x0 0xff>; vendor-id = <0x104c>; device-id = <0xb00d>; msi-map = <0x0 &gic_its 0x30000 0x10000>;
From: Kishon Vijay Abraham I kishon@ti.com
[ Upstream commit 0d553792726a61ced760422e74ea67552ac69cdb ]
commit 3276d9f53cf6 ("arm64: dts: ti: k3-j7200-main: Add PCIe device tree node") incorrectly added "vendor-id" and "device-id" as 16-bit properties though both of them are 32-bit properties. Fix it here.
Fixes: 3276d9f53cf6 ("arm64: dts: ti: k3-j7200-main: Add PCIe device tree node") Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Aswath Govindraju a-govindraju@ti.com Signed-off-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/20210915055358.19997-4-kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi index e8a41d09b45f2..521a56316fa5c 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi @@ -608,8 +608,8 @@ #size-cells = <2>; bus-range = <0x0 0xf>; cdns,no-bar-match-nbits = <64>; - vendor-id = /bits/ 16 <0x104c>; - device-id = /bits/ 16 <0xb00f>; + vendor-id = <0x104c>; + device-id = <0xb00f>; msi-map = <0x0 &gic_its 0x0 0x10000>; dma-coherent; ranges = <0x01000000 0x0 0x18001000 0x00 0x18001000 0x0 0x0010000>,
From: Kishon Vijay Abraham I kishon@ti.com
[ Upstream commit 8bb8429290c0043a78804ae48294b53f781ee426 ]
commit 3276d9f53cf6 ("arm64: dts: ti: k3-j7200-main: Add PCIe device tree node") incorrectly added PCIe bus numbers from 0 to 15 (copy-paste from J721E node). Enable all the supported bus numbers from 0 to 255 defined in PCIe spec here.
Fixes: 3276d9f53cf6 ("arm64: dts: ti: k3-j7200-main: Add PCIe device tree node") Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Reviewed-by: Aswath Govindraju a-govindraju@ti.com Signed-off-by: Nishanth Menon nm@ti.com Link: https://lore.kernel.org/r/20210915055358.19997-5-kishon@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi index 521a56316fa5c..874cba75e9a5a 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi @@ -606,7 +606,7 @@ clock-names = "fck"; #address-cells = <3>; #size-cells = <2>; - bus-range = <0x0 0xf>; + bus-range = <0x0 0xff>; cdns,no-bar-match-nbits = <64>; vendor-id = <0x104c>; device-id = <0xb00f>;
From: Anand Moon linux.amoon@gmail.com
[ Upstream commit 085675117ecf5e02c4220698fd549024ec64ad2c ]
After enabling CONFIG_REGULATOR_DEBUG=y we observe below debug logs. Changes help link VDDCPU pwm regulator to 12V regulator supply instead of dummy regulator.
[ 11.602281] pwm-regulator regulator-vddcpu: Looking up pwm-supply property in node /regulator-vddcpu failed [ 11.602344] VDDCPU: supplied by regulator-dummy [ 11.602365] regulator-dummy: could not add device link regulator.11: -ENOENT [ 11.602548] VDDCPU: 721 <--> 1022 mV at 1022 mV, enabled
Fixes: e9bc0765cc12 ("arm64: dts: meson-g12a: enable DVFS on G12A boards")
Cc: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Anand Moon linux.amoon@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/20210919202918.3556-2-linux.amoon@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts index 81269ccc24968..d8838dde0f0f4 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts @@ -139,7 +139,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&dc_in>; + pwm-supply = <&dc_in>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts index a26bfe72550fe..4b5d11e56364d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts @@ -139,7 +139,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&main_12v>; + pwm-supply = <&main_12v>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts index 579f3d02d613e..b4e86196e3468 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts @@ -139,7 +139,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&dc_in>; + pwm-supply = <&dc_in>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>;
From: Anand Moon linux.amoon@gmail.com
[ Upstream commit 62183863f708c2464769e0d477c8ce9f3d326feb ]
After enabling CONFIG_REGULATOR_DEBUG=y we observer below debug logs. Changes help link VDDCP_A and VDDCPU_B pwm regulator to 12V regulator supply instead of dummy regulator.
[ 4.147196] VDDCPU_A: will resolve supply early: pwm [ 4.147216] pwm-regulator regulator-vddcpu-a: Looking up pwm-supply from device tree [ 4.147227] pwm-regulator regulator-vddcpu-a: Looking up pwm-supply property in node /regulator-vddcpu-a failed [ 4.147258] VDDCPU_A: supplied by regulator-dummy [ 4.147288] regulator-dummy: could not add device link regulator.12: -ENOENT [ 4.147353] VDDCPU_A: 721 <--> 1022 mV at 871 mV, enabled [ 4.152014] VDDCPU_B: will resolve supply early: pwm [ 4.152035] pwm-regulator regulator-vddcpu-b: Looking up pwm-supply from device tree [ 4.152047] pwm-regulator regulator-vddcpu-b: Looking up pwm-supply property in node /regulator-vddcpu-b failed [ 4.152079] VDDCPU_B: supplied by regulator-dummy [ 4.152108] regulator-dummy: could not add device link regulator.13: -ENOENT
Fixes: c6d29c66e582 ("arm64: dts: meson-g12b-khadas-vim3: add initial device-tree") Fixes: d14734a04a8a ("arm64: dts: meson-g12b-odroid-n2: enable DVFS") Fixes: 3cb74db9b256 ("arm64: dts: meson: convert ugoos-am6 to common w400 dtsi")
Cc: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Anand Moon linux.amoon@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/20210919202918.3556-3-linux.amoon@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi | 4 ++-- arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 ++-- arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi index f42cf4b8af2d4..16dd409051b40 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi @@ -18,7 +18,7 @@ regulator-min-microvolt = <690000>; regulator-max-microvolt = <1050000>;
- vin-supply = <&dc_in>; + pwm-supply = <&dc_in>;
pwms = <&pwm_ab 0 1250 0>; pwm-dutycycle-range = <100 0>; @@ -37,7 +37,7 @@ regulator-min-microvolt = <690000>; regulator-max-microvolt = <1050000>;
- vin-supply = <&vsys_3v3>; + pwm-supply = <&vsys_3v3>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi index 344573e157a7b..4f33820aba1f1 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi @@ -130,7 +130,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&main_12v>; + pwm-supply = <&main_12v>;
pwms = <&pwm_ab 0 1250 0>; pwm-dutycycle-range = <100 0>; @@ -149,7 +149,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&main_12v>; + pwm-supply = <&main_12v>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi index feb0885047400..b40d2c1002c92 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-w400.dtsi @@ -96,7 +96,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&main_12v>; + pwm-supply = <&main_12v>;
pwms = <&pwm_ab 0 1250 0>; pwm-dutycycle-range = <100 0>; @@ -115,7 +115,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&main_12v>; + pwm-supply = <&main_12v>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>;
From: Anand Moon linux.amoon@gmail.com
[ Upstream commit 0b26fa8a02c2834f1fa8a206a285b9f84c4ad764 ]
After enabling CONFIG_REGULATOR_DEBUG=y we observe below debug logs. Changes help link VDDCPU pwm regulator to 12V regulator supply instead of dummy regulator.
[ 11.602281] pwm-regulator regulator-vddcpu: Looking up pwm-supply property in node /regulator-vddcpu failed [ 11.602344] VDDCPU: supplied by regulator-dummy [ 11.602365] regulator-dummy: could not add device link regulator.11: -ENOENT [ 11.602548] VDDCPU: 721 <--> 1022 mV at 1022 mV, enabled
Fixes: 88d537bc92ca ("arm64: dts: meson: convert meson-sm1-odroid-c4 to dtsi") Fixes: 700ab8d83927 ("arm64: dts: khadas-vim3: add support for the SM1 based VIM3L") Fixes: 3d9e76483049 ("arm64: dts: meson-sm1-sei610: enable DVFS") Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
Cc: Neil Armstrong narmstrong@baylibre.com Signed-off-by: Anand Moon linux.amoon@gmail.com Reviewed-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Signed-off-by: Neil Armstrong narmstrong@baylibre.com Link: https://lore.kernel.org/r/20210919202918.3556-4-linux.amoon@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts | 2 +- arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +- arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts index effaa138b5f98..212c6aa5a3b86 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts @@ -173,7 +173,7 @@ regulator-min-microvolt = <690000>; regulator-max-microvolt = <1050000>;
- vin-supply = <&dc_in>; + pwm-supply = <&dc_in>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts index f2c0981435944..9c0b544e22098 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts @@ -24,7 +24,7 @@ regulator-min-microvolt = <690000>; regulator-max-microvolt = <1050000>;
- vin-supply = <&vsys_3v3>; + pwm-supply = <&vsys_3v3>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi index 45e7fcb062f96..5779e70caccd3 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi @@ -116,7 +116,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>;
- vin-supply = <&main_12v>; + pwm-supply = <&main_12v>;
pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts index 2194a778973f1..427475846fc70 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts @@ -185,7 +185,7 @@ regulator-min-microvolt = <690000>; regulator-max-microvolt = <1050000>;
- vin-supply = <&dc_in>; + pwm-supply = <&dc_in>;
pwms = <&pwm_AO_cd 1 1500 0>; pwm-dutycycle-range = <100 0>;
From: Tony Lindgren tony@atomide.com
[ Upstream commit b3e9431854e8f305385d5de225441c0477b936cb ]
On resume we can get a warning at kernel/time/timekeeping.c:824 for timekeeping_suspended.
Let's fix this by adding separate functions for sysc_poll_reset_sysstatus() and sysc_poll_reset_sysconfig() and have the new functions handle also timekeeping_suspended.
If iopoll at some point supports timekeeping_suspended, we can just drop the custom handling from these functions.
Fixes: d46f9fbec719 ("bus: ti-sysc: Use optional clocks on for enable and wait for softreset bit") Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/ti-sysc.c | 65 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-)
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 6a8b7fb5be58d..f47c7e20cc271 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -17,6 +17,7 @@ #include <linux/of_platform.h> #include <linux/slab.h> #include <linux/sys_soc.h> +#include <linux/timekeeping.h> #include <linux/iopoll.h>
#include <linux/platform_data/ti-sysc.h> @@ -223,37 +224,77 @@ static u32 sysc_read_sysstatus(struct sysc *ddata) return sysc_read(ddata, offset); }
-/* Poll on reset status */ -static int sysc_wait_softreset(struct sysc *ddata) +static int sysc_poll_reset_sysstatus(struct sysc *ddata) { - u32 sysc_mask, syss_done, rstval; - int syss_offset, error = 0; - - if (ddata->cap->regbits->srst_shift < 0) - return 0; - - syss_offset = ddata->offsets[SYSC_SYSSTATUS]; - sysc_mask = BIT(ddata->cap->regbits->srst_shift); + int error, retries; + u32 syss_done, rstval;
if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) syss_done = 0; else syss_done = ddata->cfg.syss_mask;
- if (syss_offset >= 0) { + if (likely(!timekeeping_suspended)) { error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata, rstval, (rstval & ddata->cfg.syss_mask) == syss_done, 100, MAX_MODULE_SOFTRESET_WAIT); + } else { + retries = MAX_MODULE_SOFTRESET_WAIT; + while (retries--) { + rstval = sysc_read_sysstatus(ddata); + if ((rstval & ddata->cfg.syss_mask) == syss_done) + return 0; + udelay(2); /* Account for udelay flakeyness */ + } + error = -ETIMEDOUT; + }
- } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { + return error; +} + +static int sysc_poll_reset_sysconfig(struct sysc *ddata) +{ + int error, retries; + u32 sysc_mask, rstval; + + sysc_mask = BIT(ddata->cap->regbits->srst_shift); + + if (likely(!timekeeping_suspended)) { error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata, rstval, !(rstval & sysc_mask), 100, MAX_MODULE_SOFTRESET_WAIT); + } else { + retries = MAX_MODULE_SOFTRESET_WAIT; + while (retries--) { + rstval = sysc_read_sysconfig(ddata); + if (!(rstval & sysc_mask)) + return 0; + udelay(2); /* Account for udelay flakeyness */ + } + error = -ETIMEDOUT; }
return error; }
+/* Poll on reset status */ +static int sysc_wait_softreset(struct sysc *ddata) +{ + int syss_offset, error = 0; + + if (ddata->cap->regbits->srst_shift < 0) + return 0; + + syss_offset = ddata->offsets[SYSC_SYSSTATUS]; + + if (syss_offset >= 0) + error = sysc_poll_reset_sysstatus(ddata); + else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) + error = sysc_poll_reset_sysconfig(ddata); + + return error; +} + static int sysc_add_named_clock_from_child(struct sysc *ddata, const char *name, const char *optfck_name)
From: Peter Rosin peda@axentia.se
[ Upstream commit dcdbc335a91a26e022a803e1a6b837266989c032 ]
This went unnoticed until commit 7897b071ac3b ("net: macb: convert to phylink") which tickled the problem. The sama5d3 emac has never been capable of rgmii, and it all just happened to work before that commit.
Fixes: 21dd0ece34c2 ("ARM: dts: at91: add devicetree for the Axentia TSE-850") Signed-off-by: Peter Rosin peda@axentia.se Signed-off-by: Nicolas Ferre nicolas.ferre@microchip.com Link: https://lore.kernel.org/r/ea781f5e-422f-6cbf-3cf4-d5a7bac9392d@axentia.se Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/at91-tse850-3.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/at91-tse850-3.dts b/arch/arm/boot/dts/at91-tse850-3.dts index 3ca97b47c69ce..7e5c598e7e68f 100644 --- a/arch/arm/boot/dts/at91-tse850-3.dts +++ b/arch/arm/boot/dts/at91-tse850-3.dts @@ -262,7 +262,7 @@ &macb1 { status = "okay";
- phy-mode = "rgmii"; + phy-mode = "rmii";
#address-cells = <1>; #size-cells = <0>;
From: Douglas Anderson dianders@chromium.org
[ Upstream commit 82ea7d411d43f60dce878252558e926f957109f0 ]
The sc7180's dynamic-power-coefficient violates the device tree bindings. The bindings (arm/cpus.yaml) say that the units for the dynamic-power-coefficient are supposed to be "uW/MHz/V^2". The ones for sc7180 aren't this. Qualcomm arbitrarily picked 100 for the "little" CPUs and then picked a number for the big CPU based on this.
At the time, there was a giant dicussion about this. Apparently Qualcomm Engineers were instructed not to share the actual numbers here. As part of the discussion, I pointed out [1] that these numbers shouldn't really be secret since once a device is shipping anyone can just run a script and produce them. This patch is the result of running the script I posted in that discussion on sc7180-trogdor-coachz, which is currently available for purchase by consumers.
[1] https://lore.kernel.org/r/CAD=FV=U1FP0e3_AVHpauUUZtD-5X3XCwh5aT9fH_8S_FFML2U...
I ran the script four times, measuring little, big, little, big. I used the 64-bit version of dhrystone 2.2 in my test. I got these results:
576 kHz, 596 mV, 20 mW, 88 Cx 768 kHz, 596 mV, 32 mW, 122 Cx 1017 kHz, 660 mV, 45 mW, 97 Cx 1248 kHz, 720 mV, 87 mW, 139 Cx 1324 kHz, 756 mV, 109 mW, 148 Cx 1516 kHz, 828 mV, 150 mW, 148 Cx 1612 kHz, 884 mV, 182 mW, 147 Cx 1708 kHz, 884 mV, 192 mW, 146 Cx 1804 kHz, 884 mV, 207 mW, 149 Cx Your dynamic-power-coefficient for cpu 0: 132
825 kHz, 596 mV, 142 mW, 401 Cx 979 kHz, 628 mV, 183 mW, 427 Cx 1113 kHz, 656 mV, 224 mW, 433 Cx 1267 kHz, 688 mV, 282 mW, 449 Cx 1555 kHz, 812 mV, 475 mW, 450 Cx 1708 kHz, 828 mV, 566 mW, 478 Cx 1843 kHz, 884 mV, 692 mW, 476 Cx 1900 kHz, 884 mV, 722 mW, 482 Cx 1996 kHz, 916 mV, 814 mW, 482 Cx 2112 kHz, 916 mV, 862 mW, 483 Cx 2208 kHz, 916 mV, 962 mW, 521 Cx 2323 kHz, 940 mV, 1060 mW, 517 Cx 2400 kHz, 956 mV, 1133 mW, 518 Cx Your dynamic-power-coefficient for cpu 6: 471
576 kHz, 596 mV, 26 mW, 103 Cx 768 kHz, 596 mV, 40 mW, 147 Cx 1017 kHz, 660 mV, 54 mW, 114 Cx 1248 kHz, 720 mV, 97 mW, 151 Cx 1324 kHz, 756 mV, 113 mW, 150 Cx 1516 kHz, 828 mV, 154 mW, 148 Cx 1612 kHz, 884 mV, 194 mW, 155 Cx 1708 kHz, 884 mV, 203 mW, 152 Cx 1804 kHz, 884 mV, 219 mW, 155 Cx Your dynamic-power-coefficient for cpu 0: 142
825 kHz, 596 mV, 148 mW, 530 Cx 979 kHz, 628 mV, 189 mW, 475 Cx 1113 kHz, 656 mV, 230 mW, 461 Cx 1267 kHz, 688 mV, 287 mW, 466 Cx 1555 kHz, 812 mV, 469 mW, 445 Cx 1708 kHz, 828 mV, 567 mW, 480 Cx 1843 kHz, 884 mV, 699 mW, 482 Cx 1900 kHz, 884 mV, 719 mW, 480 Cx 1996 kHz, 916 mV, 814 mW, 484 Cx 2112 kHz, 916 mV, 861 mW, 483 Cx 2208 kHz, 916 mV, 963 mW, 522 Cx 2323 kHz, 940 mV, 1063 mW, 520 Cx 2400 kHz, 956 mV, 1135 mW, 519 Cx Your dynamic-power-coefficient for cpu 6: 489
As you can see, the calculations aren't perfectly consistent but roughly you could say about 480 for big and 137 for little.
The ratio between these numbers isn't quite the same as the ratio between the two numbers that Qualcomm used. Perhaps this is because Qualcomm measured something slightly different than the 64-bit version of dhrystone 2.2 or perhaps it's because they fudged these numbers a bit (and fudged the capacity-dmips-mhz). As per discussion [2], let's use the numbers I came up with and also un-fudge capacity-dmips-mhz. While unfudging capacity-dmips-mhz, let's scale it so that bigs are 1024 which seems to be the common practice.
In general these numbers don't need to be perfectly exact. In fact, they can't be since the CPU power depends a lot on what's being run on the CPU and the big/little CPUs are each more or less efficient in different operations. Historically running the 32-bit vs. 64-bit versions of dhrystone produced notably different numbers, though I didn't test this time.
We also need to scale all of the sustainable-power numbers by the same amount. I scale ones related to the big CPUs by the adjustment I made to the big dynamic-power-coefficient and the ones related to the little CPUs by the adjustment I made to the little dynamic-power-coefficient.
[2] https://lore.kernel.org/r/0a865b6e-be34-6371-f9f2-9913ee1c5608@codeaurora.or...
Fixes: 71f873169a80 ("arm64: dts: qcom: sc7180: Add dynamic CPU power coefficients") Signed-off-by: Douglas Anderson dianders@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210902145127.v2.1.I049b30065f3c715234b6303f55d72... Signed-off-by: Sasha Levin sashal@kernel.org --- .../boot/dts/qcom/sc7180-trogdor-coachz.dtsi | 2 +- .../boot/dts/qcom/sc7180-trogdor-pompom.dtsi | 8 +-- arch/arm64/boot/dts/qcom/sc7180.dtsi | 52 +++++++++---------- 3 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi index a758e4d226122..81098aa9687ba 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi @@ -33,7 +33,7 @@ ap_h1_spi: &spi0 {}; polling-delay = <0>;
thermal-sensors = <&pm6150_adc_tm 1>; - sustainable-power = <814>; + sustainable-power = <965>;
trips { skin_temp_alert0: trip-point0 { diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi index a246dbd74cc11..b7b5264888b7c 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi @@ -44,7 +44,7 @@ ap_h1_spi: &spi0 {}; };
&cpu6_thermal { - sustainable-power = <948>; + sustainable-power = <1124>; };
&cpu7_alert0 { @@ -56,7 +56,7 @@ ap_h1_spi: &spi0 {}; };
&cpu7_thermal { - sustainable-power = <948>; + sustainable-power = <1124>; };
&cpu8_alert0 { @@ -68,7 +68,7 @@ ap_h1_spi: &spi0 {}; };
&cpu8_thermal { - sustainable-power = <948>; + sustainable-power = <1124>; };
&cpu9_alert0 { @@ -80,7 +80,7 @@ ap_h1_spi: &spi0 {}; };
&cpu9_thermal { - sustainable-power = <948>; + sustainable-power = <1124>; };
&gpio_keys { diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi index c8921e2d6480f..495c15deacb7d 100644 --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -137,8 +137,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1024>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, <&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>; @@ -162,8 +162,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1024>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; next-level-cache = <&L2_100>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -184,8 +184,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1024>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; next-level-cache = <&L2_200>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -206,8 +206,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1024>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; next-level-cache = <&L2_300>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -228,8 +228,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1024>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; next-level-cache = <&L2_400>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -250,8 +250,8 @@ cpu-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1024>; - dynamic-power-coefficient = <100>; + capacity-dmips-mhz = <415>; + dynamic-power-coefficient = <137>; next-level-cache = <&L2_500>; operating-points-v2 = <&cpu0_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -272,8 +272,8 @@ cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1740>; - dynamic-power-coefficient = <405>; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <480>; next-level-cache = <&L2_600>; operating-points-v2 = <&cpu6_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -294,8 +294,8 @@ cpu-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1 &CLUSTER_SLEEP_0>; - capacity-dmips-mhz = <1740>; - dynamic-power-coefficient = <405>; + capacity-dmips-mhz = <1024>; + dynamic-power-coefficient = <480>; next-level-cache = <&L2_700>; operating-points-v2 = <&cpu6_opp_table>; interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>, @@ -3616,7 +3616,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 1>; - sustainable-power = <768>; + sustainable-power = <1052>;
trips { cpu0_alert0: trip-point0 { @@ -3665,7 +3665,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 2>; - sustainable-power = <768>; + sustainable-power = <1052>;
trips { cpu1_alert0: trip-point0 { @@ -3714,7 +3714,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 3>; - sustainable-power = <768>; + sustainable-power = <1052>;
trips { cpu2_alert0: trip-point0 { @@ -3763,7 +3763,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 4>; - sustainable-power = <768>; + sustainable-power = <1052>;
trips { cpu3_alert0: trip-point0 { @@ -3812,7 +3812,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 5>; - sustainable-power = <768>; + sustainable-power = <1052>;
trips { cpu4_alert0: trip-point0 { @@ -3861,7 +3861,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 6>; - sustainable-power = <768>; + sustainable-power = <1052>;
trips { cpu5_alert0: trip-point0 { @@ -3910,7 +3910,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 9>; - sustainable-power = <1202>; + sustainable-power = <1425>;
trips { cpu6_alert0: trip-point0 { @@ -3951,7 +3951,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 10>; - sustainable-power = <1202>; + sustainable-power = <1425>;
trips { cpu7_alert0: trip-point0 { @@ -3992,7 +3992,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 11>; - sustainable-power = <1202>; + sustainable-power = <1425>;
trips { cpu8_alert0: trip-point0 { @@ -4033,7 +4033,7 @@ polling-delay = <0>;
thermal-sensors = <&tsens0 12>; - sustainable-power = <1202>; + sustainable-power = <1425>;
trips { cpu9_alert0: trip-point0 {
From: Naina Mehta nainmeht@codeaurora.org
[ Upstream commit 3a461009e195c3c17f6af73da310b886991309fd ]
Disable MMUHWT retention for SC7280 as done for other platforms to avoid more power burn.
Fixes: f6a07be63301 ("soc: qcom: llcc: Add configuration data for SC7280") Signed-off-by: Naina Mehta nainmeht@codeaurora.org Signed-off-by: Sai Prakash Ranjan saiprakash.ranjan@codeaurora.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210921055942.30600-1-saiprakash.ranjan@codeauror... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/llcc-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 15a36dcab990e..e53109a5c3da9 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -115,7 +115,7 @@ static const struct llcc_slice_config sc7280_data[] = { { LLCC_CMPT, 10, 768, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, { LLCC_GPUHTW, 11, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, { LLCC_GPU, 12, 512, 1, 0, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, - { LLCC_MMUHWT, 13, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 1, 0}, + { LLCC_MMUHWT, 13, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 0, 1, 0}, { LLCC_MDMPNG, 21, 768, 0, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, { LLCC_WLHW, 24, 256, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0}, { LLCC_MODPE, 29, 64, 1, 1, 0x3f, 0x0, 0, 0, 0, 1, 0, 0},
From: Kuogee Hsieh khsieh@codeaurora.org
[ Upstream commit 425f30cc843c727bc7753a0d33710d1e4a999168 ]
Existing display port phy reg property is derived from usb phy which map display port phy pcs to wrong address which cause aux init with wrong address and prevent both dpcd read and write from working. Fix this problem by assigning correct pcs address to display port phy reg property.
Fixes: bb9efa59c665 ("arm64: dts: qcom: sc7280: Add USB related nodes") Signed-off-by: Kuogee Hsieh khsieh@codeaurora.org Reviewed-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1631216998-10049-1-git-send-email-khsieh@codeauror... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sc7280.dtsi | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index fd78f16181ddd..f58336536a92a 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -1258,15 +1258,11 @@ dp_phy: dp-phy@88ea200 { reg = <0 0x088ea200 0 0x200>, <0 0x088ea400 0 0x200>, - <0 0x088eac00 0 0x400>, + <0 0x088eaa00 0 0x200>, <0 0x088ea600 0 0x200>, - <0 0x088ea800 0 0x200>, - <0 0x088eaa00 0 0x100>; + <0 0x088ea800 0 0x200>; #phy-cells = <0>; #clock-cells = <1>; - clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; - clock-names = "pipe0"; - clock-output-names = "usb3_phy_pipe_clk_src"; }; };
From: Tong Zhang ztong0001@gmail.com
[ Upstream commit cbd9a3347c757383f3d2b50cf7cfd03eb479c481 ]
dc395x_init_one()->adapter_init() might fail. In this case, the acb is already cleaned up by adapter_init(), no need to do that in adapter_uninit(acb) again.
[ 1.252251] dc395x: adapter init failed [ 1.254900] RIP: 0010:adapter_uninit+0x94/0x170 [dc395x] [ 1.260307] Call Trace: [ 1.260442] dc395x_init_one.cold+0x72a/0x9bb [dc395x]
Link: https://lore.kernel.org/r/20210907040702.1846409-1-ztong0001@gmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reviewed-by: Finn Thain fthain@linux-m68k.org Signed-off-by: Tong Zhang ztong0001@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/dc395x.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 24c7cefb0b78a..1c79e6c271630 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -4618,6 +4618,7 @@ static int dc395x_init_one(struct pci_dev *dev, const struct pci_device_id *id) /* initialise the adapter and everything we need */ if (adapter_init(acb, io_port_base, io_port_len, irq)) { dprintkl(KERN_INFO, "adapter init failed\n"); + acb = NULL; goto fail; }
From: Jackie Liu liuyun01@kylinos.cn
[ Upstream commit 7f3b3c2bfa9c93ab9b5595543496f570983dc330 ]
mach/loongson64 fails to build when the FPU support is disabled:
arch/mips/loongson64/cop2-ex.c:45:15: error: implicit declaration of function ‘__is_fpu_owner’; did you mean ‘is_fpu_owner’? [-Werror=implicit-function-declaration] arch/mips/loongson64/cop2-ex.c:98:30: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:99:30: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:131:43: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:137:38: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:203:30: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:219:30: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:283:38: error: ‘struct thread_struct’ has no member named ‘fpu’ arch/mips/loongson64/cop2-ex.c:301:38: error: ‘struct thread_struct’ has no member named ‘fpu’
Fixes: ef2f826c8f2f ("MIPS: Loongson-3: Enable the COP2 usage") Suggested-by: Huacai Chen chenhuacai@kernel.org Reviewed-by: Huacai Chen chenhuacai@kernel.org Reported-by: k2ci robot kernel-bot@kylinos.cn Signed-off-by: Jackie Liu liuyun01@kylinos.cn Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6b8f591c5054c..cbbb302a460eb 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1379,6 +1379,7 @@ config CPU_LOONGSON64 select MIPS_ASID_BITS_VARIABLE select MIPS_PGD_C0_CONTEXT select MIPS_L1_CACHE_SHIFT_6 + select MIPS_FP_SUPPORT select GPIOLIB select SWIOTLB select HAVE_KVM
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit c48a14dca2cb57527dde6b960adbe69953935f10 ]
In jfs_mount, when diMount(ipaimap2) fails, it goes to errout35. However, the following code does not free ipaimap2 allocated by diReadSpecial.
Fix this by refactoring the error handling code of jfs_mount. To be specific, modify the lable name and free ipaimap2 when the above error ocurrs.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Signed-off-by: Dave Kleikamp dave.kleikamp@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/jfs/jfs_mount.c | 51 ++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 29 deletions(-)
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c index 5d7d7170c03c0..aa4ff7bcaff23 100644 --- a/fs/jfs/jfs_mount.c +++ b/fs/jfs/jfs_mount.c @@ -81,14 +81,14 @@ int jfs_mount(struct super_block *sb) * (initialize mount inode from the superblock) */ if ((rc = chkSuper(sb))) { - goto errout20; + goto out; }
ipaimap = diReadSpecial(sb, AGGREGATE_I, 0); if (ipaimap == NULL) { jfs_err("jfs_mount: Failed to read AGGREGATE_I"); rc = -EIO; - goto errout20; + goto out; } sbi->ipaimap = ipaimap;
@@ -99,7 +99,7 @@ int jfs_mount(struct super_block *sb) */ if ((rc = diMount(ipaimap))) { jfs_err("jfs_mount: diMount(ipaimap) failed w/rc = %d", rc); - goto errout21; + goto err_ipaimap; }
/* @@ -108,7 +108,7 @@ int jfs_mount(struct super_block *sb) ipbmap = diReadSpecial(sb, BMAP_I, 0); if (ipbmap == NULL) { rc = -EIO; - goto errout22; + goto err_umount_ipaimap; }
jfs_info("jfs_mount: ipbmap:0x%p", ipbmap); @@ -120,7 +120,7 @@ int jfs_mount(struct super_block *sb) */ if ((rc = dbMount(ipbmap))) { jfs_err("jfs_mount: dbMount failed w/rc = %d", rc); - goto errout22; + goto err_ipbmap; }
/* @@ -139,7 +139,7 @@ int jfs_mount(struct super_block *sb) if (!ipaimap2) { jfs_err("jfs_mount: Failed to read AGGREGATE_I"); rc = -EIO; - goto errout35; + goto err_umount_ipbmap; } sbi->ipaimap2 = ipaimap2;
@@ -151,7 +151,7 @@ int jfs_mount(struct super_block *sb) if ((rc = diMount(ipaimap2))) { jfs_err("jfs_mount: diMount(ipaimap2) failed, rc = %d", rc); - goto errout35; + goto err_ipaimap2; } } else /* Secondary aggregate inode table is not valid */ @@ -168,7 +168,7 @@ int jfs_mount(struct super_block *sb) jfs_err("jfs_mount: Failed to read FILESYSTEM_I"); /* open fileset secondary inode allocation map */ rc = -EIO; - goto errout40; + goto err_umount_ipaimap2; } jfs_info("jfs_mount: ipimap:0x%p", ipimap);
@@ -178,41 +178,34 @@ int jfs_mount(struct super_block *sb) /* initialize fileset inode allocation map */ if ((rc = diMount(ipimap))) { jfs_err("jfs_mount: diMount failed w/rc = %d", rc); - goto errout41; + goto err_ipimap; }
- goto out; + return rc;
/* * unwind on error */ - errout41: /* close fileset inode allocation map inode */ +err_ipimap: + /* close fileset inode allocation map inode */ diFreeSpecial(ipimap); - - errout40: /* fileset closed */ - +err_umount_ipaimap2: /* close secondary aggregate inode allocation map */ - if (ipaimap2) { + if (ipaimap2) diUnmount(ipaimap2, 1); +err_ipaimap2: + /* close aggregate inodes */ + if (ipaimap2) diFreeSpecial(ipaimap2); - } - - errout35: - - /* close aggregate block allocation map */ +err_umount_ipbmap: /* close aggregate block allocation map */ dbUnmount(ipbmap, 1); +err_ipbmap: /* close aggregate inodes */ diFreeSpecial(ipbmap); - - errout22: /* close aggregate inode allocation map */ - +err_umount_ipaimap: /* close aggregate inode allocation map */ diUnmount(ipaimap, 1); - - errout21: /* close aggregate inodes */ +err_ipaimap: /* close aggregate inodes */ diFreeSpecial(ipaimap); - errout20: /* aggregate closed */ - - out: - +out: if (rc) jfs_err("Mount JFS Failure: %d", rc);
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit fcfb63148c241adad54ed99fc318167176d7254b ]
Remove the duplicate port register 22h and replace it with missing port register 21h.
Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Link: https://lore.kernel.org/r/20210922074140.22178-1-biju.das.jz@bp.renesas.com Fixes: c4c4637eb57f2a25 ("pinctrl: renesas: Add RZ/G2L pin and gpio controller driver") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/pinctrl-rzg2l.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c index dbf2f521bb272..20b2af889ca96 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c +++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c @@ -852,7 +852,7 @@ static const u32 rzg2l_gpio_configs[] = { RZG2L_GPIO_PORT_PACK(2, 0x1e, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x1f, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x20, RZG2L_MPXED_PIN_FUNCS), - RZG2L_GPIO_PORT_PACK(3, 0x22, RZG2L_MPXED_PIN_FUNCS), + RZG2L_GPIO_PORT_PACK(3, 0x21, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x22, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(2, 0x23, RZG2L_MPXED_PIN_FUNCS), RZG2L_GPIO_PORT_PACK(3, 0x24, RZG2L_MPXED_ETH_PIN_FUNCS(PIN_CFG_IOLH_ETH0)),
From: Yassine Oudjana y.oudjana@protonmail.com
[ Upstream commit a270bd9abdc3cd04ec194f1f3164823cbb5a905c ]
The versioning scheme was changed in an earlier patch, which caused the version being used to initialize WCD9335 to be interpreted as if it was WCD937X, which changed code paths causing broken headphones output. Pass WCD9335 instead of WCD9335_VERSION_2_0 to wcd_clsh_ctrl_alloc to fix it.
Fixes: 19c5d1f6a0c3 ("ASoC: codecs: wcd-clsh: add new version support") Signed-off-by: Yassine Oudjana y.oudjana@protonmail.com Reviewed-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Link: https://lore.kernel.org/r/20210925022339.786296-1-y.oudjana@protonmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wcd9335.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index d885ced34f606..bc5d68c53e5ab 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -4859,7 +4859,7 @@ static int wcd9335_codec_probe(struct snd_soc_component *component)
snd_soc_component_init_regmap(component, wcd->regmap); /* Class-H Init*/ - wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, wcd->version); + wcd->clsh_ctrl = wcd_clsh_ctrl_alloc(component, WCD9335); if (IS_ERR(wcd->clsh_ctrl)) return PTR_ERR(wcd->clsh_ctrl);
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 8199a0b31e76d158ac14841e7119890461f8c595 ]
At the moment, playing audio on Secondary MI2S will just end up getting stuck, without actually playing any audio. This happens because the wrong bit clock is configured when playing audio on Secondary MI2S.
The PRI_I2S_CLK (better name: SPKR_I2S_CLK) is used by the SPKR audio mux block that provides both Primary and Secondary MI2S.
The SEC_I2S_CLK (better name: MIC_I2S_CLK) is used by the MIC audio mux block that provides Tertiary MI2S. Quaternary MI2S is also part of the MIC audio mux but has its own clock (AUX_I2S_CLK).
This means that (quite confusingly) the SEC_I2S_CLK is not actually used for Secondary MI2S as the name would suggest. Secondary MI2S needs to have the same clock as Primary MI2S configured.
Fix the clock list for the lpass node in the device tree and add a comment to clarify this confusing naming. With these changes, audio can be played correctly on Secondary MI2S.
Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Fixes: 3761a3618f55 ("arm64: dts: qcom: add lpass node") Tested-by: Vincent Knecht vincent.knecht@mailoo.org Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210816181810.2242-1-stephan@gerhold.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/msm8916.dtsi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 3f85e34a8ce6f..fbff712639513 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -1384,11 +1384,17 @@ lpass: audio-controller@7708000 { status = "disabled"; compatible = "qcom,lpass-cpu-apq8016"; + + /* + * Note: Unlike the name would suggest, the SEC_I2S_CLK + * is actually only used by Tertiary MI2S while + * Primary/Secondary MI2S both use the PRI_I2S_CLK. + */ clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, - <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 59a8bda062f8646d99ff8c4956adf37dee1cb75e ]
While networking works fine in RGMII mode when using the Linux generic PHY driver, it fails when using the Atheros PHY driver. Fix this by correcting the Ethernet PHY mode to RGMII-RXID, which works fine with both drivers.
Fixes: a5200e63af57d05e ("arm64: dts: renesas: rzg2: Convert EtherAVB to explicit delay handling") Reported-by: Adam Ford aford173@gmail.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/2a4c15b2df23bb63f15abf9dfb88860477f4f523.163246596... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi index 090dc9c4f57b5..937d17a426b66 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi @@ -50,6 +50,7 @@ &avb { pinctrl-0 = <&avb_pins>; pinctrl-names = "default"; + phy-mode = "rgmii-rxid"; phy-handle = <&phy0>; rx-internal-delay-ps = <1800>; tx-internal-delay-ps = <2000>;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit f13efafc1a2cf30d4a74c00f40210d6de36db2d0 ]
clang-14 notices that a comparison is never true when CONFIG_PHYS_ADDR_T_64BIT is disabled:
drivers/iommu/mtk_iommu.c:553:34: error: result of comparison of constant 5368709120 with expression of type 'phys_addr_t' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare] if (dom->data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE) ~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add an explicit check for the type of the variable to skip the check and the warning in that case.
Fixes: b4dad40e4f35 ("iommu/mediatek: Adjust the PA for the 4GB Mode") Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Yong Wu yong.wu@mediatek.com Link: https://lore.kernel.org/r/20210927121857.941160-1-arnd@kernel.org Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/mtk_iommu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index d837adfd1da55..25b834104790c 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -550,7 +550,9 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, phys_addr_t pa;
pa = dom->iop->iova_to_phys(dom->iop, iova); - if (dom->data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE) + if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) && + dom->data->enable_4GB && + pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE) pa &= ~BIT_ULL(32);
return pa;
From: Stephan Gerhold stephan@gerhold.net
[ Upstream commit 483de2b44cd3a168458f8f9ff237e78a434729bc ]
While removing the size from the "reg" properties in pm8916.dtsi, commit bd6429e81010 ("ARM64: dts: qcom: Remove size elements from pmic reg properties") mistakenly also removed the second register address for the rtc@6000 device. That one did not represent the size of the register region but actually the address of the second "alarm" register region of the rtc@6000 device.
Now there are "reg-names" for two "reg" elements, but there is actually only one "reg" listed.
Since the DT schema for "qcom,pm8941-rtc" only expects one "reg" element anyway, just drop the "reg-names" entirely to fix this.
Fixes: bd6429e81010 ("ARM64: dts: qcom: Remove size elements from pmic reg properties") Signed-off-by: Stephan Gerhold stephan@gerhold.net Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210928112945.25310-1-stephan@gerhold.net Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/pm8916.dtsi | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index f931cb0de231f..42180f1b5dbbb 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -86,7 +86,6 @@ rtc@6000 { compatible = "qcom,pm8941-rtc"; reg = <0x6000>; - reg-names = "rtc", "alarm"; interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; };
From: David Stevens stevensd@chromium.org
[ Upstream commit 08ae5d4a1ae96b72222e7b02d072bb997ff29dac ]
The is_swiotlb_buffer function takes the physical address of the swiotlb buffer, not the physical address of the original buffer. The sglist contains the physical addresses of the original buffer, so for the sync_sg functions to work properly when a bounce buffer might have been used, we need to use iommu_iova_to_phys to look up the physical address. This is what sync_single does, so call that function on each sglist segment.
The previous code mostly worked because swiotlb does the transfer on map and unmap. However, any callers which use DMA_ATTR_SKIP_CPU_SYNC with sglists or which call sync_sg would not have had anything copied to the bounce buffer.
Fixes: 82612d66d51d ("iommu: Allow the iommu/dma api to use bounce buffers") Signed-off-by: David Stevens stevensd@chromium.org Reviewed-by: Robin Murphy robin.murphy@arm.com Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20210929023300.335969-2-stevensd@google.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/dma-iommu.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 896bea04c347e..c4d205b63c582 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -828,17 +828,13 @@ static void iommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg; int i;
- if (dev_is_dma_coherent(dev) && !dev_is_untrusted(dev)) - return; - - for_each_sg(sgl, sg, nelems, i) { - if (!dev_is_dma_coherent(dev)) + if (dev_is_untrusted(dev)) + for_each_sg(sgl, sg, nelems, i) + iommu_dma_sync_single_for_cpu(dev, sg_dma_address(sg), + sg->length, dir); + else if (!dev_is_dma_coherent(dev)) + for_each_sg(sgl, sg, nelems, i) arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); - - if (is_swiotlb_buffer(dev, sg_phys(sg))) - swiotlb_sync_single_for_cpu(dev, sg_phys(sg), - sg->length, dir); - } }
static void iommu_dma_sync_sg_for_device(struct device *dev, @@ -848,17 +844,14 @@ static void iommu_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg; int i;
- if (dev_is_dma_coherent(dev) && !dev_is_untrusted(dev)) - return; - - for_each_sg(sgl, sg, nelems, i) { - if (is_swiotlb_buffer(dev, sg_phys(sg))) - swiotlb_sync_single_for_device(dev, sg_phys(sg), - sg->length, dir); - - if (!dev_is_dma_coherent(dev)) + if (dev_is_untrusted(dev)) + for_each_sg(sgl, sg, nelems, i) + iommu_dma_sync_single_for_device(dev, + sg_dma_address(sg), + sg->length, dir); + else if (!dev_is_dma_coherent(dev)) + for_each_sg(sgl, sg, nelems, i) arch_sync_dma_for_device(sg_phys(sg), sg->length, dir); - } }
static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page,
From: David Stevens stevensd@chromium.org
[ Upstream commit 06e620345d544e559b2961cb5a676ec9c80c8950 ]
When calling arch_sync_dma, we need to pass it the memory that's actually being used for dma. When using swiotlb bounce buffers, this is the bounce buffer. Move arch_sync_dma into the __iommu_dma_map_swiotlb helper, so it can use the bounce buffer address if necessary.
Now that iommu_dma_map_sg delegates to a function which takes care of architectural syncing in the untrusted device case, the call to iommu_dma_sync_sg_for_device can be moved so it only occurs for trusted devices. Doing the sync for untrusted devices before mapping never really worked, since it needs to be able to target swiotlb buffers.
This also moves the architectural sync to before the call to __iommu_dma_map, to guarantee that untrusted devices can't see stale data they shouldn't see.
Fixes: 82612d66d51d ("iommu: Allow the iommu/dma api to use bounce buffers") Signed-off-by: David Stevens stevensd@chromium.org Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Robin Murphy robin.murphy@arm.com Link: https://lore.kernel.org/r/20210929023300.335969-3-stevensd@google.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/dma-iommu.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index c4d205b63c582..19bebacbf1780 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -593,6 +593,9 @@ static dma_addr_t __iommu_dma_map_swiotlb(struct device *dev, phys_addr_t phys, memset(padding_start, 0, padding_size); }
+ if (!coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + arch_sync_dma_for_device(phys, org_size, dir); + iova = __iommu_dma_map(dev, phys, aligned_size, prot, dma_mask); if (iova == DMA_MAPPING_ERROR && is_swiotlb_buffer(dev, phys)) swiotlb_tbl_unmap_single(dev, phys, org_size, dir, attrs); @@ -860,14 +863,9 @@ static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, { phys_addr_t phys = page_to_phys(page) + offset; bool coherent = dev_is_dma_coherent(dev); - dma_addr_t dma_handle;
- dma_handle = __iommu_dma_map_swiotlb(dev, phys, size, dma_get_mask(dev), + return __iommu_dma_map_swiotlb(dev, phys, size, dma_get_mask(dev), coherent, dir, attrs); - if (!coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC) && - dma_handle != DMA_MAPPING_ERROR) - arch_sync_dma_for_device(phys, size, dir); - return dma_handle; }
static void iommu_dma_unmap_page(struct device *dev, dma_addr_t dma_handle, @@ -1012,12 +1010,12 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, goto out; }
- if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - iommu_dma_sync_sg_for_device(dev, sg, nents, dir); - if (dev_is_untrusted(dev)) return iommu_dma_map_sg_swiotlb(dev, sg, nents, dir, attrs);
+ if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + iommu_dma_sync_sg_for_device(dev, sg, nents, dir); + /* * Work out how much IOVA space we need, and align the segments to * IOVA granules for the IOMMU driver to handle. With some clever
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 46243b85b0ec5d2cee7545e5ce18c015ce91957e ]
The position reporting on Intel Skylake and later chips via azx_get_pos_skl() contains a udelay(20) call for the capture streams. A call for this alone doesn't sound too harmful. However, as the pointer PCM ops is one of the hottest path in the PCM operations -- especially for the timer-scheduled operations like PulseAudio -- such a delay hogs CPU usage significantly in the total performance.
The code there was taken from the original code in ASoC SST Skylake driver blindly. The udelay() is a workaround for the case where the reported position is behind the period boundary at the timing triggered from interrupts; applications often expect that the full data is available for the whole period when returned (and also that's the definition of the ALSA PCM period).
OTOH, HD-audio (legacy) driver has already some workarounds for the delayed position reporting due to its relatively large FIFO, such as the BDL position adjustment and the delayed period-elapsed call in the work. That said, the udelay() is almost superfluous for HD-audio driver unlike SST, and we can drop the udelay().
Though, the current code doesn't guarantee the full period readiness as mentioned in the above, but rather it checks the wallclock and detects the unexpected jump. That's one missing piece, and the drop of udelay() needs a bit more sanity checks for the delayed handling.
This patch implements those: the drop of udelay() call in azx_get_pos_skl() and the more proper check of hwptr in azx_position_ok(). The latter change is applied only for the case where the stream is running in the normal mode without no_period_wakeup flag. When no_period_wakeup is set, it essentially ignores the period handling and rather concentrates only on the current position; which implies that we don't need to care about the period boundary at all.
Fixes: f87e7f25893d ("ALSA: hda - Improved position reporting on SKL+") Reported-by: Jens Axboe axboe@kernel.dk Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20210929072934.6809-2-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/hda_intel.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b278706630fcb..95b9a615c47ca 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -638,13 +638,17 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) * the update-IRQ timing. The IRQ is issued before actually the * data is processed. So, we need to process it afterwords in a * workqueue. + * + * Returns 1 if OK to proceed, 0 for delay handling, -1 for skipping update */ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) { struct snd_pcm_substream *substream = azx_dev->core.substream; + struct snd_pcm_runtime *runtime = substream->runtime; int stream = substream->stream; u32 wallclk; unsigned int pos; + snd_pcm_uframes_t hwptr, target;
wallclk = azx_readl(chip, WALLCLK) - azx_dev->core.start_wallclk; if (wallclk < (azx_dev->core.period_wallclk * 2) / 3) @@ -681,6 +685,24 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) /* NG - it's below the first next period boundary */ return chip->bdl_pos_adj ? 0 : -1; azx_dev->core.start_wallclk += wallclk; + + if (azx_dev->core.no_period_wakeup) + return 1; /* OK, no need to check period boundary */ + + if (runtime->hw_ptr_base != runtime->hw_ptr_interrupt) + return 1; /* OK, already in hwptr updating process */ + + /* check whether the period gets really elapsed */ + pos = bytes_to_frames(runtime, pos); + hwptr = runtime->hw_ptr_base + pos; + if (hwptr < runtime->status->hw_ptr) + hwptr += runtime->buffer_size; + target = runtime->hw_ptr_interrupt + runtime->period_size; + if (hwptr < target) { + /* too early wakeup, process it later */ + return chip->bdl_pos_adj ? 0 : -1; + } + return 1; /* OK, it's fine */ }
@@ -875,11 +897,7 @@ static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev) if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return azx_skl_get_dpib_pos(chip, azx_dev);
- /* For capture, we need to read posbuf, but it requires a delay - * for the possible boundary overlap; the read of DPIB fetches the - * actual posbuf - */ - udelay(20); + /* read of DPIB fetches the actual posbuf */ azx_skl_get_dpib_pos(chip, azx_dev); return azx_get_pos_posbuf(chip, azx_dev); }
From: Takashi Iwai tiwai@suse.de
[ Upstream commit c4ca3871e21fa085096316f5f8d9975cf3dfde1d ]
The commit f87e7f25893d ("ALSA: hda - Improved position reporting on SKL+") changed the PCM position report for SKL+ chips to use DPIB, but according to Pierre, DPIB is no best choice for the accurate position reports and it often reports too early. The recommended method is rather the classical position buffer.
This patch makes the PCM position reporting on SKL+ back to the position buffer again.
Fixes: f87e7f25893d ("ALSA: hda - Improved position reporting on SKL+") Suggested-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20210929072934.6809-3-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/hda_intel.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 95b9a615c47ca..90e9263ac0bd7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -881,27 +881,6 @@ static int azx_get_delay_from_fifo(struct azx *chip, struct azx_dev *azx_dev, return substream->runtime->delay; }
-static unsigned int azx_skl_get_dpib_pos(struct azx *chip, - struct azx_dev *azx_dev) -{ - return _snd_hdac_chip_readl(azx_bus(chip), - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - azx_dev->core.index)); -} - -/* get the current DMA position with correction on SKL+ chips */ -static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev) -{ - /* DPIB register gives a more accurate position for playback */ - if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return azx_skl_get_dpib_pos(chip, azx_dev); - - /* read of DPIB fetches the actual posbuf */ - azx_skl_get_dpib_pos(chip, azx_dev); - return azx_get_pos_posbuf(chip, azx_dev); -} - static void __azx_shutdown_chip(struct azx *chip, bool skip_link_reset) { azx_stop_chip(chip); @@ -1591,7 +1570,7 @@ static void assign_position_fix(struct azx *chip, int fix) [POS_FIX_POSBUF] = azx_get_pos_posbuf, [POS_FIX_VIACOMBO] = azx_via_get_position, [POS_FIX_COMBO] = azx_get_pos_lpib, - [POS_FIX_SKL] = azx_get_pos_skl, + [POS_FIX_SKL] = azx_get_pos_posbuf, [POS_FIX_FIFO] = azx_get_pos_fifo, };
From: Takashi Iwai tiwai@suse.de
[ Upstream commit 86a42ad07905110f82648853c0ea3434b4eab173 ]
USB-audio driver tries to sync with the clear of all pending URBs in wait_clear_urbs(), and it waits for all bits in active_mask getting cleared. This works fine for the normal operations, but when a stream is managed in the implicit feedback mode, there is still a very thin race window: namely, in snd_complete_usb(), the active_mask bit for the current URB is once cleared before re-submitted in queue_pending_output_urbs(). If wait_clear_urbs() is called during that period, it may pass the test and go forward even though there may be a still pending URB.
For covering it, this patch adds a new counter to each endpoint to keep the number of in-flight URBs, and changes wait_clear_urbs() checking this number instead. The counter is decremented at the end of URB complete, hence the reference is kept as long as the URB complete is in process.
Link: https://lore.kernel.org/r/20210929080844.11583-3-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/card.h | 1 + sound/usb/endpoint.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/sound/usb/card.h b/sound/usb/card.h index 5b19901f305a3..860faaf249ea6 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -97,6 +97,7 @@ struct snd_usb_endpoint { unsigned int nominal_queue_size; /* total buffer sizes in URBs */ unsigned long active_mask; /* bitmask of active urbs */ unsigned long unlink_mask; /* bitmask of unlinked urbs */ + atomic_t submitted_urbs; /* currently submitted urbs */ char *syncbuf; /* sync buffer for all sync URBs */ dma_addr_t sync_dma; /* DMA address of syncbuf */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 533919a28856f..ba2d7e6884207 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -451,6 +451,7 @@ static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) }
set_bit(ctx->index, &ep->active_mask); + atomic_inc(&ep->submitted_urbs); } }
@@ -488,6 +489,7 @@ static void snd_complete_urb(struct urb *urb) clear_bit(ctx->index, &ep->active_mask); spin_unlock_irqrestore(&ep->lock, flags); queue_pending_output_urbs(ep); + atomic_dec(&ep->submitted_urbs); /* decrement at last */ return; }
@@ -513,6 +515,7 @@ static void snd_complete_urb(struct urb *urb)
exit_clear: clear_bit(ctx->index, &ep->active_mask); + atomic_dec(&ep->submitted_urbs); }
/* @@ -596,6 +599,7 @@ int snd_usb_add_endpoint(struct snd_usb_audio *chip, int ep_num, int type) ep->type = type; ep->ep_num = ep_num; INIT_LIST_HEAD(&ep->ready_playback_urbs); + atomic_set(&ep->submitted_urbs, 0);
is_playback = ((ep_num & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); ep_num &= USB_ENDPOINT_NUMBER_MASK; @@ -859,7 +863,7 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep) return 0;
do { - alive = bitmap_weight(&ep->active_mask, ep->nurbs); + alive = atomic_read(&ep->submitted_urbs); if (!alive) break;
@@ -1420,6 +1424,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) goto __error; } set_bit(i, &ep->active_mask); + atomic_inc(&ep->submitted_urbs); }
usb_audio_dbg(ep->chip, "%d URBs submitted for EP 0x%x\n",
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
[ Upstream commit 75eac387a2539aa6c6bbee3affa23435f2096396 ]
link_id can be zero and if we have multiple controller instances in a system like Qualcomm debugfs will end-up with duplicate namespace resulting in incorrect debugfs entries.
Using bus-id and link-id combination should give a unique debugfs directory entry and should fix below warning too. "debugfs: Directory 'master-0' with parent 'soundwire' already present!"
Fixes: bf03473d5bcc ("soundwire: add debugfs support") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20210907105332.1257-1-srinivas.kandagatla@linaro.o... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index b6cad0d59b7b9..49900cd207bc7 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -19,7 +19,7 @@ void sdw_bus_debugfs_init(struct sdw_bus *bus) return;
/* create the debugfs master-N */ - snprintf(name, sizeof(name), "master-%d", bus->link_id); + snprintf(name, sizeof(name), "master-%d-%d", bus->id, bus->link_id); bus->debugfs = debugfs_create_dir(name, sdw_debugfs_root); }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit f558c8072c3461b65c12c0068b108f78cebc8246 ]
devm_of_iomap() returns error code or valid pointer. Check its return value with IS_ERR().
Fixes: bd3127733f2c ("power: reset: at91-reset: use devm_of_iomap") Reported-by: Cristian Birsan cristian.birsan@microchip.com Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/reset/at91-reset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c index 026649409135c..64def79d557a8 100644 --- a/drivers/power/reset/at91-reset.c +++ b/drivers/power/reset/at91-reset.c @@ -193,7 +193,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) return -ENOMEM;
reset->rstc_base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); - if (!reset->rstc_base) { + if (IS_ERR(reset->rstc_base)) { dev_err(&pdev->dev, "Could not map reset controller address\n"); return -ENODEV; } @@ -203,7 +203,7 @@ static int __init at91_reset_probe(struct platform_device *pdev) for_each_matching_node_and_match(np, at91_ramc_of_match, &match) { reset->ramc_lpr = (u32)match->data; reset->ramc_base[idx] = devm_of_iomap(&pdev->dev, np, 0, NULL); - if (!reset->ramc_base[idx]) { + if (IS_ERR(reset->ramc_base[idx])) { dev_err(&pdev->dev, "Could not map ram controller address\n"); of_node_put(np); return -ENODEV;
From: Bean Huo beanhuo@micron.com
[ Upstream commit 68444d73d6a5864ede12df6366bd6602e022ae5b ]
Since commit 568dd9959611 ("scsi: ufs: Rename the second ufshcd_probe_hba() argument"), the second ufshcd_probe_hba() argument has been changed to init_dev_params.
Link: https://lore.kernel.org/r/20210929200640.828611-3-huobean@gmail.com Fixes: 568dd9959611 ("scsi: ufs: Rename the second ufshcd_probe_hba() argument") Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Bean Huo beanhuo@micron.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 41f2ff35f82b2..b02feb3ab7b56 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -223,7 +223,7 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); -static int ufshcd_probe_hba(struct ufs_hba *hba, bool async); +static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba);
From: Bart Van Assche bvanassche@google.com
[ Upstream commit edc0596cc04bf0ac3a69c66e994d3ff8b650ff71 ]
Commit aa53f580e67b ("scsi: ufs: Minor adjustments to error handling") introduced a ufshcd_clear_ua_wluns() call in ufshcd_err_handling_unprepare(). As explained in detail by Adrian Hunter, this can trigger a deadlock. Avoid that deadlock by removing the code that clears the unit attention. This is safe because the only software that relies on clearing unit attentions is the Android Trusty software and because support for handling unit attentions has been added in the Trusty software.
See also https://lore.kernel.org/linux-scsi/20210930124224.114031-2-adrian.hunter@int...
Note that "scsi: ufs: Retry START_STOP on UNIT_ATTENTION" is a prerequisite for this commit.
Link: https://lore.kernel.org/r/20211001182015.1347587-3-jaegeuk@kernel.org Fixes: aa53f580e67b ("scsi: ufs: Minor adjustments to error handling") Cc: Adrian Hunter adrian.hunter@intel.com Signed-off-by: Bart Van Assche bvanassche@google.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd.c | 184 +------------------------------------- drivers/scsi/ufs/ufshcd.h | 14 --- 2 files changed, 1 insertion(+), 197 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index b02feb3ab7b56..20705cec83c55 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -222,7 +222,6 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba); static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag); static void ufshcd_hba_exit(struct ufs_hba *hba); -static int ufshcd_clear_ua_wluns(struct ufs_hba *hba); static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params); static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on); static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba); @@ -4073,8 +4072,6 @@ int ufshcd_link_recovery(struct ufs_hba *hba) if (ret) dev_err(hba->dev, "%s: link recovery failed, err %d", __func__, ret); - else - ufshcd_clear_ua_wluns(hba);
return ret; } @@ -5959,7 +5956,6 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) ufshcd_release(hba); if (ufshcd_is_clkscaling_supported(hba)) ufshcd_clk_scaling_suspend(hba, false); - ufshcd_clear_ua_wluns(hba); ufshcd_rpm_put(hba); }
@@ -7875,8 +7871,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba) if (ret) goto out;
- ufshcd_clear_ua_wluns(hba); - /* Initialize devfreq after UFS device is detected */ if (ufshcd_is_clkscaling_supported(hba)) { memcpy(&hba->clk_scaling.saved_pwr_info.info, @@ -7902,116 +7896,6 @@ out: return ret; }
-static void ufshcd_request_sense_done(struct request *rq, blk_status_t error) -{ - if (error != BLK_STS_OK) - pr_err("%s: REQUEST SENSE failed (%d)\n", __func__, error); - kfree(rq->end_io_data); - blk_put_request(rq); -} - -static int -ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev) -{ - /* - * Some UFS devices clear unit attention condition only if the sense - * size used (UFS_SENSE_SIZE in this case) is non-zero. - */ - static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, UFS_SENSE_SIZE, 0}; - struct scsi_request *rq; - struct request *req; - char *buffer; - int ret; - - buffer = kzalloc(UFS_SENSE_SIZE, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, - /*flags=*/BLK_MQ_REQ_PM); - if (IS_ERR(req)) { - ret = PTR_ERR(req); - goto out_free; - } - - ret = blk_rq_map_kern(sdev->request_queue, req, - buffer, UFS_SENSE_SIZE, GFP_NOIO); - if (ret) - goto out_put; - - rq = scsi_req(req); - rq->cmd_len = ARRAY_SIZE(cmd); - memcpy(rq->cmd, cmd, rq->cmd_len); - rq->retries = 3; - req->timeout = 1 * HZ; - req->rq_flags |= RQF_PM | RQF_QUIET; - req->end_io_data = buffer; - - blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true, - ufshcd_request_sense_done); - return 0; - -out_put: - blk_put_request(req); -out_free: - kfree(buffer); - return ret; -} - -static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun) -{ - struct scsi_device *sdp; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(hba->host->host_lock, flags); - if (wlun == UFS_UPIU_UFS_DEVICE_WLUN) - sdp = hba->sdev_ufs_device; - else if (wlun == UFS_UPIU_RPMB_WLUN) - sdp = hba->sdev_rpmb; - else - BUG(); - if (sdp) { - ret = scsi_device_get(sdp); - if (!ret && !scsi_device_online(sdp)) { - ret = -ENODEV; - scsi_device_put(sdp); - } - } else { - ret = -ENODEV; - } - spin_unlock_irqrestore(hba->host->host_lock, flags); - if (ret) - goto out_err; - - ret = ufshcd_request_sense_async(hba, sdp); - scsi_device_put(sdp); -out_err: - if (ret) - dev_err(hba->dev, "%s: UAC clear LU=%x ret = %d\n", - __func__, wlun, ret); - return ret; -} - -static int ufshcd_clear_ua_wluns(struct ufs_hba *hba) -{ - int ret = 0; - - if (!hba->wlun_dev_clr_ua) - goto out; - - ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN); - if (!ret) - ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN); - if (!ret) - hba->wlun_dev_clr_ua = false; -out: - if (ret) - dev_err(hba->dev, "%s: Failed to clear UAC WLUNS ret = %d\n", - __func__, ret); - return ret; -} - /** * ufshcd_probe_hba - probe hba to detect device and initialize it * @hba: per-adapter instance @@ -8062,8 +7946,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool init_dev_params) /* UFS device is also active now */ ufshcd_set_ufs_dev_active(hba); ufshcd_force_reset_auto_bkops(hba); - hba->wlun_dev_clr_ua = true; - hba->wlun_rpmb_clr_ua = true;
/* Gear up to HS gear if supported */ if (hba->max_pwr_info.is_valid) { @@ -8625,8 +8507,6 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, * handling context. */ hba->host->eh_noresume = 1; - if (hba->wlun_dev_clr_ua) - ufshcd_clear_ua_wlun(hba, UFS_UPIU_UFS_DEVICE_WLUN);
cmd[4] = pwr_mode << 4;
@@ -9699,10 +9579,6 @@ void ufshcd_resume_complete(struct device *dev) ufshcd_rpm_put(hba); hba->complete_put = false; } - if (hba->rpmb_complete_put) { - ufshcd_rpmb_rpm_put(hba); - hba->rpmb_complete_put = false; - } } EXPORT_SYMBOL_GPL(ufshcd_resume_complete);
@@ -9725,10 +9601,6 @@ int ufshcd_suspend_prepare(struct device *dev) } hba->complete_put = true; } - if (hba->sdev_rpmb) { - ufshcd_rpmb_rpm_get_sync(hba); - hba->rpmb_complete_put = true; - } return 0; } EXPORT_SYMBOL_GPL(ufshcd_suspend_prepare); @@ -9797,49 +9669,6 @@ static struct scsi_driver ufs_dev_wlun_template = { }, };
-static int ufshcd_rpmb_probe(struct device *dev) -{ - return is_rpmb_wlun(to_scsi_device(dev)) ? 0 : -ENODEV; -} - -static inline int ufshcd_clear_rpmb_uac(struct ufs_hba *hba) -{ - int ret = 0; - - if (!hba->wlun_rpmb_clr_ua) - return 0; - ret = ufshcd_clear_ua_wlun(hba, UFS_UPIU_RPMB_WLUN); - if (!ret) - hba->wlun_rpmb_clr_ua = 0; - return ret; -} - -#ifdef CONFIG_PM -static int ufshcd_rpmb_resume(struct device *dev) -{ - struct ufs_hba *hba = wlun_dev_to_hba(dev); - - if (hba->sdev_rpmb) - ufshcd_clear_rpmb_uac(hba); - return 0; -} -#endif - -static const struct dev_pm_ops ufs_rpmb_pm_ops = { - SET_RUNTIME_PM_OPS(NULL, ufshcd_rpmb_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(NULL, ufshcd_rpmb_resume) -}; - -/* ufs_rpmb_wlun_template - Describes UFS RPMB WLUN. Used only to send UAC. */ -static struct scsi_driver ufs_rpmb_wlun_template = { - .gendrv = { - .name = "ufs_rpmb_wlun", - .owner = THIS_MODULE, - .probe = ufshcd_rpmb_probe, - .pm = &ufs_rpmb_pm_ops, - }, -}; - static int __init ufshcd_core_init(void) { int ret; @@ -9848,24 +9677,13 @@ static int __init ufshcd_core_init(void)
ret = scsi_register_driver(&ufs_dev_wlun_template.gendrv); if (ret) - goto debugfs_exit; - - ret = scsi_register_driver(&ufs_rpmb_wlun_template.gendrv); - if (ret) - goto unregister; - - return ret; -unregister: - scsi_unregister_driver(&ufs_dev_wlun_template.gendrv); -debugfs_exit: - ufs_debugfs_exit(); + ufs_debugfs_exit(); return ret; }
static void __exit ufshcd_core_exit(void) { ufs_debugfs_exit(); - scsi_unregister_driver(&ufs_rpmb_wlun_template.gendrv); scsi_unregister_driver(&ufs_dev_wlun_template.gendrv); }
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 41f6e06f91856..07ada6676c3b4 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -871,9 +871,6 @@ struct ufs_hba { struct ufs_vreg_info vreg_info; struct list_head clk_list_head;
- bool wlun_dev_clr_ua; - bool wlun_rpmb_clr_ua; - /* Number of requests aborts */ int req_abort_count;
@@ -920,7 +917,6 @@ struct ufs_hba { #endif u32 luns_avail; bool complete_put; - bool rpmb_complete_put; };
/* Returns true if clocks can be gated. Otherwise false */ @@ -1393,14 +1389,4 @@ static inline int ufshcd_rpm_put(struct ufs_hba *hba) return pm_runtime_put(&hba->sdev_ufs_device->sdev_gendev); }
-static inline int ufshcd_rpmb_rpm_get_sync(struct ufs_hba *hba) -{ - return pm_runtime_get_sync(&hba->sdev_rpmb->sdev_gendev); -} - -static inline int ufshcd_rpmb_rpm_put(struct ufs_hba *hba) -{ - return pm_runtime_put(&hba->sdev_rpmb->sdev_gendev); -} - #endif /* End of Header */
From: Sumit Saxena sumit.saxena@broadcom.com
[ Upstream commit e7dcc514a49e74051b869697d5ab0370f6301d57 ]
IRQ polling thread calls ISR after enable_irq() to handle any missed I/O completion. The atomic flag "in_used" was added to have the synchronization between the IRQ polling thread and the interrupt context. There is a bug around it leading to a race condition.
Below is the sequence:
- IRQ polling thread accesses ISR, fetches the reply descriptor.
- Real interrupt arrives and pre-empts polling thread (enable_irq() is already called).
- Interrupt context picks the same reply descriptor as fetched by polling thread, processes it, and exits.
- Polling thread resumes and processes the descriptor which is already processed by interrupt thread leads to kernel crash.
Setting the "in_used" flag before fetching the reply descriptor ensures synchronized access to ISR.
Link: https://www.spinics.net/lists/linux-scsi/msg159440.html Link: https://lore.kernel.org/r/20210929124022.24605-2-sumit.saxena@broadcom.com Fixes: 9bedd36e9146 ("scsi: megaraid_sas: Handle missing interrupts while re-enabling IRQs") Signed-off-by: Sumit Saxena sumit.saxena@broadcom.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 26d0cf9353dd6..eb5ceb75a15ec 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3530,6 +3530,9 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) return IRQ_HANDLED;
+ if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1)) + return 0; + desc = fusion->reply_frames_desc[MSIxIndex] + fusion->last_reply_idx[MSIxIndex];
@@ -3540,11 +3543,11 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, reply_descript_type = reply_desc->ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
- if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) + if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) { + if (irq_context) + atomic_dec(&irq_context->in_used); return IRQ_NONE; - - if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1)) - return 0; + }
num_completed = 0;
From: Igor Pylypiv ipylypiv@google.com
[ Upstream commit 4084a7235d38311a77c86ba69ba849bd787db87b ]
pm8001_mpi_get_nvmd_resp() handles a GET_NVMD_DATA response, not a SET_NVMD_DATA response, as the log statement implies.
Fixes: 1f889b58716a ("scsi: pm80xx: Fix pm8001_mpi_get_nvmd_resp() race condition") Link: https://lore.kernel.org/r/20210929025847.646999-1-ipylypiv@google.com Reviewed-by: Changyuan Lyu changyuanl@google.com Acked-by: Jack Wang jinpu.wang@ionos.com Signed-off-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 63690508313b7..639b7e38a1947 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3169,7 +3169,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) * fw_control_context->usrAddr */ complete(pm8001_ha->nvmd_completion); - pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n"); + pm8001_dbg(pm8001_ha, MSG, "Get nvmd data complete!\n"); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; pm8001_tag_free(pm8001_ha, tag);
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit df0a18149474c7e6b21f6367fbc6bc8d0f192444 ]
I got memory leak as follows:
unreferenced object 0xffff88801f0b2200 (size 64): comm "i2c-lis2hh12-21", pid 5455, jiffies 4294944606 (age 15.224s) hex dump (first 32 bytes): 72 65 67 75 6c 61 74 6f 72 3a 72 65 67 75 6c 61 regulator:regula 74 6f 72 2e 30 2d 2d 69 32 63 3a 31 2d 30 30 31 tor.0--i2c:1-001 backtrace: [<00000000bf5b0c3b>] __kmalloc_track_caller+0x19f/0x3a0 [<0000000050da42d9>] kvasprintf+0xb5/0x150 [<000000004bbbed13>] kvasprintf_const+0x60/0x190 [<00000000cdac7480>] kobject_set_name_vargs+0x56/0x150 [<00000000bf83f8e8>] dev_set_name+0xc0/0x100 [<00000000cc1cf7e3>] device_link_add+0x6b4/0x17c0 [<000000009db9faed>] _regulator_get+0x297/0x680 [<00000000845e7f2b>] _devm_regulator_get+0x5b/0xe0 [<000000003958ee25>] st_sensors_power_enable+0x71/0x1b0 [st_sensors] [<000000005f450f52>] st_accel_i2c_probe+0xd9/0x150 [st_accel_i2c] [<00000000b5f2ab33>] i2c_device_probe+0x4d8/0xbe0 [<0000000070fb977b>] really_probe+0x299/0xc30 [<0000000088e226ce>] __driver_probe_device+0x357/0x500 [<00000000c21dda32>] driver_probe_device+0x4e/0x140 [<000000004e650441>] __device_attach_driver+0x257/0x340 [<00000000cf1891b8>] bus_for_each_drv+0x166/0x1e0
When device_register() returns an error, the name allocated in dev_set_name() will be leaked, the put_device() should be used instead of kfree() to give up the device reference, then the name will be freed in kobject_cleanup() and the references of consumer and supplier will be decreased in device_link_release_fn().
Fixes: 287905e68dd2 ("driver core: Expose device link details in sysfs") Reported-by: Hulk Robot hulkci@huawei.com Reviewed-by: Saravana Kannan saravanak@google.com Reviewed-by: Rafael J. Wysocki rafael@kernel.org Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20210930085714.2057460-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c index 249da496581a0..63577de268565 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -821,9 +821,7 @@ struct device_link *device_link_add(struct device *consumer, dev_bus_name(supplier), dev_name(supplier), dev_bus_name(consumer), dev_name(consumer)); if (device_register(&link->link_dev)) { - put_device(consumer); - put_device(supplier); - kfree(link); + put_device(&link->link_dev); link = NULL; goto out; }
From: Andreas Kemnade andreas@kemnade.info
[ Upstream commit 884ea75d79a36faf3731ad9d6b9c29f58697638d ]
Fix typo in pinctrl. It did only work because the bootloader seems to have initialized it.
Fixes: ee327111953b ("ARM: dts: omap3-gta04: Define and use bma180 irq pin") Signed-off-by: Andreas Kemnade andreas@kemnade.info Signed-off-by: Tony Lindgren tony@atomide.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/omap3-gta04.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index 938cc691bb2fe..23ab27fe4ee5d 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -515,7 +515,7 @@ compatible = "bosch,bma180"; reg = <0x41>; pinctrl-names = "default"; - pintcrl-0 = <&bma180_pins>; + pinctrl-0 = <&bma180_pins>; interrupt-parent = <&gpio4>; interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_115 */ };
From: Ranjani Sridharan ranjani.sridharan@linux.intel.com
[ Upstream commit ec626334eaffe101df9ed79e161eba95124e64ad ]
When removing the topology components, do not power down the primary core. Doing so will result in an IPC timeout when the SOF PCI device runtime suspends.
Fixes: 0dcdf84289fb ("ASoC: SOF: add a "core" parameter to widget loading functions")
Signed-off-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Kai Vehmanen kai.vehmanen@linux.intel.com Signed-off-by: Peter Ujfalusi peter.ujfalusi@linux.intel.com Link: https://lore.kernel.org/r/20211006104041.27183-1-peter.ujfalusi@linux.intel.... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sof/topology.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index cc9585bfa4e9f..1bb2dcf37ffe9 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2598,6 +2598,15 @@ static int sof_widget_unload(struct snd_soc_component *scomp,
/* power down the pipeline schedule core */ pipeline = swidget->private; + + /* + * Runtime PM should still function normally if topology loading fails and + * it's components are unloaded. Do not power down the primary core so that the + * CTX_SAVE IPC can succeed during runtime suspend. + */ + if (pipeline->core == SOF_DSP_PRIMARY_CORE) + break; + ret = snd_sof_dsp_core_power_down(sdev, 1 << pipeline->core); if (ret < 0) dev_err(scomp->dev, "error: powering down pipeline schedule core %d\n",
From: Mark Brown broonie@kernel.org
[ Upstream commit 03748d4e003c9f2ad3cd00e3e46f054dcad6b96d ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding SPI IDs for parts that only have a compatible listed.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20210927134153.12739-1-broonie@kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/pressure/st_pressure_spi.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/iio/pressure/st_pressure_spi.c b/drivers/iio/pressure/st_pressure_spi.c index 5001aae8f00b8..e220cf0b125f1 100644 --- a/drivers/iio/pressure/st_pressure_spi.c +++ b/drivers/iio/pressure/st_pressure_spi.c @@ -117,6 +117,10 @@ static const struct spi_device_id st_press_id_table[] = { { LPS33HW_PRESS_DEV_NAME }, { LPS35HW_PRESS_DEV_NAME }, { LPS22HH_PRESS_DEV_NAME }, + { "lps001wp-press" }, + { "lps25h-press", }, + { "lps331ap-press" }, + { "lps22hb-press" }, {}, }; MODULE_DEVICE_TABLE(spi, st_press_id_table);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 986b5094708e508baa452a23ffe809870934a7df ]
If an error occurs after a successful tegra_powergate_enable_clocks() call, it must be undone by a tegra_powergate_disable_clocks() call, as already done in the below and above error handling paths of this function.
Update the 'goto' to branch at the correct place of the error handling path.
Fixes: a38045121bf4 ("soc/tegra: pmc: Add generic PM domain support") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Jon Hunter jonathanh@nvidia.com Signed-off-by: Thierry Reding treding@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/tegra/pmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 50091c4ec9481..a60e142ade344 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -782,7 +782,7 @@ static int tegra_powergate_power_up(struct tegra_powergate *pg,
err = reset_control_deassert(pg->reset); if (err) - goto powergate_off; + goto disable_clks;
usleep_range(10, 20);
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit 4ed2f3545c2e5acfbccd7f85fea5b1a82e9862d7 ]
The error handling code of fsl_ifc_ctrl_probe is problematic. When fsl_ifc_ctrl_init fails or request_irq of fsl_ifc_ctrl_dev->irq fails, it forgets to free the irq and nand_irq. Meanwhile, if request_irq of fsl_ifc_ctrl_dev->nand_irq fails, it will still free nand_irq even if the request_irq is not successful.
Fix this by refactoring the error handling code.
Fixes: d2ae2e20fbdd ("driver/memory:Move Freescale IFC driver to a common driver") Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Link: https://lore.kernel.org/r/20210925151434.8170-1-mudongliangabcd@gmail.com Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/memory/fsl_ifc.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c index d062c2f8250f4..75a8c38df9394 100644 --- a/drivers/memory/fsl_ifc.c +++ b/drivers/memory/fsl_ifc.c @@ -263,7 +263,7 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev)
ret = fsl_ifc_ctrl_init(fsl_ifc_ctrl_dev); if (ret < 0) - goto err; + goto err_unmap_nandirq;
init_waitqueue_head(&fsl_ifc_ctrl_dev->nand_wait);
@@ -272,7 +272,7 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->irq); - goto err_irq; + goto err_unmap_nandirq; }
if (fsl_ifc_ctrl_dev->nand_irq) { @@ -281,17 +281,16 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->nand_irq); - goto err_nandirq; + goto err_free_irq; } }
return 0;
-err_nandirq: - free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev); - irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); -err_irq: +err_free_irq: free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); +err_unmap_nandirq: + irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); err: iounmap(fsl_ifc_ctrl_dev->gregs);
From: Clément Léger clement.leger@bootlin.com
[ Upstream commit c405f5c15e9f6094f2fa1658e73e56f3058e2122 ]
Currently, at91 pmc driver always register the syscore_ops whatever the status of the pmc node that has been found. When set as secure and disabled, the pmc should not be accessed or this will generate abort exceptions. To avoid this, add a check on node availability before registering the syscore operations.
Signed-off-by: Clément Léger clement.leger@bootlin.com Link: https://lore.kernel.org/r/20210913082633.110168-1-clement.leger@bootlin.com Acked-by: Nicolas Ferre nicolas.ferre@microchip.com Reviewed-by: Claudiu Beznea claudiu.beznea@microchip.com Fixes: b3b02eac33ed ("clk: at91: Add sama5d2 suspend/resume") Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/at91/pmc.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 20ee9dccee787..b40035b011d0a 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -267,6 +267,11 @@ static int __init pmc_register_ops(void) if (!np) return -ENODEV;
+ if (!of_device_is_available(np)) { + of_node_put(np); + return -ENODEV; + } + pmcreg = device_node_to_regmap(np); of_node_put(np); if (IS_ERR(pmcreg))
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit 7eff9bc00ddf1e2281dff575884b7f676c85b006 ]
Commit 8e11d62e2e87 ("powerpc/mem: Add back missing header to fix 'no previous prototype' error") was supposed to fix the problem, but in the meantime commit a927bd6ba952 ("mm: fix phys_to_target_node() and* memory_add_physaddr_to_nid() exports") moved create_section_mapping() prototype from asm/sparsemem.h to asm/mmzone.h
Fixes: 8e11d62e2e87 ("powerpc/mem: Add back missing header to fix 'no previous prototype' error") Reported-by: kernel test robot lkp@intel.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/025754fde3d027904ae9d0191f395890bec93369.163154164... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index c3c4e31462eca..05b9c3f31456c 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -20,8 +20,8 @@ #include <asm/machdep.h> #include <asm/rtas.h> #include <asm/kasan.h> -#include <asm/sparsemem.h> #include <asm/svm.h> +#include <asm/mmzone.h>
#include <mm/mmu_decl.h>
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit f2719b26ae27282c145202ffd656d5ff1fe737cc ]
While investigating a lockup at startup on Powerbook 3400C, it was identified that the fbdev driver generates alignment exception at startup:
--- interrupt: 600 at memset+0x60/0xc0 NIP: c0021414 LR: c03fc49c CTR: 00007fff REGS: ca021c10 TRAP: 0600 Tainted: G W (5.14.2-pmac-00727-g12a41fa69492) MSR: 00009032 <EE,ME,IR,DR,RI> CR: 44008442 XER: 20000100 DAR: cab80020 DSISR: 00017c07 GPR00: 00000007 ca021cd0 c14412e0 cab80000 00000000 00100000 cab8001c 00000004 GPR08: 00100000 00007fff 00000000 00000000 84008442 00000000 c0006fb4 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00100000 GPR24: 00000000 81800000 00000320 c15fa400 c14d1878 00000000 c14d1800 c094e19c NIP [c0021414] memset+0x60/0xc0 LR [c03fc49c] chipsfb_pci_init+0x160/0x580 --- interrupt: 600 [ca021cd0] [c03fc46c] chipsfb_pci_init+0x130/0x580 (unreliable) [ca021d20] [c03a3a70] pci_device_probe+0xf8/0x1b8 [ca021d50] [c043d584] really_probe.part.0+0xac/0x388 [ca021d70] [c043d914] __driver_probe_device+0xb4/0x170 [ca021d90] [c043da18] driver_probe_device+0x48/0x144 [ca021dc0] [c043e318] __driver_attach+0x11c/0x1c4 [ca021de0] [c043ad30] bus_for_each_dev+0x88/0xf0 [ca021e10] [c043c724] bus_add_driver+0x190/0x22c [ca021e40] [c043ee94] driver_register+0x9c/0x170 [ca021e60] [c0006c28] do_one_initcall+0x54/0x1ec [ca021ed0] [c08246e4] kernel_init_freeable+0x1c0/0x270 [ca021f10] [c0006fdc] kernel_init+0x28/0x11c [ca021f30] [c0017148] ret_from_kernel_thread+0x14/0x1c Instruction dump: 7d4601a4 39490777 7d4701a4 39490888 7d4801a4 39490999 7d4901a4 39290aaa 7d2a01a4 4c00012c 4bfffe88 0fe00000 <4bfffe80> 9421fff0 38210010 48001970
This is due to 'dcbz' instruction being used on non-cached memory. 'dcbz' instruction is used by memset() to zeroize a complete cacheline at once, and memset() is not expected to be used on non cached memory.
When performing a 'sparse' check on fbdev driver, it also appears that the use of memset() is unexpected:
drivers/video/fbdev/chipsfb.c:334:17: warning: incorrect type in argument 1 (different address spaces) drivers/video/fbdev/chipsfb.c:334:17: expected void * drivers/video/fbdev/chipsfb.c:334:17: got char [noderef] __iomem *screen_base drivers/video/fbdev/chipsfb.c:334:15: warning: memset with byte count of 1048576
Use fb_memset() instead of memset(). fb_memset() is defined as memset_io() for powerpc.
Fixes: 8c8709334cec ("[PATCH] ppc32: Remove CONFIG_PMAC_PBOOK") Reported-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/884a54f1e5cb774c1d9b4db780209bee5d4f6718.163171256... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/video/fbdev/chipsfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c index 998067b701fa0..393894af26f84 100644 --- a/drivers/video/fbdev/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c @@ -331,7 +331,7 @@ static const struct fb_var_screeninfo chipsfb_var = {
static void init_chips(struct fb_info *p, unsigned long addr) { - memset(p->screen_base, 0, 0x100000); + fb_memset(p->screen_base, 0, 0x100000);
p->fix = chipsfb_fix; p->fix.smem_start = addr;
From: Nathan Lynch nathanl@linux.ibm.com
[ Upstream commit 56537faf8821e361d739fc5ff58c9c40f54a1d4c ]
When check_kvm_guest() succeeds in looking up a /hypervisor OF node, it returns without performing a matching put for the lookup, leaving the node's reference count elevated.
Add the necessary call to of_node_put(), rearranging the code slightly to avoid repetition or goto.
Fixes: 107c55005fbd ("powerpc/pseries: Add KVM guest doorbell restrictions") Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Reviewed-by: Srikar Dronamraju srikar@linux.vnet.ibm.com Reviewed-by: Tyrel Datwyler tyreld@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210928124550.132020-1-nathanl@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/kernel/firmware.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c index c7022c41cc314..20328f72f9f2b 100644 --- a/arch/powerpc/kernel/firmware.c +++ b/arch/powerpc/kernel/firmware.c @@ -31,11 +31,10 @@ int __init check_kvm_guest(void) if (!hyper_node) return 0;
- if (!of_device_is_compatible(hyper_node, "linux,kvm")) - return 0; - - static_branch_enable(&kvm_guest); + if (of_device_is_compatible(hyper_node, "linux,kvm")) + static_branch_enable(&kvm_guest);
+ of_node_put(hyper_node); return 0; } core_initcall(check_kvm_guest); // before kvm_guest_init()
From: Nathan Lynch nathanl@linux.ibm.com
[ Upstream commit fda0eb220021a97c1d656434b9340ebf3fc4704a ]
vcpu_is_preempted() can be used outside of preempt-disabled critical sections, yielding warnings such as:
BUG: using smp_processor_id() in preemptible [00000000] code: systemd-udevd/185 caller is rwsem_spin_on_owner+0x1cc/0x2d0 CPU: 1 PID: 185 Comm: systemd-udevd Not tainted 5.15.0-rc2+ #33 Call Trace: [c000000012907ac0] [c000000000aa30a8] dump_stack_lvl+0xac/0x108 (unreliable) [c000000012907b00] [c000000001371f70] check_preemption_disabled+0x150/0x160 [c000000012907b90] [c0000000001e0e8c] rwsem_spin_on_owner+0x1cc/0x2d0 [c000000012907be0] [c0000000001e1408] rwsem_down_write_slowpath+0x478/0x9a0 [c000000012907ca0] [c000000000576cf4] filename_create+0x94/0x1e0 [c000000012907d10] [c00000000057ac08] do_symlinkat+0x68/0x1a0 [c000000012907d70] [c00000000057ae18] sys_symlink+0x58/0x70 [c000000012907da0] [c00000000002e448] system_call_exception+0x198/0x3c0 [c000000012907e10] [c00000000000c54c] system_call_common+0xec/0x250
The result of vcpu_is_preempted() is always used speculatively, and the function does not access per-cpu resources in a (Linux) preempt-unsafe way. Use raw_smp_processor_id() to avoid such warnings, adding explanatory comments.
Fixes: ca3f969dcb11 ("powerpc/paravirt: Use is_kvm_guest() in vcpu_is_preempted()") Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Reviewed-by: Srikar Dronamraju srikar@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210928214147.312412-3-nathanl@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/paravirt.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h index bcb7b5f917be6..b325022ffa2b0 100644 --- a/arch/powerpc/include/asm/paravirt.h +++ b/arch/powerpc/include/asm/paravirt.h @@ -97,7 +97,23 @@ static inline bool vcpu_is_preempted(int cpu)
#ifdef CONFIG_PPC_SPLPAR if (!is_kvm_guest()) { - int first_cpu = cpu_first_thread_sibling(smp_processor_id()); + int first_cpu; + + /* + * The result of vcpu_is_preempted() is used in a + * speculative way, and is always subject to invalidation + * by events internal and external to Linux. While we can + * be called in preemptable context (in the Linux sense), + * we're not accessing per-cpu resources in a way that can + * race destructively with Linux scheduler preemption and + * migration, and callers can tolerate the potential for + * error introduced by sampling the CPU index without + * pinning the task to it. So it is permissible to use + * raw_smp_processor_id() here to defeat the preempt debug + * warnings that can arise from using smp_processor_id() + * in arbitrary contexts. + */ + first_cpu = cpu_first_thread_sibling(raw_smp_processor_id());
/* * Preemption can only happen at core granularity. This CPU
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit ebabb77a2a115b6c5e68f7364b598310b5f61fb2 ]
ACPI_PTR() is more harmful than helpful. For example, in this case if CONFIG_ACPI=n, the ID table left unused which is not what we want.
Instead of adding ifdeffery here and there, drop ACPI_PTR().
Fixes: 6a7320c4669f ("serial: 8250_dw: Add ACPI 5.0 support") Reported-by: Daniel Palmer daniel@0x0f.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20211005134516.23218-1-andriy.shevchenko@linux.int... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_dw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a3a0154da567d..49559731bbcf1 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -726,7 +726,7 @@ static struct platform_driver dw8250_platform_driver = { .name = "dw-apb-uart", .pm = &dw8250_pm_ops, .of_match_table = dw8250_of_match, - .acpi_match_table = ACPI_PTR(dw8250_acpi_match), + .acpi_match_table = dw8250_acpi_match, }, .probe = dw8250_probe, .remove = dw8250_remove,
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 68e7c510fdf4f6167404609da52e1979165649f6 ]
Return an error code if usb_get_function() fails. Don't return success.
Fixes: 4bc8a33f2407 ("usb: gadget: hid: convert to new interface of f_hid") Acked-by: Felipe Balbi balbi@kernel.org Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Link: https://lore.kernel.org/r/20211011123739.GC15188@kili Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/legacy/hid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 5b27d289443fe..3912cc805f3af 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -99,8 +99,10 @@ static int do_config(struct usb_configuration *c)
list_for_each_entry(e, &hidg_func_list, node) { e->f = usb_get_function(e->fi); - if (IS_ERR(e->f)) + if (IS_ERR(e->f)) { + status = PTR_ERR(e->f); goto put; + } status = usb_add_function(c, e->f); if (status < 0) { usb_put_function(e->f);
From: Jakob Hauser jahau@rocketmail.com
[ Upstream commit bf895295e9a73411889816f1a0c1f4f1a2d9c678 ]
Currently the rt5033_battery driver provides voltage values in mV. It should be µV as stated in Documentation/power/power_supply_class.rst.
Fixes: b847dd96e659 ("power: rt5033_battery: Add RT5033 Fuel gauge device driver") Cc: Beomho Seo beomho.seo@samsung.com Cc: Chanwoo Choi cw00.choi@samsung.com Signed-off-by: Jakob Hauser jahau@rocketmail.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/rt5033_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/power/supply/rt5033_battery.c b/drivers/power/supply/rt5033_battery.c index 9ad0afe83d1b7..7a23c70f48791 100644 --- a/drivers/power/supply/rt5033_battery.c +++ b/drivers/power/supply/rt5033_battery.c @@ -60,7 +60,7 @@ static int rt5033_battery_get_watt_prop(struct i2c_client *client, regmap_read(battery->regmap, regh, &msb); regmap_read(battery->regmap, regl, &lsb);
- ret = ((msb << 4) + (lsb >> 4)) * 1250 / 1000; + ret = ((msb << 4) + (lsb >> 4)) * 1250;
return ret; }
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 1d422ecfc48ee683ae1ccc9217764f6310c0ffce ]
Add check the return value of devm_regmap_init_i2c(), otherwise later access may cause null-ptr-deref as follows:
KASAN: null-ptr-deref in range [0x0000000000000360-0x0000000000000367] RIP: 0010:regmap_read+0x33/0x170 Call Trace: max17040_probe+0x61b/0xff0 [max17040_battery] ? write_comp_data+0x2a/0x90 ? max17040_set_property+0x1d0/0x1d0 [max17040_battery] ? tracer_hardirqs_on+0x33/0x520 ? __sanitizer_cov_trace_pc+0x1d/0x50 ? _raw_spin_unlock_irqrestore+0x4b/0x60 ? trace_hardirqs_on+0x63/0x2d0 ? write_comp_data+0x2a/0x90 ? __sanitizer_cov_trace_pc+0x1d/0x50 ? max17040_set_property+0x1d0/0x1d0 [max17040_battery] i2c_device_probe+0xa31/0xbe0
Fixes: 6455a8a84bdf ("power: supply: max17040: Use regmap i2c") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/max17040_battery.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c index 3cea92e28dc3e..a9aef1e8b186e 100644 --- a/drivers/power/supply/max17040_battery.c +++ b/drivers/power/supply/max17040_battery.c @@ -449,6 +449,8 @@ static int max17040_probe(struct i2c_client *client,
chip->client = client; chip->regmap = devm_regmap_init_i2c(client, &max17040_regmap); + if (IS_ERR(chip->regmap)) + return PTR_ERR(chip->regmap); chip_id = (enum chip_id) id->driver_data; if (client->dev.of_node) { ret = max17040_get_of_data(chip);
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit f4875d509a0a78ad294a1a538d534b5ba94e685a ]
This variable is just a temporary variable, used to do an endian conversion. The problem is that the last byte is not initialized. After the conversion is completely done, the last byte is discarded so it doesn't cause a problem. But static checkers and the KMSan runtime checker can detect the uninitialized read and will complain about it.
Link: https://lore.kernel.org/r/20211006073242.GA8404@kili Fixes: 5036f0a0ecd3 ("[SCSI] csiostor: Fix sparse warnings.") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/csiostor/csio_lnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index dc98f51f466fb..d5ac938970232 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -619,7 +619,7 @@ csio_ln_vnp_read_cbfn(struct csio_hw *hw, struct csio_mb *mbp) struct fc_els_csp *csp; struct fc_els_cssp *clsp; enum fw_retval retval; - __be32 nport_id; + __be32 nport_id = 0;
retval = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (retval != FW_SUCCESS) {
From: Leon Romanovsky leonro@nvidia.com
[ Upstream commit f4e56ec4452f48b8292dcf0e1c4bdac83506fb8b ]
The error flow fixed in this patch is not possible because all kernel users of create QP interface check that device supports steering before set IB_QP_CREATE_NETIF_QP flag.
Fixes: c1c98501121e ("IB/mlx4: Add support for steerable IB UD QPs") Link: https://lore.kernel.org/r/91c61f6e60eb0240f8bbc321fda7a1d2986dd03c.163402367... Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/mlx4/qp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 8662f462e2a5f..3a1a4ac9dd33d 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1099,8 +1099,10 @@ static int create_qp_common(struct ib_pd *pd, struct ib_qp_init_attr *init_attr, if (dev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) qp->flags |= MLX4_IB_QP_NETIF; - else + else { + err = -EINVAL; goto err; + } }
err = set_kernel_sq_size(dev, &init_attr->cap, qp_type, qp);
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit fde1fbedbaed4e76cef4600d775b185f59b9b568 ]
The kconfig symbol GENERIC_PHY says: All the users of this framework should select this config. and around 136 out of 138 drivers do so, so change USB_MUSB_MEDIATEK to do so also.
This (also) fixes a long circular dependency problem for an upcoming patch.
Fixes: 0990366bab3c ("usb: musb: Add support for MediaTek musb controller") Cc: Bin Liu b-liu@ti.com Cc: Min Guo min.guo@mediatek.com Cc: Yonglong Wu yonglong.wu@mediatek.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: linux-mediatek@lists.infradead.org Signed-off-by: Randy Dunlap rdunlap@infradead.org Link: https://lore.kernel.org/r/20211005235747.5588-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/musb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 8de143807c1ae..4d61df6a9b5c8 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -120,7 +120,7 @@ config USB_MUSB_MEDIATEK tristate "MediaTek platforms" depends on ARCH_MEDIATEK || COMPILE_TEST depends on NOP_USB_XCEIV - depends on GENERIC_PHY + select GENERIC_PHY select USB_ROLE_SWITCH
comment "MUSB DMA mode"
From: Nikita Yushchenko nikita.yoush@cogentembedded.com
[ Upstream commit 2ab189164056b05474275bb40caa038a37713061 ]
Commit 723de0f9171e ("staging: most: remove device from interface structure") moved registration of driver-provided struct device to the most subsystem.
Dim2 used to register the same struct device to provide a custom device attribute. This causes double-registration of the same struct device.
Fix that by moving the custom attribute to driver's dev_groups. This moves attribute to the platform_device object, which is a better location for platform-specific attributes anyway.
Fixes: 723de0f9171e ("staging: most: remove device from interface structure") Acked-by: Christian Gromm christian.gromm@microchip.com Signed-off-by: Nikita Yushchenko nikita.yoush@cogentembedded.com Link: https://lore.kernel.org/r/20211011061117.21435-1-nikita.yoush@cogentembedded... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/most/dim2/Makefile | 2 +- drivers/staging/most/dim2/dim2.c | 24 ++++++++------- drivers/staging/most/dim2/sysfs.c | 49 ------------------------------ drivers/staging/most/dim2/sysfs.h | 11 ------- 4 files changed, 14 insertions(+), 72 deletions(-) delete mode 100644 drivers/staging/most/dim2/sysfs.c
diff --git a/drivers/staging/most/dim2/Makefile b/drivers/staging/most/dim2/Makefile index 861adacf6c729..5f9612af3fa3c 100644 --- a/drivers/staging/most/dim2/Makefile +++ b/drivers/staging/most/dim2/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_MOST_DIM2) += most_dim2.o
-most_dim2-objs := dim2.o hal.o sysfs.o +most_dim2-objs := dim2.o hal.o diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index 093ef9a2b2919..b72d7b9b45ea9 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -117,7 +117,8 @@ struct dim2_platform_data { (((p)[1] == 0x18) && ((p)[2] == 0x05) && ((p)[3] == 0x0C) && \ ((p)[13] == 0x3C) && ((p)[14] == 0x00) && ((p)[15] == 0x0A))
-bool dim2_sysfs_get_state_cb(void) +static ssize_t state_show(struct device *dev, struct device_attribute *attr, + char *buf) { bool state; unsigned long flags; @@ -126,9 +127,18 @@ bool dim2_sysfs_get_state_cb(void) state = dim_get_lock_state(); spin_unlock_irqrestore(&dim_lock, flags);
- return state; + return sysfs_emit(buf, "%s\n", state ? "locked" : ""); }
+static DEVICE_ATTR_RO(state); + +static struct attribute *dim2_attrs[] = { + &dev_attr_state.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(dim2); + /** * dimcb_on_error - callback from HAL to report miscommunication between * HDM and HAL @@ -866,16 +876,8 @@ static int dim2_probe(struct platform_device *pdev) goto err_stop_thread; }
- ret = dim2_sysfs_probe(&dev->dev); - if (ret) { - dev_err(&pdev->dev, "failed to create sysfs attribute\n"); - goto err_unreg_iface; - } - return 0;
-err_unreg_iface: - most_deregister_interface(&dev->most_iface); err_stop_thread: kthread_stop(dev->netinfo_task); err_shutdown_dim: @@ -898,7 +900,6 @@ static int dim2_remove(struct platform_device *pdev) struct dim2_hdm *dev = platform_get_drvdata(pdev); unsigned long flags;
- dim2_sysfs_destroy(&dev->dev); most_deregister_interface(&dev->most_iface); kthread_stop(dev->netinfo_task);
@@ -1082,6 +1083,7 @@ static struct platform_driver dim2_driver = { .driver = { .name = "hdm_dim2", .of_match_table = dim2_of_match, + .dev_groups = dim2_groups, }, };
diff --git a/drivers/staging/most/dim2/sysfs.c b/drivers/staging/most/dim2/sysfs.c deleted file mode 100644 index c85b2cdcdca3d..0000000000000 --- a/drivers/staging/most/dim2/sysfs.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * sysfs.c - MediaLB sysfs information - * - * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - */ - -/* Author: Andrey Shvetsov andrey.shvetsov@k2l.de */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include "sysfs.h" -#include <linux/device.h> - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - bool state = dim2_sysfs_get_state_cb(); - - return sprintf(buf, "%s\n", state ? "locked" : ""); -} - -static DEVICE_ATTR_RO(state); - -static struct attribute *dev_attrs[] = { - &dev_attr_state.attr, - NULL, -}; - -static struct attribute_group dev_attr_group = { - .attrs = dev_attrs, -}; - -static const struct attribute_group *dev_attr_groups[] = { - &dev_attr_group, - NULL, -}; - -int dim2_sysfs_probe(struct device *dev) -{ - dev->groups = dev_attr_groups; - return device_register(dev); -} - -void dim2_sysfs_destroy(struct device *dev) -{ - device_unregister(dev); -} diff --git a/drivers/staging/most/dim2/sysfs.h b/drivers/staging/most/dim2/sysfs.h index 24277a17cff3d..09115cf4ed00e 100644 --- a/drivers/staging/most/dim2/sysfs.h +++ b/drivers/staging/most/dim2/sysfs.h @@ -16,15 +16,4 @@ struct medialb_bus { struct kobject kobj_group; };
-struct device; - -int dim2_sysfs_probe(struct device *dev); -void dim2_sysfs_destroy(struct device *dev); - -/* - * callback, - * must deliver MediaLB state as true if locked or false if unlocked - */ -bool dim2_sysfs_get_state_cb(void); - #endif /* DIM2_SYSFS_H */
From: Vegard Nossum vegard.nossum@oracle.com
[ Upstream commit 9ca0e55e52c7b2a99f3c2051fc4bd1c63a061519 ]
Fix the following build/link errors:
ld: drivers/staging/ks7010/ks_hostif.o: in function `michael_mic.constprop.0': ks_hostif.c:(.text+0x95b): undefined reference to `crypto_alloc_shash' ld: ks_hostif.c:(.text+0x97a): undefined reference to `crypto_shash_setkey' ld: ks_hostif.c:(.text+0xa13): undefined reference to `crypto_shash_update' ld: ks_hostif.c:(.text+0xa28): undefined reference to `crypto_shash_update' ld: ks_hostif.c:(.text+0xa48): undefined reference to `crypto_shash_finup' ld: ks_hostif.c:(.text+0xa6d): undefined reference to `crypto_destroy_tfm'
Fixes: 8b523f20417d ("staging: ks7010: removed custom Michael MIC implementation.") Fixes: 3e5bc68fa5968 ("staging: ks7010: Fix build error") Fixes: a4961427e7494 ("Revert "staging: ks7010: Fix build error"") Signed-off-by: Vegard Nossum vegard.nossum@oracle.com Link: https://lore.kernel.org/r/20211011152941.12847-1-vegard.nossum@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/ks7010/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/staging/ks7010/Kconfig b/drivers/staging/ks7010/Kconfig index 0987fdc2f70db..8ea6c09286798 100644 --- a/drivers/staging/ks7010/Kconfig +++ b/drivers/staging/ks7010/Kconfig @@ -5,6 +5,9 @@ config KS7010 select WIRELESS_EXT select WEXT_PRIV select FW_LOADER + select CRYPTO + select CRYPTO_HASH + select CRYPTO_MICHAEL_MIC help This is a driver for KeyStream KS7010 based SDIO WIFI cards. It is found on at least later Spectec SDW-821 (FCC-ID "S2Y-WLAN-11G-K" only,
From: Logan Gunthorpe logang@deltatee.com
[ Upstream commit ac0fffa0859b8e1e991939663b3ebdd80bf979e6 ]
ib_dma_map_sgtable_attrs() should be mapping the sgls and setting nents but the ib_uses_virt_dma() path falls back to ib_dma_virt_map_sg() which will not set the nents in the sgtable.
Check the return value (per the map_sg calling convention) and set sgt->nents appropriately on success.
Fixes: 79fbd3e1241c ("RDMA: Use the sg_table directly and remove the opencoded version from umem") Link: https://lore.kernel.org/r/20211013165942.89806-1-logang@deltatee.com Reported-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Logan Gunthorpe logang@deltatee.com Tested-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/rdma/ib_verbs.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 4b50d9a3018a6..4ba642fc8a19a 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -4097,8 +4097,13 @@ static inline int ib_dma_map_sgtable_attrs(struct ib_device *dev, enum dma_data_direction direction, unsigned long dma_attrs) { + int nents; + if (ib_uses_virt_dma(dev)) { - ib_dma_virt_map_sg(dev, sgt->sgl, sgt->orig_nents); + nents = ib_dma_virt_map_sg(dev, sgt->sgl, sgt->orig_nents); + if (!nents) + return -EIO; + sgt->nents = nents; return 0; } return dma_map_sgtable(dev->dma_device, sgt, direction, dma_attrs);
From: Andrew Halaney ahalaney@redhat.com
[ Upstream commit 5ca173974888368fecfb17ae6fe455df5fd2a9d2 ]
Right now dyndbg shows up as an unknown parameter if used on boot:
Unknown command line parameters: dyndbg=+p
That's because it is unknown, it doesn't sit in the __param section, so the processing done to warn users supplying an unknown parameter doesn't think it is legitimate.
Install a dummy handler to register it. dynamic debug needs to search the whole command line for modules listed that are currently builtin, so there's no real work to be done in this callback.
Fixes: 86d1919a4fb0 ("init: print out unknown kernel parameters") Tested-by: Jim Cromie jim.cromie@gmail.com Signed-off-by: Andrew Halaney ahalaney@redhat.com Signed-off-by: Jason Baron jbaron@akamai.com Link: https://lore.kernel.org/r/1634139622-20667-2-git-send-email-jbaron@akamai.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/dynamic_debug.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index cb5abb42c16a2..84c16309cc637 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -761,6 +761,18 @@ static __init int ddebug_setup_query(char *str)
__setup("ddebug_query=", ddebug_setup_query);
+/* + * Install a noop handler to make dyndbg look like a normal kernel cli param. + * This avoids warnings about dyndbg being an unknown cli param when supplied + * by a user. + */ +static __init int dyndbg_setup(char *str) +{ + return 1; +} + +__setup("dyndbg=", dyndbg_setup); + /* * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the * command text from userspace, parses and executes it.
From: Athira Rajeev atrajeev@linux.vnet.ibm.cm
[ Upstream commit 8f6aca0e0f26eaaee670cd27896993a45cdc8f9e ]
On power9 and earlier platforms, the default event used for cyles and instructions is PM_CYC (0x0001e) and PM_INST_CMPL (0x00002) respectively. These events use two programmable PMCs and by default will count irrespective of the run latch state (idle state). But since they use programmable PMCs, these events can lead to multiplexing with other events, because there are only 4 programmable PMCs. Hence in power10, performance monitoring unit (PMU) driver uses performance monitor counter 5 (PMC5) and performance monitor counter6 (PMC6) for counting instructions and cycles.
Currently on power10, the event used for cycles is PM_RUN_CYC (0x600F4) and instructions uses PM_RUN_INST_CMPL (0x500fa). But counting of these events in idle state is controlled by the CC56RUN bit setting in Monitor Mode Control Register0 (MMCR0). If the CC56RUN bit is zero, PMC5/6 will not count when CTRL[RUN] (run latch) is zero. This could lead to missing some counts if a thread is in idle state during system wide profiling.
To fix it, set the CC56RUN bit in MMCR0 for power10, which makes PMC5 and PMC6 count instructions and cycles regardless of the run latch state. Since this change make PMC5/6 count as PM_INST_CMPL/PM_CYC, rename the event code 0x600f4 as PM_CYC instead of PM_RUN_CYC and event code 0x500fa as PM_INST_CMPL instead of PM_RUN_INST_CMPL. The changes are only for PMC5/6 event codes and will not affect the behaviour of PM_RUN_CYC/PM_RUN_INST_CMPL if progammed in other PMC's.
Fixes: a64e697cef23 ("powerpc/perf: power10 Performance Monitoring support") Signed-off-by: Athira Rajeev atrajeev@linux.vnet.ibm.cm Reviewed-by: Madhavan Srinivasan maddy@linux.ibm.com [mpe: Tweak change log wording for style and consistency] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211007075121.28497-1-atrajeev@linux.vnet.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/perf/power10-events-list.h | 8 ++--- arch/powerpc/perf/power10-pmu.c | 44 +++++++++++++++++-------- 2 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/perf/power10-events-list.h b/arch/powerpc/perf/power10-events-list.h index 93be7197d2502..564f14097f07b 100644 --- a/arch/powerpc/perf/power10-events-list.h +++ b/arch/powerpc/perf/power10-events-list.h @@ -9,10 +9,10 @@ /* * Power10 event codes. */ -EVENT(PM_RUN_CYC, 0x600f4); +EVENT(PM_CYC, 0x600f4); EVENT(PM_DISP_STALL_CYC, 0x100f8); EVENT(PM_EXEC_STALL, 0x30008); -EVENT(PM_RUN_INST_CMPL, 0x500fa); +EVENT(PM_INST_CMPL, 0x500fa); EVENT(PM_BR_CMPL, 0x4d05e); EVENT(PM_BR_MPRED_CMPL, 0x400f6); EVENT(PM_BR_FIN, 0x2f04a); @@ -50,8 +50,8 @@ EVENT(PM_DTLB_MISS, 0x300fc); /* ITLB Reloaded */ EVENT(PM_ITLB_MISS, 0x400fc);
-EVENT(PM_RUN_CYC_ALT, 0x0001e); -EVENT(PM_RUN_INST_CMPL_ALT, 0x00002); +EVENT(PM_CYC_ALT, 0x0001e); +EVENT(PM_INST_CMPL_ALT, 0x00002);
/* * Memory Access Events diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c index f9d64c63bb4a7..9dd75f3858372 100644 --- a/arch/powerpc/perf/power10-pmu.c +++ b/arch/powerpc/perf/power10-pmu.c @@ -91,8 +91,8 @@ extern u64 PERF_REG_EXTENDED_MASK;
/* Table of alternatives, sorted by column 0 */ static const unsigned int power10_event_alternatives[][MAX_ALT] = { - { PM_RUN_CYC_ALT, PM_RUN_CYC }, - { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL }, + { PM_CYC_ALT, PM_CYC }, + { PM_INST_CMPL_ALT, PM_INST_CMPL }, };
static int power10_get_alternatives(u64 event, unsigned int flags, u64 alt[]) @@ -118,8 +118,8 @@ static int power10_check_attr_config(struct perf_event *ev) return 0; }
-GENERIC_EVENT_ATTR(cpu-cycles, PM_RUN_CYC); -GENERIC_EVENT_ATTR(instructions, PM_RUN_INST_CMPL); +GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); +GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); GENERIC_EVENT_ATTR(branch-instructions, PM_BR_CMPL); GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL); GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); @@ -148,8 +148,8 @@ CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS);
static struct attribute *power10_events_attr_dd1[] = { - GENERIC_EVENT_PTR(PM_RUN_CYC), - GENERIC_EVENT_PTR(PM_RUN_INST_CMPL), + GENERIC_EVENT_PTR(PM_CYC), + GENERIC_EVENT_PTR(PM_INST_CMPL), GENERIC_EVENT_PTR(PM_BR_CMPL), GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL), GENERIC_EVENT_PTR(PM_LD_REF_L1), @@ -173,8 +173,8 @@ static struct attribute *power10_events_attr_dd1[] = { };
static struct attribute *power10_events_attr[] = { - GENERIC_EVENT_PTR(PM_RUN_CYC), - GENERIC_EVENT_PTR(PM_RUN_INST_CMPL), + GENERIC_EVENT_PTR(PM_CYC), + GENERIC_EVENT_PTR(PM_INST_CMPL), GENERIC_EVENT_PTR(PM_BR_FIN), GENERIC_EVENT_PTR(PM_MPRED_BR_FIN), GENERIC_EVENT_PTR(PM_LD_REF_L1), @@ -271,8 +271,8 @@ static const struct attribute_group *power10_pmu_attr_groups[] = { };
static int power10_generic_events_dd1[] = { - [PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC, - [PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL, + [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, + [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_CMPL, [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED_CMPL, [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, @@ -280,8 +280,8 @@ static int power10_generic_events_dd1[] = { };
static int power10_generic_events[] = { - [PERF_COUNT_HW_CPU_CYCLES] = PM_RUN_CYC, - [PERF_COUNT_HW_INSTRUCTIONS] = PM_RUN_INST_CMPL, + [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, + [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BR_FIN, [PERF_COUNT_HW_BRANCH_MISSES] = PM_MPRED_BR_FIN, [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, @@ -548,6 +548,24 @@ static u64 power10_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
#undef C
+/* + * Set the MMCR0[CC56RUN] bit to enable counting for + * PMC5 and PMC6 regardless of the state of CTRL[RUN], + * so that we can use counters 5 and 6 as PM_INST_CMPL and + * PM_CYC. + */ +static int power10_compute_mmcr(u64 event[], int n_ev, + unsigned int hwc[], struct mmcr_regs *mmcr, + struct perf_event *pevents[], u32 flags) +{ + int ret; + + ret = isa207_compute_mmcr(event, n_ev, hwc, mmcr, pevents, flags); + if (!ret) + mmcr->mmcr0 |= MMCR0_C56RUN; + return ret; +} + static struct power_pmu power10_pmu = { .name = "POWER10", .n_counter = MAX_PMU_COUNTERS, @@ -555,7 +573,7 @@ static struct power_pmu power10_pmu = { .test_adder = ISA207_TEST_ADDER, .group_constraint_mask = CNST_CACHE_PMC4_MASK, .group_constraint_val = CNST_CACHE_PMC4_VAL, - .compute_mmcr = isa207_compute_mmcr, + .compute_mmcr = power10_compute_mmcr, .config_bhrb = power10_config_bhrb, .bhrb_filter_map = power10_bhrb_filter_map, .get_constraint = isa207_get_constraint,
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 28e7f8ff90583791a034d43b5d2e3fe394142e13 ]
The GENMASK(h, l) macro creates a contiguous bitmask starting at bit position @l and ending at position @h, inclusive.
This did not trigger any error checks, as the individual register fields cover at most 3 of the 4 available bits.
Fixes: 08df16e07ad0a1ec ("pinctrl: sh-pfc: checker: Add drive strength register checks") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/8f82d6147fbe3367d4c83962480e97f58d9c96a2.163361565... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index f2ab02225837e..f29130957e49a 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -890,7 +890,7 @@ static void __init sh_pfc_check_drive_reg(const struct sh_pfc_soc_info *info, if (!field->pin && !field->offset && !field->size) continue;
- mask = GENMASK(field->offset + field->size, field->offset); + mask = GENMASK(field->offset + field->size - 1, field->offset); if (mask & seen) sh_pfc_err("drive_reg 0x%x: field %u overlap\n", drive->reg, i);
From: Marek Vasut marex@denx.de
[ Upstream commit 2012579b31293d0a8cf2024e9dab66810bf1a15e ]
The SPI NOR is a bit further away from the SoC on DHCOR than on DHCOM, which causes additional signal delay. At 108 MHz, this delay triggers a sporadic issue where the first bit of RX data is not received by the QSPI controller.
There are two options of addressing this problem, either by using the DLYB block to compensate the extra delay, or by reducing the QSPI bus clock frequency. The former requires calibration and that is overly complex, so opt for the second option.
Fixes: 76045bc457104 ("ARM: dts: stm32: Add QSPI NOR on AV96") Signed-off-by: Marek Vasut marex@denx.de Cc: Alexandre Torgue alexandre.torgue@foss.st.com Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: linux-stm32@st-md-mailman.stormreply.com To: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi index 2b0ac605549d7..44ecc47085871 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi @@ -202,7 +202,7 @@ compatible = "jedec,spi-nor"; reg = <0>; spi-rx-bus-width = <4>; - spi-max-frequency = <108000000>; + spi-max-frequency = <50000000>; #address-cells = <1>; #size-cells = <1>; };
From: Fabrice Gasnier fabrice.gasnier@foss.st.com
[ Upstream commit 3d4fb3d4c431f45272bf8c308d3cbe030817f046 ]
STUSB1600 IRQ (Alert pin) is active low (open drain). Interrupts may get lost currently, so fix the IRQ type.
Fixes: 83686162c0eb ("ARM: dts: stm32: add STUSB1600 Type-C using I2C4 on stm32mp15xx-dkx")
Signed-off-by: Fabrice Gasnier fabrice.gasnier@foss.st.com Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15xx-dkx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi index 899bfe04aeb91..48beed0f1f30a 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi @@ -249,7 +249,7 @@ stusb1600@28 { compatible = "st,stusb1600"; reg = <0x28>; - interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpioi>; pinctrl-names = "default"; pinctrl-0 = <&stusb1600_pins_a>;
From: Olivier Moysan olivier.moysan@foss.st.com
[ Upstream commit 6f87a74d31277f0896dcf8c0850ec14bde03c423 ]
The STM32 SAI subblocks registers offsets are in the range 0x0004 (SAIx_CR1) to 0x0020 (SAIx_DR). The corresponding range length is 0x20 instead of 0x1c. Change reg property accordingly.
Fixes: 5afd65c3a060 ("ARM: dts: stm32: add sai support on stm32mp157c")
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp151.dtsi | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index bd289bf5d2690..6992a4b0ba79b 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -824,7 +824,7 @@ #sound-dai-cells = <0>;
compatible = "st,stm32-sai-sub-a"; - reg = <0x4 0x1c>; + reg = <0x4 0x20>; clocks = <&rcc SAI1_K>; clock-names = "sai_ck"; dmas = <&dmamux1 87 0x400 0x01>; @@ -834,7 +834,7 @@ sai1b: audio-controller@4400a024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI1_K>; clock-names = "sai_ck"; dmas = <&dmamux1 88 0x400 0x01>; @@ -855,7 +855,7 @@ sai2a: audio-controller@4400b004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x4 0x1c>; + reg = <0x4 0x20>; clocks = <&rcc SAI2_K>; clock-names = "sai_ck"; dmas = <&dmamux1 89 0x400 0x01>; @@ -865,7 +865,7 @@ sai2b: audio-controller@4400b024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI2_K>; clock-names = "sai_ck"; dmas = <&dmamux1 90 0x400 0x01>; @@ -886,7 +886,7 @@ sai3a: audio-controller@4400c004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x04 0x1c>; + reg = <0x04 0x20>; clocks = <&rcc SAI3_K>; clock-names = "sai_ck"; dmas = <&dmamux1 113 0x400 0x01>; @@ -896,7 +896,7 @@ sai3b: audio-controller@4400c024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI3_K>; clock-names = "sai_ck"; dmas = <&dmamux1 114 0x400 0x01>; @@ -1271,7 +1271,7 @@ sai4a: audio-controller@50027004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x04 0x1c>; + reg = <0x04 0x20>; clocks = <&rcc SAI4_K>; clock-names = "sai_ck"; dmas = <&dmamux1 99 0x400 0x01>; @@ -1281,7 +1281,7 @@ sai4b: audio-controller@50027024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI4_K>; clock-names = "sai_ck"; dmas = <&dmamux1 100 0x400 0x01>;
From: Olivier Moysan olivier.moysan@foss.st.com
[ Upstream commit 1a9a9d226f0f0ef5d9bf588ab432e0d679bb1954 ]
Fix SAI2A and SAI2B pin muxings for AV96 board on STM32MP15. Change sai2a-4 & sai2a-5 to sai2a-2 & sai2a-2. Change sai2a-4 & sai2a-sleep-5 to sai2b-2 & sai2b-sleep-2
Fixes: dcf185ca8175 ("ARM: dts: stm32: Add alternate pinmux for SAI2 pins on stm32mp15")
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com Reviewed-by: Marek Vasut marex@denx.de Signed-off-by: Alexandre Torgue alexandre.torgue@foss.st.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi index 5b60ecbd718f0..2ebafe27a865b 100644 --- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi @@ -1179,7 +1179,7 @@ }; };
- sai2a_pins_c: sai2a-4 { + sai2a_pins_c: sai2a-2 { pins { pinmux = <STM32_PINMUX('D', 13, AF10)>, /* SAI2_SCK_A */ <STM32_PINMUX('D', 11, AF10)>, /* SAI2_SD_A */ @@ -1190,7 +1190,7 @@ }; };
- sai2a_sleep_pins_c: sai2a-5 { + sai2a_sleep_pins_c: sai2a-2 { pins { pinmux = <STM32_PINMUX('D', 13, ANALOG)>, /* SAI2_SCK_A */ <STM32_PINMUX('D', 11, ANALOG)>, /* SAI2_SD_A */ @@ -1235,14 +1235,14 @@ }; };
- sai2b_pins_c: sai2a-4 { + sai2b_pins_c: sai2b-2 { pins1 { pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */ bias-disable; }; };
- sai2b_sleep_pins_c: sai2a-sleep-5 { + sai2b_sleep_pins_c: sai2b-sleep-2 { pins { pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */ };
From: Richard Fitzgerald rf@opensource.cirrus.com
[ Upstream commit 6e6825801ab926360f7f4f2dbcfd107d5ab8f025 ]
An I2S frame always has two slots (left and right) even when sending mono. The right channel (channel 2) of ASP TX will always have the same bit width as the left channel and will always be on the high phase of LRCLK.
The previous implementation always passed the field masks for both channels to snd_soc_component_update_bits() but for mono the written value only contained the settings for channel 1. The result was that for mono channel 2 was set to 8-bit (which is an invalid configuration) with both channels on the low phase of LRCLK.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com Fixes: 585e7079de0e ("ASoC: cs42l42: Add Capture Support") Link: https://lore.kernel.org/r/20211015133619.4698-3-rf@opensource.cirrus.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/cs42l42.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 9a463ab54bddc..4548dae7ed834 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -853,11 +853,10 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream,
switch(substream->stream) { case SNDRV_PCM_STREAM_CAPTURE: - if (channels == 2) { - val |= CS42L42_ASP_TX_CH2_AP_MASK; - val |= width << CS42L42_ASP_TX_CH2_RES_SHIFT; - } - val |= width << CS42L42_ASP_TX_CH1_RES_SHIFT; + /* channel 2 on high LRCLK */ + val = CS42L42_ASP_TX_CH2_AP_MASK | + (width << CS42L42_ASP_TX_CH2_RES_SHIFT) | + (width << CS42L42_ASP_TX_CH1_RES_SHIFT);
snd_soc_component_update_bits(component, CS42L42_ASP_TX_CH_AP_RES, CS42L42_ASP_TX_CH1_AP_MASK | CS42L42_ASP_TX_CH2_AP_MASK |
From: Richard Fitzgerald rf@opensource.cirrus.com
[ Upstream commit d591d4b32aa9552af14a0c7c586a2d3fe9ecc6e0 ]
Some registers had wrong default values in cs42l42_reg_defaults[].
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec") Link: https://lore.kernel.org/r/20211015133619.4698-4-rf@opensource.cirrus.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/cs42l42.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 4548dae7ed834..205f81d27c30f 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -93,7 +93,7 @@ static const struct reg_default cs42l42_reg_defaults[] = { { CS42L42_ASP_RX_INT_MASK, 0x1F }, { CS42L42_ASP_TX_INT_MASK, 0x0F }, { CS42L42_CODEC_INT_MASK, 0x03 }, - { CS42L42_SRCPL_INT_MASK, 0xFF }, + { CS42L42_SRCPL_INT_MASK, 0x7F }, { CS42L42_VPMON_INT_MASK, 0x01 }, { CS42L42_PLL_LOCK_INT_MASK, 0x01 }, { CS42L42_TSRS_PLUG_INT_MASK, 0x0F }, @@ -130,7 +130,7 @@ static const struct reg_default cs42l42_reg_defaults[] = { { CS42L42_MIXER_CHA_VOL, 0x3F }, { CS42L42_MIXER_ADC_VOL, 0x3F }, { CS42L42_MIXER_CHB_VOL, 0x3F }, - { CS42L42_EQ_COEF_IN0, 0x22 }, + { CS42L42_EQ_COEF_IN0, 0x00 }, { CS42L42_EQ_COEF_IN1, 0x00 }, { CS42L42_EQ_COEF_IN2, 0x00 }, { CS42L42_EQ_COEF_IN3, 0x00 },
From: Richard Fitzgerald rf@opensource.cirrus.com
[ Upstream commit 0306988789d9d91a18ff70bd2bf165d3ae0ef1dd ]
The driver can run without an interrupt so if devm_request_threaded_irq() failed, the probe() just carried on. But if this was EPROBE_DEFER the driver would continue without an interrupt instead of deferring to wait for the interrupt to become available.
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec") Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com Link: https://lore.kernel.org/r/20211015133619.4698-6-rf@opensource.cirrus.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/cs42l42.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 205f81d27c30f..6034e439d3132 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1947,8 +1947,9 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client, NULL, cs42l42_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW, "cs42l42", cs42l42); - - if (ret != 0) + if (ret == -EPROBE_DEFER) + goto err_disable; + else if (ret != 0) dev_err(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);
From: Bjorn Andersson bjorn.andersson@linaro.org
[ Upstream commit e3e56c050ab6e3f1bd811f0787f50709017543e4 ]
The general expectation is that powering on a power-domain should make the power domain deliver some power, and if a specific performance state is needed further requests has to be made.
But in contrast with other power-domain implementations (e.g. rpmpd) the RPMh does not have an interface to enable the power, so the driver has to vote for a particular corner (performance level) in rpmh_power_on().
But the corner is never initialized, so a typical request to simply enable the power domain would not actually turn on the hardware. Further more, when no more clients vote for a performance state (i.e. the aggregated vote is 0) the power domain would be turned off.
Fix both of these issues by always voting for a corner with non-zero value, when the power domain is enabled.
The tracking of the lowest non-zero corner is performed to handle the corner case if there's ever a domain with a non-zero lowest corner, in which case both rpmh_power_on() and rpmh_rpmhpd_set_performance_state() would be allowed to use this lowest corner.
Fixes: 279b7e8a62cc ("soc: qcom: rpmhpd: Add RPMh power domain driver") Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Reviewed-by: Stephen Boyd swboyd@chromium.org Link: https://lore.kernel.org/r/20211005033732.2284447-1-bjorn.andersson@linaro.or... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/rpmhpd.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index fa209b479ab35..a46735cec3f0f 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -30,6 +30,7 @@ * @active_only: True if it represents an Active only peer * @corner: current corner * @active_corner: current active corner + * @enable_corner: lowest non-zero corner * @level: An array of level (vlvl) to corner (hlvl) mappings * derived from cmd-db * @level_count: Number of levels supported by the power domain. max @@ -47,6 +48,7 @@ struct rpmhpd { const bool active_only; unsigned int corner; unsigned int active_corner; + unsigned int enable_corner; u32 level[RPMH_ARC_MAX_LEVELS]; size_t level_count; bool enabled; @@ -385,13 +387,13 @@ static int rpmhpd_aggregate_corner(struct rpmhpd *pd, unsigned int corner) static int rpmhpd_power_on(struct generic_pm_domain *domain) { struct rpmhpd *pd = domain_to_rpmhpd(domain); - int ret = 0; + unsigned int corner; + int ret;
mutex_lock(&rpmhpd_lock);
- if (pd->corner) - ret = rpmhpd_aggregate_corner(pd, pd->corner); - + corner = max(pd->corner, pd->enable_corner); + ret = rpmhpd_aggregate_corner(pd, corner); if (!ret) pd->enabled = true;
@@ -436,6 +438,10 @@ static int rpmhpd_set_performance_state(struct generic_pm_domain *domain, i--;
if (pd->enabled) { + /* Ensure that the domain isn't turn off */ + if (i < pd->enable_corner) + i = pd->enable_corner; + ret = rpmhpd_aggregate_corner(pd, i); if (ret) goto out; @@ -472,6 +478,10 @@ static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd) for (i = 0; i < rpmhpd->level_count; i++) { rpmhpd->level[i] = buf[i];
+ /* Remember the first corner with non-zero level */ + if (!rpmhpd->level[rpmhpd->enable_corner] && rpmhpd->level[i]) + rpmhpd->enable_corner = i; + /* * The AUX data may be zero padded. These 0 valued entries at * the end of the map must be ignored.
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 2fae3ecc70405b72ea6c923b216d34547559d6a9 ]
Add IDs for PMK8001 and PMI8996. They also fall in the list of 'duplicated' IDs, where the same index was used for multiple chips.
Fixes: 7fda2b0bfbd9 ("soc: qcom: socinfo: import PMIC IDs from pmic-spmi") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211016190607.49866-1-dmitry.baryshkov@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/socinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 52e5811671155..5beb452f24013 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -87,8 +87,8 @@ static const char *const pmic_models[] = { [15] = "PM8901", [16] = "PM8950/PM8027", [17] = "PMI8950/ISL9519", - [18] = "PM8921", - [19] = "PM8018", + [18] = "PMK8001/PM8921", + [19] = "PMI8996/PM8018", [20] = "PM8998/PM8015", [21] = "PMI8998/PM8014", [22] = "PM8821",
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit 09776d9374e635b1580b3736c19b95b788fbaa85 ]
When __iio_buffer_alloc_sysfs_and_mask() failed, 'unwind_idx' should be set to 'i - 1' to prevent double-free when cleanup resources.
BUG: KASAN: double-free or invalid-free in __iio_buffer_free_sysfs_and_mask+0x32/0xb0 [industrialio] Call Trace: kfree+0x117/0x4c0 __iio_buffer_free_sysfs_and_mask+0x32/0xb0 [industrialio] iio_buffers_alloc_sysfs_and_mask+0x60d/0x1570 [industrialio] __iio_device_register+0x483/0x1a30 [industrialio] ina2xx_probe+0x625/0x980 [ina2xx_adc]
Reported-by: Hulk Robot hulkci@huawei.com Fixes: ee708e6baacd ("iio: buffer: introduce support for attaching more IIO buffers") Signed-off-by: Yang Yingliang yangyingliang@huawei.com Reviewed-by: Alexandru Ardelean ardeleanalex@gmail.com Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20211013094923.2473-2-andriy.shevchenko@linux.inte... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/industrialio-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 7f4e3ceaafec6..2f98ba70e3d78 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1624,7 +1624,7 @@ int iio_buffers_alloc_sysfs_and_mask(struct iio_dev *indio_dev) buffer = iio_dev_opaque->attached_buffers[i]; ret = __iio_buffer_alloc_sysfs_and_mask(buffer, indio_dev, i); if (ret) { - unwind_idx = i; + unwind_idx = i - 1; goto error_unwind_sysfs_and_mask; } }
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 8ef1e58783b9f55daa4a865c7801dc75cbeb8260 ]
REGMAP_I2C is not a user visible kconfig symbol so driver configs should not "depend on" it. They should depend on I2C and then select REGMAP_I2C.
If this worked, it was only because some other driver had set/enabled REGMAP_I2C.
Fixes: da0cb6310094 ("usb: typec: add support for STUSB160x Type-C controller family") Cc: Heikki Krogerus heikki.krogerus@linux.intel.com Cc: Amelie Delaunay amelie.delaunay@st.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: linux-usb@vger.kernel.org Reviewed-by: Amelie Delaunay amelie.delaunay@foss.st.com Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Signed-off-by: Randy Dunlap rdunlap@infradead.org Link: https://lore.kernel.org/r/20211015013609.7300-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index a0418f23b4aae..ab480f38523aa 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -65,9 +65,9 @@ config TYPEC_HD3SS3220
config TYPEC_STUSB160X tristate "STMicroelectronics STUSB160x Type-C controller driver" - depends on I2C - depends on REGMAP_I2C depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH + depends on I2C + select REGMAP_I2C help Say Y or M here if your system has STMicroelectronics STUSB160x Type-C port controller.
From: Nuno Sá nuno.sa@analog.com
[ Upstream commit b600bd7eb333554518b4dd36b882b2ae58a5149e ]
With commit ecb010d441088 ("iio: imu: adis: Refactor adis_initial_startup") we are doing a HW or SW reset to the device which means that we'll get the default state of the data ready pin (which is enabled). Hence there's no point in disabling the IRQ in the init function. Moreover, this function is intended to initialize internal data structures and not really do anything on the device.
As a result of this, some devices were left with the data ready pin enabled after probe which was not the desired behavior. Thus, we move the call to 'adis_enable_irq()' to the initial startup function where it makes more sense for it to be.
Note that for devices that cannot mask/unmask the pin, it makes no sense to call the function at this point since the IRQ should not have been yet requested. This will be improved in a follow up change.
Fixes: ecb010d441088 ("iio: imu: adis: Refactor adis_initial_startup") Signed-off-by: Nuno Sá nuno.sa@analog.com Link: https://lore.kernel.org/r/20210903141423.517028-2-nuno.sa@analog.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/imu/adis.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index b9a06ca29beec..d4e692b187cda 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -430,6 +430,8 @@ int __adis_initial_startup(struct adis *adis) if (ret) return ret;
+ adis_enable_irq(adis, false); + if (!adis->data->prod_id_reg) return 0;
@@ -526,7 +528,7 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, adis->current_page = 0; }
- return adis_enable_irq(adis, false); + return 0; } EXPORT_SYMBOL_GPL(adis_init);
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
[ Upstream commit 4cbbe74d906be0bcffbe1e74b43a00f99626a69c ]
Slave pointer is invalid after end of list iteration, using this would result in below Memory abort.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000004 ... Call trace: __dev_printk+0x34/0x7c _dev_warn+0x6c/0x90 sdw_bus_exit_clk_stop+0x194/0x1d0 swrm_runtime_resume+0x13c/0x238 pm_generic_runtime_resume+0x2c/0x48 __rpm_callback+0x44/0x150 rpm_callback+0x6c/0x78 rpm_resume+0x314/0x558 rpm_resume+0x378/0x558 rpm_resume+0x378/0x558 __pm_runtime_resume+0x3c/0x88
Use bus->dev instead to print this error message.
Fixes: b50bb8ba369cd ("soundwire: bus: handle -ENODATA errors in clock stop/start sequences") Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Link: https://lore.kernel.org/r/20211012101521.32087-1-srinivas.kandagatla@linaro.... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soundwire/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 1b115734a8f6b..67369e941d0d6 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -1110,7 +1110,7 @@ int sdw_bus_exit_clk_stop(struct sdw_bus *bus) if (!simple_clk_stop) { ret = sdw_bus_wait_for_clk_prep_deprep(bus, SDW_BROADCAST_DEV_NUM); if (ret < 0) - dev_warn(&slave->dev, "clock stop deprepare wait failed:%d\n", ret); + dev_warn(bus->dev, "clock stop deprepare wait failed:%d\n", ret); }
list_for_each_entry(slave, &bus->slaves, node) {
From: Srinivas Kandagatla srinivas.kandagatla@linaro.org
[ Upstream commit b6ca770ae7f2c560a29bbd02c4e3d734fafaf804 ]
UFS drivers that probe defer will end up leaking memory allocated for clk and regulator names via kstrdup() because the structure that is holding this memory is allocated via devm_* variants which will be freed during probe defer but the names are never freed.
Use same devm_* variant of kstrdup to free the memory allocated to name when driver probe defers.
Kmemleak found around 11 leaks on Qualcomm Dragon Board RB5:
unreferenced object 0xffff66f243fb2c00 (size 128): comm "kworker/u16:0", pid 7, jiffies 4294893319 (age 94.848s) hex dump (first 32 bytes): 63 6f 72 65 5f 63 6c 6b 00 76 69 72 74 75 61 6c core_clk.virtual 2f 77 6f 72 6b 71 75 65 75 65 2f 73 63 73 69 5f /workqueue/scsi_ backtrace: [<000000006f788cd1>] slab_post_alloc_hook+0x88/0x410 [<00000000cfd1372b>] __kmalloc_track_caller+0x138/0x230 [<00000000a92ab17b>] kstrdup+0xb0/0x110 [<0000000037263ab6>] ufshcd_pltfrm_init+0x1a8/0x500 [<00000000a20a5caa>] ufs_qcom_probe+0x20/0x58 [<00000000a5e43067>] platform_probe+0x6c/0x118 [<00000000ef686e3f>] really_probe+0xc4/0x330 [<000000005b18792c>] __driver_probe_device+0x88/0x118 [<00000000a5d295e8>] driver_probe_device+0x44/0x158 [<000000007e83f58d>] __device_attach_driver+0xb4/0x128 [<000000004bfa4470>] bus_for_each_drv+0x68/0xd0 [<00000000b89a83bc>] __device_attach+0xec/0x170 [<00000000ada2beea>] device_initial_probe+0x14/0x20 [<0000000079921612>] bus_probe_device+0x9c/0xa8 [<00000000d268bf7c>] deferred_probe_work_func+0x90/0xd0 [<000000009ef64bfa>] process_one_work+0x29c/0x788 unreferenced object 0xffff66f243fb2c80 (size 128): comm "kworker/u16:0", pid 7, jiffies 4294893319 (age 94.848s) hex dump (first 32 bytes): 62 75 73 5f 61 67 67 72 5f 63 6c 6b 00 00 00 00 bus_aggr_clk.... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
With this patch no memory leaks are reported.
Link: https://lore.kernel.org/r/20210914092214.6468-1-srinivas.kandagatla@linaro.o... Fixes: aa4976130934 ("ufs: Add regulator enable support") Fixes: c6e79dacd86f ("ufs: Add clock initialization support") Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Srinivas Kandagatla srinivas.kandagatla@linaro.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshcd-pltfrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 8859c13f4e091..eaeae83b999fd 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -91,7 +91,7 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
clki->min_freq = clkfreq[i]; clki->max_freq = clkfreq[i+1]; - clki->name = kstrdup(name, GFP_KERNEL); + clki->name = devm_kstrdup(dev, name, GFP_KERNEL); if (!strcmp(name, "ref_clk")) clki->keep_link_active = true; dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz", @@ -126,7 +126,7 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, if (!vreg) return -ENOMEM;
- vreg->name = kstrdup(name, GFP_KERNEL); + vreg->name = devm_kstrdup(dev, name, GFP_KERNEL);
snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name); if (of_property_read_u32(np, prop_name, &vreg->max_uA)) {
From: James Smart jsmart2021@gmail.com
[ Upstream commit d305c253af693e69a36cedec880aca6d0c6d789d ]
A prior patch introduced HBA_NEEDS_CFG_PORT flag logic, but in lpfc_sli_brdrestart_s3() code path, right after HBA_NEEDS_CFG_PORT is set, the phba->hba_flag is cleared in lpfc_sli_brdreset().
Fix by calling lpfc_sli_chipset_init() to wait for successful restart of the HBA in lpfc_host_reset_handler() after lpfc_sli_brdrestart().
lpfc_sli_chipset_init() sets the HBA_NEEDS_CFG_PORT flag so that the lpfc_sli_hba_setup() routine from lpfc_online() will execute lpfc_sli_config_port() initialization step when the brdrestart is successful.
Link: https://lore.kernel.org/r/20211020211417.88754-3-jsmart2021@gmail.com Fixes: d2f2547efd39 ("scsi: lpfc: Fix auto sli_mode and its effect on CONFIG_PORT for SLI3") Co-developed-by: Justin Tee justin.tee@broadcom.com Signed-off-by: Justin Tee justin.tee@broadcom.com Signed-off-by: James Smart jsmart2021@gmail.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/lpfc/lpfc_scsi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index befdf864c43bd..364c8a9b99095 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -6628,6 +6628,13 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd) if (rc) goto error;
+ /* Wait for successful restart of adapter */ + if (phba->sli_rev < LPFC_SLI_REV4) { + rc = lpfc_sli_chipset_init(phba); + if (rc) + goto error; + } + rc = lpfc_online(phba); if (rc) goto error;
From: Stefan Agner stefan@agner.ch
[ Upstream commit 6d0d1b5a1b4870911beb89544ec1a9751c42fec7 ]
If the device used as a serial console gets detached/attached at runtime, register_console() will try to call imx_uart_setup_console(), but this is not possible since it is marked as __init.
For instance
# cat /sys/devices/virtual/tty/console/active tty1 ttymxc0 # echo -n N > /sys/devices/virtual/tty/console/subsystem/ttymxc0/console # echo -n Y > /sys/devices/virtual/tty/console/subsystem/ttymxc0/console
[ 73.166649] 8<--- cut here --- [ 73.167005] Unable to handle kernel paging request at virtual address c154d928 [ 73.167601] pgd = 55433e84 [ 73.167875] [c154d928] *pgd=8141941e(bad) [ 73.168304] Internal error: Oops: 8000000d [#1] SMP ARM [ 73.168429] Modules linked in: [ 73.168522] CPU: 0 PID: 536 Comm: sh Not tainted 5.15.0-rc6-00056-g3968ddcf05fb #3 [ 73.168675] Hardware name: Freescale i.MX6 Ultralite (Device Tree) [ 73.168791] PC is at imx_uart_console_setup+0x0/0x238 [ 73.168927] LR is at try_enable_new_console+0x98/0x124 [ 73.169056] pc : [<c154d928>] lr : [<c0196f44>] psr: a0000013 [ 73.169178] sp : c2ef5e70 ip : 00000000 fp : 00000000 [ 73.169281] r10: 00000000 r9 : c02cf970 r8 : 00000000 [ 73.169389] r7 : 00000001 r6 : 00000001 r5 : c1760164 r4 : c1e0fb08 [ 73.169512] r3 : c154d928 r2 : 00000000 r1 : efffcbd1 r0 : c1760164 [ 73.169641] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 73.169782] Control: 10c5387d Table: 8345406a DAC: 00000051 [ 73.169895] Register r0 information: non-slab/vmalloc memory [ 73.170032] Register r1 information: non-slab/vmalloc memory [ 73.170158] Register r2 information: NULL pointer [ 73.170273] Register r3 information: non-slab/vmalloc memory [ 73.170397] Register r4 information: non-slab/vmalloc memory [ 73.170521] Register r5 information: non-slab/vmalloc memory [ 73.170647] Register r6 information: non-paged memory [ 73.170771] Register r7 information: non-paged memory [ 73.170892] Register r8 information: NULL pointer [ 73.171009] Register r9 information: non-slab/vmalloc memory [ 73.171142] Register r10 information: NULL pointer [ 73.171259] Register r11 information: NULL pointer [ 73.171375] Register r12 information: NULL pointer [ 73.171494] Process sh (pid: 536, stack limit = 0xcd1ba82f) [ 73.171621] Stack: (0xc2ef5e70 to 0xc2ef6000) [ 73.171731] 5e60: ???????? ???????? ???????? ???????? [ 73.171899] 5e80: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.172059] 5ea0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.172217] 5ec0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.172377] 5ee0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.172537] 5f00: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.172698] 5f20: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.172856] 5f40: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.173016] 5f60: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.173177] 5f80: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.173336] 5fa0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.173496] 5fc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.173654] 5fe0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.173826] [<c0196f44>] (try_enable_new_console) from [<c01984a8>] (register_console+0x10c/0x2ec) [ 73.174053] [<c01984a8>] (register_console) from [<c06e2c90>] (console_store+0x14c/0x168) [ 73.174262] [<c06e2c90>] (console_store) from [<c0383718>] (kernfs_fop_write_iter+0x110/0x1cc) [ 73.174470] [<c0383718>] (kernfs_fop_write_iter) from [<c02cf5f4>] (vfs_write+0x31c/0x548) [ 73.174679] [<c02cf5f4>] (vfs_write) from [<c02cf970>] (ksys_write+0x60/0xec) [ 73.174863] [<c02cf970>] (ksys_write) from [<c0100080>] (ret_fast_syscall+0x0/0x1c) [ 73.175052] Exception stack(0xc2ef5fa8 to 0xc2ef5ff0) [ 73.175167] 5fa0: ???????? ???????? ???????? ???????? ???????? ???????? [ 73.175327] 5fc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ???????? [ 73.175486] 5fe0: ???????? ???????? ???????? ???????? [ 73.175608] Code: 00000000 00000000 00000000 00000000 (00000000) [ 73.175744] ---[ end trace 9b75121265109bf1 ]---
A similar issue could be triggered by unbinding/binding the serial console device [*].
Drop __init so that imx_uart_setup_console() can be safely called at runtime.
[*] https://lore.kernel.org/all/20181114174940.7865-3-stefan@agner.ch/
Fixes: a3cb39d258ef ("serial: core: Allow detach and attach serial device for console") Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Acked-by: Uwe Kleine-König u.kleine-koenig@pengutronix.de Signed-off-by: Stefan Agner stefan@agner.ch Signed-off-by: Francesco Dolcini francesco.dolcini@toradex.com Link: https://lore.kernel.org/r/20211020192643.476895-2-francesco.dolcini@toradex.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/imx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 8b121cd869e94..51a9f9423b1a6 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -2017,7 +2017,7 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) * If the port was already initialised (eg, by a boot loader), * try to determine the current setup. */ -static void __init +static void imx_uart_console_get_options(struct imx_port *sport, int *baud, int *parity, int *bits) { @@ -2076,7 +2076,7 @@ imx_uart_console_get_options(struct imx_port *sport, int *baud, } }
-static int __init +static int imx_uart_console_setup(struct console *co, char *options) { struct imx_port *sport;
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit b2cab2a24fb5d13ce1d384ecfb6de827fa08a048 ]
Instead of forcing the role to Device, check the dr_mode configuration. If the core is Host only, force the mode to Host, this to avoid the dwc2_force_mode warning: WARNING: CPU: 1 PID: 21 at drivers/usb/dwc2/core.c:615 dwc2_drd_init+0x104/0x17c
When forcing mode to Host, dwc2_force_mode may sleep the time the host role is applied. To avoid sleeping while atomic context, move the call to dwc2_force_mode after spin_unlock_irqrestore. It is safe, as interrupts are not yet unmasked here.
Fixes: 17f934024e84 ("usb: dwc2: override PHY input signals with usb role switch support") Acked-by: Minas Harutyunyan Minas.Harutyunyan@synopsys.com Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20211005095305.66397-2-amelie.delaunay@foss.st.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc2/drd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/dwc2/drd.c b/drivers/usb/dwc2/drd.c index 2d4176f5788eb..80eae88d76dda 100644 --- a/drivers/usb/dwc2/drd.c +++ b/drivers/usb/dwc2/drd.c @@ -25,9 +25,9 @@ static void dwc2_ovr_init(struct dwc2_hsotg *hsotg) gotgctl &= ~(GOTGCTL_BVALOVAL | GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL); dwc2_writel(hsotg, gotgctl, GOTGCTL);
- dwc2_force_mode(hsotg, false); - spin_unlock_irqrestore(&hsotg->lock, flags); + + dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST)); }
static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid)
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit 8d387f61b0240854e81450c261beb775065bad5d ]
In case of USB_DR_MODE_PERIPHERAL, the OTG clock is disabled at the end of the probe (it is not the case if USB_DR_MODE_HOST or USB_DR_MODE_OTG). The clock is then enabled on udc_start. If dwc2_drd_role_sw_set is called before udc_start (it is the case if the usb cable is plugged at boot), GOTGCTL and GUSBCFG registers cannot be read/written, so session cannot be overridden. To avoid this case, check the ll_hw_enabled value and enable the clock if it is available, and disable it after the override.
Fixes: 17f934024e84 ("usb: dwc2: override PHY input signals with usb role switch support") Acked-by: Minas Harutyunyan Minas.Harutyunyan@synopsys.com Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20211005095305.66397-3-amelie.delaunay@foss.st.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc2/drd.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/drivers/usb/dwc2/drd.c b/drivers/usb/dwc2/drd.c index 80eae88d76dda..99672360f34b0 100644 --- a/drivers/usb/dwc2/drd.c +++ b/drivers/usb/dwc2/drd.c @@ -7,6 +7,7 @@ * Author(s): Amelie Delaunay amelie.delaunay@st.com */
+#include <linux/clk.h> #include <linux/iopoll.h> #include <linux/platform_device.h> #include <linux/usb/role.h> @@ -86,6 +87,20 @@ static int dwc2_drd_role_sw_set(struct usb_role_switch *sw, enum usb_role role) } #endif
+ /* + * In case of USB_DR_MODE_PERIPHERAL, clock is disabled at the end of + * the probe and enabled on udc_start. + * If role-switch set is called before the udc_start, we need to enable + * the clock to read/write GOTGCTL and GUSBCFG registers to override + * mode and sessions. It is the case if cable is plugged at boot. + */ + if (!hsotg->ll_hw_enabled && hsotg->clk) { + int ret = clk_prepare_enable(hsotg->clk); + + if (ret) + return ret; + } + spin_lock_irqsave(&hsotg->lock, flags);
if (role == USB_ROLE_HOST) { @@ -110,6 +125,9 @@ static int dwc2_drd_role_sw_set(struct usb_role_switch *sw, enum usb_role role) /* This will raise a Connector ID Status Change Interrupt */ dwc2_force_mode(hsotg, role == USB_ROLE_HOST);
+ if (!hsotg->ll_hw_enabled && hsotg->clk) + clk_disable_unprepare(hsotg->clk); + dev_dbg(hsotg->dev, "%s-session valid\n", role == USB_ROLE_NONE ? "No" : role == USB_ROLE_HOST ? "A" : "B");
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit 1ad707f559f7cb12c64f3d7cb37f0b1ea27c1058 ]
If role is changed without the "none" step, A- and B- valid session could be set at the same time. It is an issue. This patch resets A-session if role switch sets B-session, and resets B-session if role switch sets A-session. Then, it is possible to change the role without the "none" step.
Fixes: 17f934024e84 ("usb: dwc2: override PHY input signals with usb role switch support") Acked-by: Minas Harutyunyan Minas.Harutyunyan@synopsys.com Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20211005095305.66397-4-amelie.delaunay@foss.st.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc2/drd.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/usb/dwc2/drd.c b/drivers/usb/dwc2/drd.c index 99672360f34b0..aa6eb76f64ddc 100644 --- a/drivers/usb/dwc2/drd.c +++ b/drivers/usb/dwc2/drd.c @@ -40,6 +40,7 @@ static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid) (!valid && !(gotgctl & GOTGCTL_ASESVLD))) return -EALREADY;
+ gotgctl &= ~GOTGCTL_BVALOVAL; if (valid) gotgctl |= GOTGCTL_AVALOVAL | GOTGCTL_VBVALOVAL; else @@ -58,6 +59,7 @@ static int dwc2_ovr_bvalid(struct dwc2_hsotg *hsotg, bool valid) (!valid && !(gotgctl & GOTGCTL_BSESVLD))) return -EALREADY;
+ gotgctl &= ~GOTGCTL_AVALOVAL; if (valid) gotgctl |= GOTGCTL_BVALOVAL | GOTGCTL_VBVALOVAL; else
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit 68b44f94d6370e2c6c790fedd28e637fa9964a93 ]
fsl_booke and 44x are not able to map kernel linear memory with pages, so they can't support DEBUG_PAGEALLOC and KFENCE, and STRICT_KERNEL_RWX is also a problem for now.
Enable those only on book3s (both 32 and 64 except KFENCE), 8xx and 40x.
Fixes: 88df6e90fa97 ("[POWERPC] DEBUG_PAGEALLOC for 32-bit") Fixes: 95902e6c8864 ("powerpc/mm: Implement STRICT_KERNEL_RWX on PPC32") Fixes: 90cbac0e995d ("powerpc: Enable KFENCE for PPC32") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/d1ad9fdd9b27da3fdfa16510bb542ed51fa6e134.163429213... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index ba5b661893588..6b9f523882c58 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -138,7 +138,7 @@ config PPC select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 select ARCH_HAS_SET_MEMORY - select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION) + select ARCH_HAS_STRICT_KERNEL_RWX if (PPC_BOOK3S || PPC_8xx || 40x) && !HIBERNATION select ARCH_HAS_STRICT_MODULE_RWX if ARCH_HAS_STRICT_KERNEL_RWX && !PPC_BOOK3S_32 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE @@ -150,7 +150,7 @@ config PPC select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX select ARCH_STACKWALK select ARCH_SUPPORTS_ATOMIC_RMW - select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC32 || PPC_BOOK3S_64 + select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx || 40x select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF if PPC64 select ARCH_USE_MEMTEST @@ -190,7 +190,7 @@ config PPC select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14 select HAVE_ARCH_KASAN_VMALLOC if PPC32 && PPC_PAGE_SHIFT <= 14 - select HAVE_ARCH_KFENCE if PPC32 + select HAVE_ARCH_KFENCE if PPC_BOOK3S_32 || PPC_8xx || 40x select HAVE_ARCH_KGDB select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
From: Jack Pham jackp@codeaurora.org
[ Upstream commit 876a75cb520f5869533a30a6ca01545ec817b7a0 ]
Some functions may dynamically enable and disable their endpoints regularly throughout their operation, particularly when Set Interface is employed to switch between Alternate Settings. For instance the UAC2 function has its respective endpoints for playback & capture associated with AltSetting 1, in which case those endpoints would not get enabled until the host activates the AltSetting. And they conversely become disabled when the interfaces' AltSetting 0 is chosen.
With the DWC3 FIFO resizing algorithm recently added, every usb_ep_enable() call results in a call to resize that EP's TXFIFO, but if the same endpoint is enabled again and again, this incorrectly leads to FIFO RAM allocation exhaustion as the mechanism did not account for the possibility that endpoints can be re-enabled many times.
Example log splat:
dwc3 a600000.dwc3: Fifosize(3717) > RAM size(3462) ep3in depth:217973127 configfs-gadget gadget: u_audio_start_capture:521 Error! dwc3 a600000.dwc3: request 000000000be13e18 was not queued to ep3in
Add another bit DWC3_EP_TXFIFO_RESIZED to dep->flags to keep track of whether an EP had already been resized in the current configuration. If so, bail out of dwc3_gadget_resize_tx_fifos() to avoid the calculation error resulting from accumulating the EP's FIFO depth repeatedly. This flag is retained across multiple ep_disable() and ep_enable() calls and is cleared when GTXFIFOSIZn is reset in dwc3_gadget_clear_tx_fifos() upon receiving the next Set Config.
Fixes: 9f607a309fbe9 ("usb: dwc3: Resize TX FIFOs to meet EP bursting requirements") Reviewed-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Signed-off-by: Jack Pham jackp@codeaurora.org Link: https://lore.kernel.org/r/20211021180129.27938-1-jackp@codeaurora.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/gadget.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5612bfdf37da9..0c100901a7845 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -723,6 +723,7 @@ struct dwc3_ep { #define DWC3_EP_FORCE_RESTART_STREAM BIT(9) #define DWC3_EP_FIRST_STREAM_PRIMED BIT(10) #define DWC3_EP_PENDING_CLEAR_STALL BIT(11) +#define DWC3_EP_TXFIFO_RESIZED BIT(12)
/* This last one is specific to EP0 */ #define DWC3_EP0_DIR_IN BIT(31) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4519d06c9ca2b..ed97e47d32613 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -702,6 +702,7 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) DWC31_GTXFIFOSIZ_TXFRAMNUM;
dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1), size); + dep->flags &= ~DWC3_EP_TXFIFO_RESIZED; } dwc->num_ep_resized = 0; } @@ -747,6 +748,10 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) if (!usb_endpoint_dir_in(dep->endpoint.desc) || dep->number <= 1) return 0;
+ /* bail if already resized */ + if (dep->flags & DWC3_EP_TXFIFO_RESIZED) + return 0; + ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
if ((dep->endpoint.maxburst > 1 && @@ -807,6 +812,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) }
dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size); + dep->flags |= DWC3_EP_TXFIFO_RESIZED; dwc->num_ep_resized++;
return 0; @@ -995,7 +1001,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
dep->stream_capable = false; dep->type = 0; - dep->flags = 0; + dep->flags &= DWC3_EP_TXFIFO_RESIZED;
return 0; }
From: Guru Das Srinagesh quic_gurus@quicinc.com
[ Upstream commit 38212b2a8a6fc4c3a6fa99d7445b833bedc9a67c ]
Since __qcom_scm_is_call_available() returns bool, have it return false instead of -EINVAL if an invalid SMC convention is detected.
This fixes the Smatch static checker warning:
drivers/firmware/qcom_scm.c:255 __qcom_scm_is_call_available() warn: signedness bug returning '(-22)'
Fixes: 9d11af8b06a8 ("firmware: qcom_scm: Make __qcom_scm_is_call_available() return bool") Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Guru Das Srinagesh quic_gurus@quicinc.com Reviewed-by: Stephen Boyd swboyd@chromium.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/1633982414-28347-1-git-send-email-quic_gurus@quici... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/firmware/qcom_scm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2ee97bab74409..27a64de919817 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -252,7 +252,7 @@ static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id, break; default: pr_err("Unknown SMC convention being used\n"); - return -EINVAL; + return false; }
ret = qcom_scm_call(dev, &desc, &res);
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 086f52fdc8f7bd273d06a3de2adf65a063eb5392 ]
The sm8350_mxc's domain description incorrectly references sm8150_mmcx_ao as a peer instead of sm8350_mxc_ao. Correct this typo.
Fixes: 639c85628757 ("soc: qcom: rpmhpd: Add SM8350 power domains") Cc: Vinod Koul vkoul@kernel.org Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211020012639.1183806-1-dmitry.baryshkov@linaro.o... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/rpmhpd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index a46735cec3f0f..d98cc8c2e5d5c 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -206,7 +206,7 @@ static const struct rpmhpd_desc sm8250_desc = { static struct rpmhpd sm8350_mxc_ao; static struct rpmhpd sm8350_mxc = { .pd = { .name = "mxc", }, - .peer = &sm8150_mmcx_ao, + .peer = &sm8350_mxc_ao, .res_name = "mxc.lvl", };
From: Wan Jiabing wanjiabing@vivo.com
[ Upstream commit 72f1aa6205d84337b90b065f602a8fe190821781 ]
Fix following coccicheck warning:
./drivers/soc/qcom/apr.c:485:1-23: WARNING: Function for_each_child_of_node should have of_node_put() before return
Early exits from for_each_child_of_node should decrement the node reference counter.
Fixes: 834735662602 ("soc: qcom: apr: Add avs/audio tracking functionality") Signed-off-by: Wan Jiabing wanjiabing@vivo.com Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211014083017.19714-1-wanjiabing@vivo.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/apr.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index 475a57b435b24..2e455d9e3d94a 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -321,12 +321,14 @@ static int of_apr_add_pd_lookups(struct device *dev) 1, &service_path); if (ret < 0) { dev_err(dev, "pdr service path missing: %d\n", ret); + of_node_put(node); return ret; }
pds = pdr_add_lookup(apr->pdr, service_name, service_path); if (IS_ERR(pds) && PTR_ERR(pds) != -EALREADY) { dev_err(dev, "pdr add lookup failed: %ld\n", PTR_ERR(pds)); + of_node_put(node); return PTR_ERR(pds); } }
From: Marijn Suijten marijn.suijten@somainline.org
[ Upstream commit b110dfa5ad42be93ebf73540d16430878dfb26bb ]
The property is named "qcom,external-pfet", as found by dt_binding_check:
'qcom,eternal-pfet' does not match any of the regexes
Fixes: 37aa540cbd30 ("arm64: dts: qcom: pmi8994: Add WLED node") Signed-off-by: Marijn Suijten marijn.suijten@somainline.org Reviewed-By: AngeloGioacchino Del Regno angelogioacchino.delregno@somainline.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211007213400.258371-11-marijn.suijten@somainline... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/pmi8994.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi index b4ac900ab115f..a06ea9adae810 100644 --- a/arch/arm64/boot/dts/qcom/pmi8994.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -42,7 +42,7 @@ /* Yes, all four strings *have to* be defined or things won't work. */ qcom,enabled-strings = <0 1 2 3>; qcom,cabc; - qcom,eternal-pfet; + qcom,external-pfet; status = "disabled"; }; };
From: Bhupesh Sharma bhupesh.sharma@linaro.org
[ Upstream commit eed1d9b6e36b06faa53c6dc74134ec21b1336d94 ]
In commit 3e482859f1ef ("dts: qcom: sdm845: Add dt entries to support crypto engine."), we decided to use the value indicated by constant RPMH_CE_CLK rather than using it directly.
Now that the same RPMH clock value might be used for other SoCs (in addition to sdm845), let's use the constant RPMH_CE_CLK to make sure that this dtsi is compatible with the other qcom ones.
Signed-off-by: Bhupesh Sharma bhupesh.sharma@linaro.org Reviewed-by: Thara Gopinath thara.gopinath@linaro.org Link: https://lore.kernel.org/r/20210519143700.27392-8-bhupesh.sharma@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index b3b9119261844..98370d474f646 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -2316,7 +2316,7 @@ compatible = "qcom,bam-v1.7.0"; reg = <0 0x01dc4000 0 0x24000>; interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&rpmhcc 15>; + clocks = <&rpmhcc RPMH_CE_CLK>; clock-names = "bam_clk"; #dma-cells = <1>; qcom,ee = <0>; @@ -2332,7 +2332,7 @@ reg = <0 0x01dfa000 0 0x6000>; clocks = <&gcc GCC_CE1_AHB_CLK>, <&gcc GCC_CE1_AHB_CLK>, - <&rpmhcc 15>; + <&rpmhcc RPMH_CE_CLK>; clock-names = "iface", "bus", "core"; dmas = <&cryptobam 6>, <&cryptobam 7>; dma-names = "rx", "tx";
From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit d5240f8e23641c70bc70892d7999398b081ccb7e ]
The change corrects the described bus clock of the QCE.
Fixes: 3e482859f1ef ("dts: qcom: sdm845: Add dt entries to support crypto engine.") Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reviewed-by: Thara Gopinath thara.gopinath@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211011095534.1580406-1-vladimir.zapolskiy@linaro... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 98370d474f646..a810adc1a707f 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -2331,7 +2331,7 @@ compatible = "qcom,crypto-v5.4"; reg = <0 0x01dfa000 0 0x6000>; clocks = <&gcc GCC_CE1_AHB_CLK>, - <&gcc GCC_CE1_AHB_CLK>, + <&gcc GCC_CE1_AXI_CLK>, <&rpmhcc RPMH_CE_CLK>; clock-names = "iface", "bus", "core"; dmas = <&cryptobam 6>, <&cryptobam 7>;
From: Rahul Tanwar rtanwar@maxlinear.com
[ Upstream commit 53b3947ddb7f309d1f611f8dc9bfd6ea9d699907 ]
Ignore the same function with multiple groups. Fix a typo in error print.
Fixes: 1948d5c51dba ("pinctrl: Add pinmux & GPIO controller driver for a new SoC") Signed-off-by: Rahul Tanwar rtanwar@maxlinear.com Link: https://lore.kernel.org/r/20211020093815.20870-1-rtanwar@maxlinear.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-equilibrium.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c index fb713f9c53d0e..3f0143087cc77 100644 --- a/drivers/pinctrl/pinctrl-equilibrium.c +++ b/drivers/pinctrl/pinctrl-equilibrium.c @@ -675,6 +675,11 @@ static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata) return ret;
for (i = 0; i < nr_funcs; i++) { + + /* Ignore the same function with multiple groups */ + if (funcs[i].name == NULL) + continue; + ret = pinmux_generic_add_function(drvdata->pctl_dev, funcs[i].name, funcs[i].groups, @@ -815,7 +820,7 @@ static int pinctrl_reg(struct eqbr_pinctrl_drv_data *drvdata)
ret = eqbr_build_functions(drvdata); if (ret) { - dev_err(dev, "Failed to build groups\n"); + dev_err(dev, "Failed to build functions\n"); return ret; }
From: Mark Brown broonie@kernel.org
[ Upstream commit 1198ff12cbdd5f42c032cba1d96ebc7af8024cf9 ]
When removing the index argument from snd_soc_topology_component_remove() commit a5b8f71c5477f (ASoC: topology: Remove multistep topology loading) forgot to update the stub for !SND_SOC_TOPOLOGY use, causing build failures for anything that tries to make use of it.
Fixes: a5b8f71c5477f (ASoC: topology: Remove multistep topology loading) Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20211025154844.2342120-1-broonie@kernel.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/sound/soc-topology.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/sound/soc-topology.h b/include/sound/soc-topology.h index 4afd667e124c2..3e8a85e1e8094 100644 --- a/include/sound/soc-topology.h +++ b/include/sound/soc-topology.h @@ -188,8 +188,7 @@ int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w,
#else
-static inline int snd_soc_tplg_component_remove(struct snd_soc_component *comp, - u32 index) +static inline int snd_soc_tplg_component_remove(struct snd_soc_component *comp) { return 0; }
From: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org
[ Upstream commit bf7ffcd0069d30e2e7ba2b827f08c89f471cd1f3 ]
On success nvmem_cell_read() returns a pointer to a dynamically allocated buffer, and therefore it shall be freed after usage.
The issue is reported by kmemleak:
# cat /sys/kernel/debug/kmemleak unreferenced object 0xffff3b3803e4b280 (size 128): comm "kworker/u16:1", pid 107, jiffies 4294892861 (age 94.120s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<000000007739afdc>] __kmalloc+0x27c/0x41c [<0000000071c0fbf8>] nvmem_cell_read+0x40/0xe0 [<00000000e803ef1f>] qusb2_phy_init+0x258/0x5bc [<00000000fc81fcfa>] phy_init+0x70/0x110 [<00000000e3d48a57>] dwc3_core_soft_reset+0x4c/0x234 [<0000000027d1dbd4>] dwc3_core_init+0x68/0x990 [<000000001965faf9>] dwc3_probe+0x4f4/0x730 [<000000002f7617ca>] platform_probe+0x74/0xf0 [<00000000a2576cac>] really_probe+0xc4/0x470 [<00000000bc77f2c5>] __driver_probe_device+0x11c/0x190 [<00000000130db71f>] driver_probe_device+0x48/0x110 [<0000000019f36c2b>] __device_attach_driver+0xa4/0x140 [<00000000e5812ff7>] bus_for_each_drv+0x84/0xe0 [<00000000f4bac574>] __device_attach+0xe4/0x1c0 [<00000000d3beb631>] device_initial_probe+0x20/0x30 [<000000008019b9db>] bus_probe_device+0xa4/0xb0
Fixes: ca04d9d3e1b1 ("phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips") Signed-off-by: Vladimir Zapolskiy vladimir.zapolskiy@linaro.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20210922233548.2150244-1-vladimir.zapolskiy@linaro... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 3c1d3b71c825b..f1d97fbd13318 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -561,7 +561,7 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy) { struct device *dev = &qphy->phy->dev; const struct qusb2_phy_cfg *cfg = qphy->cfg; - u8 *val; + u8 *val, hstx_trim;
/* efuse register is optional */ if (!qphy->cell) @@ -575,7 +575,13 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy) * set while configuring the phy. */ val = nvmem_cell_read(qphy->cell, NULL); - if (IS_ERR(val) || !val[0]) { + if (IS_ERR(val)) { + dev_dbg(dev, "failed to read a valid hs-tx trim value\n"); + return; + } + hstx_trim = val[0]; + kfree(val); + if (!hstx_trim) { dev_dbg(dev, "failed to read a valid hs-tx trim value\n"); return; } @@ -583,12 +589,10 @@ static void qusb2_phy_set_tune2_param(struct qusb2_phy *qphy) /* Fused TUNE1/2 value is the higher nibble only */ if (cfg->update_tune1_with_efuse) qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1], - val[0] << HSTX_TRIM_SHIFT, - HSTX_TRIM_MASK); + hstx_trim << HSTX_TRIM_SHIFT, HSTX_TRIM_MASK); else qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2], - val[0] << HSTX_TRIM_SHIFT, - HSTX_TRIM_MASK); + hstx_trim << HSTX_TRIM_SHIFT, HSTX_TRIM_MASK); }
static int qusb2_phy_set_mode(struct phy *phy,
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 8d55027f4e2c04146a75fb63371ab96ccc887f2c ]
Smatch complains that if of_get_address() returns NULL, then "size" isn't initialized. Also it would lead to an Oops.
Fixes: 7f78322cdd67 ("phy: ti: gmii-sel: retrieve ports number and base offset from dt") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Grygorii Strashko grygorii.strashko@ti.com Link: https://lore.kernel.org/r/20210914110038.GB11657@kili Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/ti/phy-gmii-sel.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c index 5fd2e8a08bfcf..d0ab69750c6b4 100644 --- a/drivers/phy/ti/phy-gmii-sel.c +++ b/drivers/phy/ti/phy-gmii-sel.c @@ -320,6 +320,8 @@ static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv) u64 size;
offset = of_get_address(dev->of_node, 0, &size, NULL); + if (!offset) + return -EINVAL; priv->num_ports = size / sizeof(u32); if (!priv->num_ports) return -EINVAL;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 26f71abef580537d978f6299330689f029ee1e6c ]
Commit f839f14e24f2 ("phy: qcom-qmp: Add sc8180x PCIe support") added SC8180X PCIe tables, but used sm8250_qmp_pcie_serdes_tbl as a serdes table because of the copy paste error. Commit bfccd9a71a08 ("phy: qcom-qmp: Fix sc8180x PCIe definition") corrected part of this mistake by pointing serdes_tbl to sc8180x_qmp_pcie_serdes_tbl, however the serdes_tbl_num field was not updated to use sc8180x table. So let's now fix the serdes_tbl_num field too.
Fixes: bfccd9a71a08 ("phy: qcom-qmp: Fix sc8180x PCIe definition") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/20211020155604.1374530-1-dmitry.baryshkov@linaro.o... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/qualcomm/phy-qcom-qmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index f14032170b1c1..06b04606dd7ea 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -3632,7 +3632,7 @@ static const struct qmp_phy_cfg sc8180x_pciephy_cfg = { .nlanes = 1,
.serdes_tbl = sc8180x_qmp_pcie_serdes_tbl, - .serdes_tbl_num = ARRAY_SIZE(sm8250_qmp_pcie_serdes_tbl), + .serdes_tbl_num = ARRAY_SIZE(sc8180x_qmp_pcie_serdes_tbl), .tx_tbl = sc8180x_qmp_pcie_tx_tbl, .tx_tbl_num = ARRAY_SIZE(sc8180x_qmp_pcie_tx_tbl), .rx_tbl = sc8180x_qmp_pcie_rx_tbl,
From: Sandeep Maheswaram quic_c_sanm@quicinc.com
[ Upstream commit b475bf0ec40a2b13fb32ef62f5706576d5858460 ]
The FSEL_MASK which selects the refclock is defined incorrectly. It should be [4:6] not [5:7]. Due to this incorrect definition, the BIT(7) in USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 is reset which keeps PHY analog blocks ON during suspend. Fix this issue by correctly defining the FSEL_MASK.
Fixes: 51e8114f80d0 ("phy: qcom-snps: Add SNPS USB PHY driver for QCOM based SOCs") Signed-off-by: Sandeep Maheswaram quic_c_sanm@quicinc.com Link: https://lore.kernel.org/r/1635135575-5668-1-git-send-email-quic_c_sanm@quici... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index ae4bac024c7b1..7e61202aa234e 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -33,7 +33,7 @@
#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON0 (0x54) #define RETENABLEN BIT(3) -#define FSEL_MASK GENMASK(7, 5) +#define FSEL_MASK GENMASK(6, 4) #define FSEL_DEFAULT (0x3 << 4)
#define USB2_PHY_USB_PHY_HS_PHY_CTRL_COMMON1 (0x58)
From: Yang Yingliang yangyingliang@huawei.com
[ Upstream commit b4dc97ab0a629eda8bda20d96ef47dac08a505d9 ]
In case of error, the function devm_ioremap() returns NULL pointer not ERR_PTR(). The IS_ERR() test in the return value check should be replaced with NULL test.
Fixes: 2ff8a1eeb5aa ("phy: Add Sparx5 ethernet serdes PHY driver") Reported-by: Hulk Robot hulkci@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Link: https://lore.kernel.org/r/20210909072149.2934047-1-yangyingliang@huawei.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/microchip/sparx5_serdes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/microchip/sparx5_serdes.c b/drivers/phy/microchip/sparx5_serdes.c index 4076580fc2cd9..ab1b0986aa671 100644 --- a/drivers/phy/microchip/sparx5_serdes.c +++ b/drivers/phy/microchip/sparx5_serdes.c @@ -2475,10 +2475,10 @@ static int sparx5_serdes_probe(struct platform_device *pdev) return -EINVAL; } iomem = devm_ioremap(priv->dev, iores->start, resource_size(iores)); - if (IS_ERR(iomem)) { + if (!iomem) { dev_err(priv->dev, "Unable to get serdes registers: %s\n", iores->name); - return PTR_ERR(iomem); + return -ENOMEM; } for (idx = 0; idx < ARRAY_SIZE(sparx5_serdes_iomap); idx++) { struct sparx5_serdes_io_resource *iomap = &sparx5_serdes_iomap[idx];
From: Anssi Hannula anssi.hannula@bitwise.fi
[ Upstream commit 88b20f84f0fe47409342669caf3e58a3fc64c316 ]
xilinx_uartps .start_tx() clears TXEMPTY when enabling TXEMPTY to avoid any previous TXEVENT event asserting the UART interrupt. This clear operation is done immediately after filling the TX FIFO.
However, if the bytes inserted by cdns_uart_handle_tx() are consumed by the UART before the TXEMPTY is cleared, the clear operation eats the new TXEMPTY event as well, causing cdns_uart_isr() to never receive the TXEMPTY event. If there are bytes still queued in circbuf, TX will get stuck as they will never get transferred to FIFO (unless new bytes are queued to circbuf in which case .start_tx() is called again).
While the racy missed TXEMPTY occurs fairly often with short data sequences (e.g. write 1 byte), in those cases circbuf is usually empty so no action on TXEMPTY would have been needed anyway. On the other hand, longer data sequences make the race much more unlikely as UART takes longer to consume the TX FIFO. Therefore it is rare for this race to cause visible issues in general.
Fix the race by clearing the TXEMPTY bit in ISR *before* filling the FIFO.
The TXEMPTY bit in ISR will only get asserted at the exact moment the TX FIFO *becomes* empty, so clearing the bit before filling FIFO does not cause an extra immediate assertion even if the FIFO is initially empty.
This is hard to reproduce directly on a normal system, but inserting e.g. udelay(200) after cdns_uart_handle_tx(port), setting 4000000 baud, and then running "dd if=/dev/zero bs=128 of=/dev/ttyPS0 count=50" reliably reproduces the issue on my ZynqMP test system unless this fix is applied.
Fixes: 85baf542d54e ("tty: xuartps: support 64 byte FIFO size") Signed-off-by: Anssi Hannula anssi.hannula@bitwise.fi Link: https://lore.kernel.org/r/20211026102741.2910441-1-anssi.hannula@bitwise.fi Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/xilinx_uartps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index 962e522ccc45c..d5e243908d9fd 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -601,9 +601,10 @@ static void cdns_uart_start_tx(struct uart_port *port) if (uart_circ_empty(&port->state->xmit)) return;
+ writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_ISR); + cdns_uart_handle_tx(port);
- writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_ISR); /* Enable the TX Empty interrupt */ writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IER); }
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit f12d028b743bb6136da60b17228a1b6162886444 ]
Use DIV_ROUND_CLOSEST_ULL() to avoid any inconsistency b/w the rate computed in sam9x60_frac_pll_recalc_rate() and the one computed in sam9x60_frac_pll_compute_mul_frac().
Fixes: 43b1bb4a9b3e1 ("clk: at91: clk-sam9x60-pll: re-factor to support plls with multiple outputs") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20211011112719.3951784-8-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/clk-sam9x60-pll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index 34e3ab13741ac..1f52409475e9c 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -71,8 +71,8 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw, struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); struct sam9x60_frac *frac = to_sam9x60_frac(core);
- return (parent_rate * (frac->mul + 1) + - ((u64)parent_rate * frac->frac >> 22)); + return parent_rate * (frac->mul + 1) + + DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22)); }
static int sam9x60_frac_pll_prepare(struct clk_hw *hw)
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit c2910c00fee4cbb7b222d6e02846adef9ae4135a ]
Check if div or pres is zero before using it as argument for ffs(). In case div is zero ffs() will return 0 and thus substracting from zero will lead to invalid values to be setup in registers.
Fixes: 7a110b9107ed8 ("clk: at91: clk-master: re-factor master clock") Fixes: 75c88143f3b87 ("clk: at91: clk-master: add master clock support for SAMA7G5") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20211011112719.3951784-9-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/clk-master.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index a80427980bf73..2e410815a3405 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -280,7 +280,7 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate,
else if (pres == 3) pres = MASTER_PRES_MAX; - else + else if (pres) pres = ffs(pres) - 1;
spin_lock_irqsave(master->lock, flags); @@ -610,7 +610,7 @@ static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate,
if (div == 3) div = MASTER_PRES_MAX; - else + else if (div) div = ffs(div) - 1;
spin_lock_irqsave(master->lock, flags);
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 0ef99f8202c5078a72c05af76bfaed2ea4daab19 ]
When prescaler value read from register is MASTER_PRES_MAX it means that the input clock will be divided by 3. Fix the code to reflect this.
Fixes: 7a110b9107ed8 ("clk: at91: clk-master: re-factor master clock") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Link: https://lore.kernel.org/r/20211011112719.3951784-11-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/clk-master.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 2e410815a3405..04d0dd8385945 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -309,7 +309,7 @@ static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, spin_unlock_irqrestore(master->lock, flags);
pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; - if (pres == 3 && characteristics->have_div3_pres) + if (pres == MASTER_PRES_MAX && characteristics->have_div3_pres) pres = 3; else pres = (1 << pres);
From: Andrej Shadura andrew.shadura@collabora.co.uk
[ Upstream commit b7abf78b7a6c4a29a6e0ba0bb883fe44a2f3d693 ]
The previous commit fixed handling of incomplete packets but broke error handling: offsetof returns an unsigned value (size_t), but when compared against the signed return value, the return value is interpreted as if it were unsigned, so negative return values are never less than the offset.
To make the code easier to read, calculate the minimal packet length once and separately, and assign it to a signed int variable to eliminate unsigned math and the need for type casts. It then becomes immediately obvious how the actual data length is calculated and why the return value cannot be less than the minimal length.
Fixes: 22d65765f211 ("HID: u2fzero: ignore incomplete packets without data") Fixes: 42337b9d4d95 ("HID: add driver for U2F Zero built-in LED and RNG") Signed-off-by: Andrej Shadura andrew.shadura@collabora.co.uk Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-u2fzero.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-u2fzero.c b/drivers/hid/hid-u2fzero.c index d70cd3d7f583b..94f78ffb76d04 100644 --- a/drivers/hid/hid-u2fzero.c +++ b/drivers/hid/hid-u2fzero.c @@ -191,6 +191,8 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data, struct u2f_hid_msg resp; int ret; size_t actual_length; + /* valid packets must have a correct header */ + int min_length = offsetof(struct u2f_hid_msg, init.data);
if (!dev->present) { hid_dbg(dev->hdev, "device not present"); @@ -200,12 +202,12 @@ static int u2fzero_rng_read(struct hwrng *rng, void *data, ret = u2fzero_recv(dev, &req, &resp);
/* ignore errors or packets without data */ - if (ret < offsetof(struct u2f_hid_msg, init.data)) + if (ret < min_length) return 0;
/* only take the minimum amount of data it is safe to take */ - actual_length = min3((size_t)ret - offsetof(struct u2f_hid_msg, - init.data), U2F_HID_MSG_LEN(resp), max); + actual_length = min3((size_t)ret - min_length, + U2F_HID_MSG_LEN(resp), max);
memcpy(data, resp.init.data, actual_length);
From: Andrej Shadura andrew.shadura@collabora.co.uk
[ Upstream commit 43775e62c4b784f44a159e13ba80e6146a42d502 ]
The wait_for_completion_timeout function returns 0 if timed out or a positive value if completed. Hence, "less than zero" comparison always misses timeouts and doesn't kill the URB as it should, leading to re-sending it while it is active.
Fixes: 42337b9d4d95 ("HID: add driver for U2F Zero built-in LED and RNG") Signed-off-by: Andrej Shadura andrew.shadura@collabora.co.uk Signed-off-by: Jiri Kosina jkosina@suse.cz Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/hid-u2fzero.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/hid-u2fzero.c b/drivers/hid/hid-u2fzero.c index 94f78ffb76d04..67ae2b18e33ac 100644 --- a/drivers/hid/hid-u2fzero.c +++ b/drivers/hid/hid-u2fzero.c @@ -132,7 +132,7 @@ static int u2fzero_recv(struct u2fzero_device *dev,
ret = (wait_for_completion_timeout( &ctx.done, msecs_to_jiffies(USB_CTRL_SET_TIMEOUT))); - if (ret < 0) { + if (ret == 0) { usb_kill_urb(dev->urb); hid_err(hdev, "urb submission timed out"); } else {
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit b1b93cb7e794e914787bf7d9936b57a149cdee4f ]
Commit 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code") changed those two functions to use pte helpers to determine which bits to clear and which bits to set.
This change was based on the assumption that bits to be set/cleared are always the same and can be determined by applying the pte manipulation helpers on __pte(0).
But on platforms like book3e, the bits depend on whether the page is a user page or not.
For the time being it more or less works because of _PAGE_EXEC being used for user pages only and exec right being set at all time on kernel page. But following patch will clean that and output of pte_mkexec() will depend on the page being a user or kernel page.
Instead of trying to make an even more complicated helper where bits would become dependent on the final pte value, come back to a more static situation like before commit 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code"), by introducing an 8xx specific version of __ptep_set_access_flags() and ptep_set_wrprotect().
Fixes: 26973fa5ac0e ("powerpc/mm: use pte helpers in generic code") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/922bdab3a220781bae2360ff3dd5adb7fe4d34f1.163522674... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/nohash/32/pgtable.h | 17 +++++++-------- arch/powerpc/include/asm/nohash/32/pte-8xx.h | 22 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index f06ae00f2a65e..ac0a5ff48c3ad 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -306,30 +306,29 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, }
#define __HAVE_ARCH_PTEP_SET_WRPROTECT +#ifndef ptep_set_wrprotect static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - unsigned long clr = ~pte_val(pte_wrprotect(__pte(~0))); - unsigned long set = pte_val(pte_wrprotect(__pte(0))); - - pte_update(mm, addr, ptep, clr, set, 0); + pte_update(mm, addr, ptep, _PAGE_RW, 0, 0); } +#endif
+#ifndef __ptep_set_access_flags static inline void __ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, pte_t entry, unsigned long address, int psize) { - pte_t pte_set = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(0))))); - pte_t pte_clr = pte_mkyoung(pte_mkdirty(pte_mkwrite(pte_mkexec(__pte(~0))))); - unsigned long set = pte_val(entry) & pte_val(pte_set); - unsigned long clr = ~pte_val(entry) & ~pte_val(pte_clr); + unsigned long set = pte_val(entry) & + (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); int huge = psize > mmu_virtual_psize ? 1 : 0;
- pte_update(vma->vm_mm, address, ptep, clr, set, huge); + pte_update(vma->vm_mm, address, ptep, 0, set, huge);
flush_tlb_page(vma, address); } +#endif
static inline int pte_young(pte_t pte) { diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h index fcc48d590d888..1a89ebdc3acc9 100644 --- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h +++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h @@ -136,6 +136,28 @@ static inline pte_t pte_mkhuge(pte_t pte)
#define pte_mkhuge pte_mkhuge
+static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p, + unsigned long clr, unsigned long set, int huge); + +static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + pte_update(mm, addr, ptep, 0, _PAGE_RO, 0); +} +#define ptep_set_wrprotect ptep_set_wrprotect + +static inline void __ptep_set_access_flags(struct vm_area_struct *vma, pte_t *ptep, + pte_t entry, unsigned long address, int psize) +{ + unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_EXEC); + unsigned long clr = ~pte_val(entry) & _PAGE_RO; + int huge = psize > mmu_virtual_psize ? 1 : 0; + + pte_update(vma->vm_mm, address, ptep, clr, set, huge); + + flush_tlb_page(vma, address); +} +#define __ptep_set_access_flags __ptep_set_access_flags + static inline unsigned long pgd_leaf_size(pgd_t pgd) { if (pgd_val(pgd) & _PMD_PAGE_8M)
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit b6cb20fdc2735f8b2e082937066c33fe376c2ee2 ]
set_memory_x() calls pte_mkexec() which sets _PAGE_EXEC. set_memory_nx() calls pte_exprotec() which clears _PAGE_EXEC.
Book3e has 2 bits, UX and SX, which defines the exec rights resp. for user (PR=1) and for kernel (PR=0).
_PAGE_EXEC is defined as UX only.
An executable kernel page is set with either _PAGE_KERNEL_RWX or _PAGE_KERNEL_ROX, which both have SX set and UX cleared.
So set_memory_nx() call for an executable kernel page does nothing because UX is already cleared.
And set_memory_x() on a non-executable kernel page makes it executable for the user and keeps it non-executable for kernel.
Also, pte_exec() always returns 'false' on kernel pages, because it checks _PAGE_EXEC which doesn't include SX, so for instance the W+X check doesn't work.
To fix this: - change tlb_low_64e.S to use _PAGE_BAP_UX instead of _PAGE_USER - sets both UX and SX in _PAGE_EXEC so that pte_exec() returns true whenever one of the two bits is set and pte_exprotect() clears both bits. - Define a book3e specific version of pte_mkexec() which sets either SX or UX based on UR.
Fixes: 1f9ad21c3b38 ("powerpc/mm: Implement set_memory() routines") Signed-off-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/c41100f9c144dc5b62e5a751b810190c6b5d42fd.163522674... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/include/asm/nohash/32/pgtable.h | 2 ++ arch/powerpc/include/asm/nohash/64/pgtable.h | 5 ----- arch/powerpc/include/asm/nohash/pte-book3e.h | 18 ++++++++++++++---- arch/powerpc/mm/nohash/tlb_low_64e.S | 8 ++++---- 4 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index ac0a5ff48c3ad..d6ba821a56ced 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -193,10 +193,12 @@ static inline pte_t pte_wrprotect(pte_t pte) } #endif
+#ifndef pte_mkexec static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) | _PAGE_EXEC); } +#endif
#define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_bad(pmd) (pmd_val(pmd) & _PMD_BAD) diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index d081704b13fb9..9d2905a474103 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -118,11 +118,6 @@ static inline pte_t pte_wrprotect(pte_t pte) return __pte(pte_val(pte) & ~_PAGE_RW); }
-static inline pte_t pte_mkexec(pte_t pte) -{ - return __pte(pte_val(pte) | _PAGE_EXEC); -} - #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
diff --git a/arch/powerpc/include/asm/nohash/pte-book3e.h b/arch/powerpc/include/asm/nohash/pte-book3e.h index 813918f407653..f798640422c2d 100644 --- a/arch/powerpc/include/asm/nohash/pte-book3e.h +++ b/arch/powerpc/include/asm/nohash/pte-book3e.h @@ -48,7 +48,7 @@ #define _PAGE_WRITETHRU 0x800000 /* W: cache write-through */
/* "Higher level" linux bit combinations */ -#define _PAGE_EXEC _PAGE_BAP_UX /* .. and was cache cleaned */ +#define _PAGE_EXEC (_PAGE_BAP_SX | _PAGE_BAP_UX) /* .. and was cache cleaned */ #define _PAGE_RW (_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */ #define _PAGE_KERNEL_RW (_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY) #define _PAGE_KERNEL_RO (_PAGE_BAP_SR) @@ -93,11 +93,11 @@ /* Permission masks used to generate the __P and __S table */ #define PAGE_NONE __pgprot(_PAGE_BASE) #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) -#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) +#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_BAP_UX) #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) -#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_BAP_UX) #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) -#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) +#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_BAP_UX)
#ifndef __ASSEMBLY__ static inline pte_t pte_mkprivileged(pte_t pte) @@ -113,6 +113,16 @@ static inline pte_t pte_mkuser(pte_t pte) }
#define pte_mkuser pte_mkuser + +static inline pte_t pte_mkexec(pte_t pte) +{ + if (pte_val(pte) & _PAGE_BAP_UR) + return __pte((pte_val(pte) & ~_PAGE_BAP_SX) | _PAGE_BAP_UX); + else + return __pte((pte_val(pte) & ~_PAGE_BAP_UX) | _PAGE_BAP_SX); +} +#define pte_mkexec pte_mkexec + #endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */ diff --git a/arch/powerpc/mm/nohash/tlb_low_64e.S b/arch/powerpc/mm/nohash/tlb_low_64e.S index bf24451f3e71f..9235e720e3572 100644 --- a/arch/powerpc/mm/nohash/tlb_low_64e.S +++ b/arch/powerpc/mm/nohash/tlb_low_64e.S @@ -222,7 +222,7 @@ tlb_miss_kernel_bolted:
tlb_miss_fault_bolted: /* We need to check if it was an instruction miss */ - andi. r10,r11,_PAGE_EXEC|_PAGE_BAP_SX + andi. r10,r11,_PAGE_BAP_UX|_PAGE_BAP_SX bne itlb_miss_fault_bolted dtlb_miss_fault_bolted: tlb_epilog_bolted @@ -239,7 +239,7 @@ itlb_miss_fault_bolted: srdi r15,r16,60 /* get region */ bne- itlb_miss_fault_bolted
- li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */ + li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */
/* We do the user/kernel test for the PID here along with the RW test */ @@ -614,7 +614,7 @@ itlb_miss_fault_e6500:
/* We do the user/kernel test for the PID here along with the RW test */ - li r11,_PAGE_PRESENT|_PAGE_EXEC /* Base perm */ + li r11,_PAGE_PRESENT|_PAGE_BAP_UX /* Base perm */ oris r11,r11,_PAGE_ACCESSED@h
cmpldi cr0,r15,0 /* Check for user region */ @@ -734,7 +734,7 @@ normal_tlb_miss_done:
normal_tlb_miss_access_fault: /* We need to check if it was an instruction miss */ - andi. r10,r11,_PAGE_EXEC + andi. r10,r11,_PAGE_BAP_UX bne 1f ld r14,EX_TLB_DEAR(r12) ld r15,EX_TLB_ESR(r12)
From: Bixuan Cui cuibixuan@linux.alibaba.com
[ Upstream commit 290fe8aa69ef5c51c778c0bb33f8ef0181c769f5 ]
Early exits from for_each_compatible_node() should decrement the node reference counter. Reported by Coccinelle:
./arch/powerpc/platforms/44x/fsp2.c:206:1-25: WARNING: Function "for_each_compatible_node" should have of_node_put() before return around line 218.
Fixes: 7813043e1bbc ("powerpc/44x/fsp2: Add irq error handlers") Signed-off-by: Bixuan Cui cuibixuan@linux.alibaba.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/1635406102-88719-1-git-send-email-cuibixuan@linux.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/platforms/44x/fsp2.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/platforms/44x/fsp2.c b/arch/powerpc/platforms/44x/fsp2.c index b299e43f5ef94..823397c802def 100644 --- a/arch/powerpc/platforms/44x/fsp2.c +++ b/arch/powerpc/platforms/44x/fsp2.c @@ -208,6 +208,7 @@ static void node_irq_request(const char *compat, irq_handler_t errirq_handler) if (irq == NO_IRQ) { pr_err("device tree node %pOFn is missing a interrupt", np); + of_node_put(np); return; }
@@ -215,6 +216,7 @@ static void node_irq_request(const char *compat, irq_handler_t errirq_handler) if (rc) { pr_err("fsp_of_probe: request_irq failed: np=%pOF rc=%d", np, rc); + of_node_put(np); return; } }
From: Denis Kirjanov kda@linux-powerpc.org
[ Upstream commit b1f896ce3542eb2eede5949ee2e481526fae1108 ]
p_state is unsigned since the commit 2f064a59a11f
The patch also uses TASK_RUNNING instead of null.
Fixes: 2f064a59a11f ("sched: Change task_struct::state") Signed-off-by: Denis Kirjanov kda@linux-powerpc.org Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211026133108.7113-1-kda@linux-powerpc.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/xmon/xmon.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index dd8241c009e53..8b28ff9d98d16 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -3264,8 +3264,7 @@ static void show_task(struct task_struct *volatile tsk) * appropriate for calling from xmon. This could be moved * to a common, generic, routine used by both. */ - state = (p_state == 0) ? 'R' : - (p_state < 0) ? 'U' : + state = (p_state == TASK_RUNNING) ? 'R' : (p_state & TASK_UNINTERRUPTIBLE) ? 'D' : (p_state & TASK_STOPPED) ? 'T' : (p_state & TASK_TRACED) ? 'C' :
From: Takashi Sakamoto o-takashi@sakamocchi.jp
[ Upstream commit cddcd5472abb7b8a9c37ccbcf0908b79740a01b5 ]
A user reports functional regression for Mackie Onyx 1640i that the device generates slow sound with ALSA oxfw driver which supports media clock recovery. Although the device is based on OXFW971 ASIC, it does not transfer isochronous packet with own event frequency as expected. The device seems to adjust event frequency according to events in received isochronous packets in the beginning of packet streaming. This is unknown quirk.
This commit fixes the regression to turn the recovery off in driver side. As a result, nominal frequency is used in duplex packet streaming between device and driver. For stability of sampling rate in events of transferred isochronous packet, 4,000 isochronous packets are skipped in the beginning of packet streaming.
Reference: https://github.com/takaswie/snd-firewire-improve/issues/38 Fixes: 029ffc429440 ("ALSA: oxfw: perform sequence replay for media clock recovery") Signed-off-by: Takashi Sakamoto o-takashi@sakamocchi.jp Link: https://lore.kernel.org/r/20211028130325.45772-1-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/firewire/oxfw/oxfw-stream.c | 7 ++++++- sound/firewire/oxfw/oxfw.c | 8 ++++++++ sound/firewire/oxfw/oxfw.h | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/sound/firewire/oxfw/oxfw-stream.c b/sound/firewire/oxfw/oxfw-stream.c index fff18b5d4e052..f4a702def3979 100644 --- a/sound/firewire/oxfw/oxfw-stream.c +++ b/sound/firewire/oxfw/oxfw-stream.c @@ -9,7 +9,7 @@ #include <linux/delay.h>
#define AVC_GENERIC_FRAME_MAXIMUM_BYTES 512 -#define READY_TIMEOUT_MS 200 +#define READY_TIMEOUT_MS 600
/* * According to datasheet of Oxford Semiconductor: @@ -367,6 +367,11 @@ int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw) // Just after changing sampling transfer frequency, many cycles are // skipped for packet transmission. tx_init_skip_cycles = 400; + } else if (oxfw->quirks & SND_OXFW_QUIRK_VOLUNTARY_RECOVERY) { + // It takes a bit time for target device to adjust event frequency + // according to nominal event frequency in isochronous packets from + // ALSA oxfw driver. + tx_init_skip_cycles = 4000; } else { replay_seq = true; } diff --git a/sound/firewire/oxfw/oxfw.c b/sound/firewire/oxfw/oxfw.c index daf731364695b..b496f87841aec 100644 --- a/sound/firewire/oxfw/oxfw.c +++ b/sound/firewire/oxfw/oxfw.c @@ -25,6 +25,7 @@ #define MODEL_SATELLITE 0x00200f #define MODEL_SCS1M 0x001000 #define MODEL_DUET_FW 0x01dddd +#define MODEL_ONYX_1640I 0x001640
#define SPECIFIER_1394TA 0x00a02d #define VERSION_AVC 0x010001 @@ -192,6 +193,13 @@ static int detect_quirks(struct snd_oxfw *oxfw, const struct ieee1394_device_id // OXFW971-based models may transfer events by blocking method. if (!(oxfw->quirks & SND_OXFW_QUIRK_JUMBO_PAYLOAD)) oxfw->quirks |= SND_OXFW_QUIRK_BLOCKING_TRANSMISSION; + + if (model == MODEL_ONYX_1640I) { + //Unless receiving packets without NOINFO packet, the device transfers + //mostly half of events in packets than expected. + oxfw->quirks |= SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET | + SND_OXFW_QUIRK_VOLUNTARY_RECOVERY; + } }
return 0; diff --git a/sound/firewire/oxfw/oxfw.h b/sound/firewire/oxfw/oxfw.h index c13034f6c2ca5..d728e451a25c6 100644 --- a/sound/firewire/oxfw/oxfw.h +++ b/sound/firewire/oxfw/oxfw.h @@ -47,6 +47,11 @@ enum snd_oxfw_quirk { // the device to process audio data even if the value is invalid in a point of // IEC 61883-1/6. SND_OXFW_QUIRK_IGNORE_NO_INFO_PACKET = 0x10, + // Loud Technologies Mackie Onyx 1640i seems to configure OXFW971 ASIC so that it decides + // event frequency according to events in received isochronous packets. The device looks to + // performs media clock recovery voluntarily. In the recovery, the packets with NO_INFO + // are ignored, thus driver should transfer packets with timestamp. + SND_OXFW_QUIRK_VOLUNTARY_RECOVERY = 0x20, };
/* This is an arbitrary number for convinience. */
From: Logan Gunthorpe logang@deltatee.com
[ Upstream commit ac315f96b3bd6f6b8f18f387816c7c2cc6b32e02 ]
scsi_dma_map() was reporting a failure during boot on an AMD machine with the IOMMU enabled.
scsi_dma_map failed: request for 36 bytes!
The issue was tracked down to a mistake in logic: should not return an error if iommu_deferred_attach() returns zero.
Reported-by: Marshall Midden marshallmidden@gmail.com Fixes: dabb16f67215 ("iommu/dma: return error code from iommu_dma_map_sg()") Link: https://lore.kernel.org/all/CAD2CkAWjS8=kKwEEN4cgVNjyFORUibzEiCUA-X+SMtbo0Jo... Signed-off-by: Logan Gunthorpe logang@deltatee.com Cc: Joerg Roedel joro@8bytes.org Cc: Will Deacon will@kernel.org Link: https://lore.kernel.org/r/20211027174757.119755-1-logang@deltatee.com Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/dma-iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 19bebacbf1780..2d60216440009 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -1007,7 +1007,8 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg,
if (static_branch_unlikely(&iommu_deferred_attach_enabled)) { ret = iommu_deferred_attach(dev, domain); - goto out; + if (ret) + goto out; }
if (dev_is_untrusted(dev))
From: Christophe Leroy christophe.leroy@csgroup.eu
[ Upstream commit f8c0e36b48e32b14bb83332d24e0646acd31d9e9 ]
When ARCH_SUPPORTS_DEBUG_PAGEALLOC is not selected, the user can still select CONFIG_DEBUG_PAGEALLOC in which case __kernel_map_pages() is provided by mm/page_poison.c
So only define __kernel_map_pages() when both CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC and CONFIG_DEBUG_PAGEALLOC are defined.
Fixes: 68b44f94d637 ("powerpc/booke: Disable STRICT_KERNEL_RWX, DEBUG_PAGEALLOC and KFENCE") Reported-by: kernel test robot lkp@intel.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/971b69739ff4746252e711a9845210465c023a9e.163542594... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/mm/pgtable_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index dcf5ecca19d99..fde1ed445ca46 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -173,7 +173,7 @@ void mark_rodata_ro(void) } #endif
-#ifdef CONFIG_DEBUG_PAGEALLOC +#if defined(CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC) && defined(CONFIG_DEBUG_PAGEALLOC) void __kernel_map_pages(struct page *page, int numpages, int enable) { unsigned long addr = (unsigned long)page_address(page);
From: Richard Fitzgerald rf@opensource.cirrus.com
[ Upstream commit 778a0cbef5fb76bf506f84938517bb77e7a1c478 ]
The setting from the cirrus,ts-inv property should be applied to the TIP_SENSE_INV bit, as this is the one that actually affects the jack detect block. The TS_INV bit only swaps the meaning of the PLUG and UNPLUG interrupts and should always be 1 for the interrupts to have the normal meaning.
Due to some misunderstanding the driver had been implemented to configure the TS_INV bit based on the jack switch polarity. This made the interrupts behave the correct way around, but left the jack detect block, button detect and analogue circuits always interpreting an open switch as unplugged.
The signal chain inside the codec is:
SENSE pin -> TIP_SENSE_INV -> TS_INV -> (invert) -> interrupts | v Jack detect, button detect and analog control
As the TIP_SENSE_INV already performs the necessary inversion the TS_INV bit never needs to change. It must always be 1 to yield the expected interrupt behaviour.
Some extra confusion has arisen because of the additional invert in the interrupt path, meaning that a value applied to the TS_INV bit produces the opposite effect of applying it to the TIP_SENSE_INV bit. The ts-inv property has therefore always had the opposite effect to what might be expected (0 = inverted, 1 = not inverted). To maintain the meaning of the ts-inv property it must be inverted when applied to TIP_SENSE_INV.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec") Link: https://lore.kernel.org/r/20211028140902.11786-3-rf@opensource.cirrus.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/cs42l42.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 6034e439d3132..762d9de73dbc2 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1684,12 +1684,15 @@ static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) (1 << CS42L42_HS_CLAMP_DISABLE_SHIFT));
/* Enable the tip sense circuit */ + regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL, + CS42L42_TS_INV_MASK, CS42L42_TS_INV_MASK); + regmap_update_bits(cs42l42->regmap, CS42L42_TIPSENSE_CTL, CS42L42_TIP_SENSE_CTRL_MASK | CS42L42_TIP_SENSE_INV_MASK | CS42L42_TIP_SENSE_DEBOUNCE_MASK, (3 << CS42L42_TIP_SENSE_CTRL_SHIFT) | - (0 << CS42L42_TIP_SENSE_INV_SHIFT) | + (!cs42l42->ts_inv << CS42L42_TIP_SENSE_INV_SHIFT) | (2 << CS42L42_TIP_SENSE_DEBOUNCE_SHIFT));
/* Save the initial status of the tip sense */ @@ -1733,10 +1736,6 @@ static int cs42l42_handle_device_data(struct device *dev, cs42l42->ts_inv = CS42L42_TS_INV_DIS; }
- regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL, - CS42L42_TS_INV_MASK, - (cs42l42->ts_inv << CS42L42_TS_INV_SHIFT)); - ret = device_property_read_u32(dev, "cirrus,ts-dbnc-rise", &val); if (!ret) { switch (val) {
From: Haoyue Xu xuhaoyue1@hisilicon.com
[ Upstream commit 571fb4fb78a3bf0fcadbe65eca9ca4ccee885af4 ]
We set the init CQ status to ARMED before. As a result, an unexpected CEQE would be reported. Therefore, the init CQ status should be set to no_armed rather than REG_NXT_CEQE.
Fixes: a5073d6054f7 ("RDMA/hns: Add eq support of hip08") Link: https://lore.kernel.org/r/20211029095846.26732-1-liangwenpeng@huawei.com Signed-off-by: Haoyue Xu xuhaoyue1@hisilicon.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index d5f3faa1627a4..8e5f0862896ee 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -3328,7 +3328,7 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev, memset(cq_context, 0, sizeof(*cq_context));
hr_reg_write(cq_context, CQC_CQ_ST, V2_CQ_STATE_VALID); - hr_reg_write(cq_context, CQC_ARM_ST, REG_NXT_CEQE); + hr_reg_write(cq_context, CQC_ARM_ST, NO_ARMED); hr_reg_write(cq_context, CQC_SHIFT, ilog2(hr_cq->cq_depth)); hr_reg_write(cq_context, CQC_CEQN, hr_cq->vector); hr_reg_write(cq_context, CQC_CQN, hr_cq->cqn);
From: Yixing Liu liuyixing1@huawei.com
[ Upstream commit 0e60778efb072d47efc7100c4009b5bd97273b0b ]
The upper limit of MAX_LP_MSG_LEN on HIP08 is 64K, and the upper limit on HIP09 is 16K. Regardless of whether it is HIP08 or HIP09, only 16K will be used. In order to ensure compatibility, it is unified to 16K.
Setting MAX_LP_MSG_LEN to 16K will not cause performance loss on HIP08.
Fixes: fbed9d2be292 ("RDMA/hns: Fix configuration of ack_req_freq in QPC") Link: https://lore.kernel.org/r/20211029100537.27299-1-liangwenpeng@huawei.com Signed-off-by: Yixing Liu liuyixing1@huawei.com Signed-off-by: Wenpeng Liang liangwenpeng@huawei.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 8e5f0862896ee..a9c6ffef9640f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -4399,8 +4399,8 @@ static int modify_qp_init_to_rtr(struct ib_qp *ibqp, mtu = ib_mtu_enum_to_int(ib_mtu); if (WARN_ON(mtu <= 0)) return -EINVAL; -#define MAX_LP_MSG_LEN 65536 - /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 64KB */ +#define MAX_LP_MSG_LEN 16384 + /* MTU * (2 ^ LP_PKTN_INI) shouldn't be bigger than 16KB */ lp_pktn_ini = ilog2(MAX_LP_MSG_LEN / mtu); if (WARN_ON(lp_pktn_ini >= 0xF)) return -EINVAL;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 173632358fde7a567f28e07c4549b959ee857986 ]
If we return before the end of the 'for_each_child_of_node()' iterator, the reference taken on 'np' must be released.
Add the missing 'of_node_put()' call.
Fixes: c413983eb66a ("ASoC: rsnd: adjust disabled module") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/4c0e893cbfa21dc76c1ede0b6f4f8cff42209299.163458616... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/sh/rcar/core.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 978bd0406729a..6a8fe0da7670b 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1225,6 +1225,7 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name if (i < 0) { dev_err(dev, "strange node numbering (%s)", of_node_full_name(node)); + of_node_put(np); return 0; } i++;
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit d142585bceb3218ad432ed0fcd5be9d6e3cd9052 ]
If CONFIG_CONSOLE_POLL=y, and CONFIG_SERIAL_CPM=m (hence CONFIG_SERIAL_CPM_CONSOLE=n):
drivers/tty/serial/cpm_uart/cpm_uart_core.c:1109:12: warning: ‘udbg_cpm_getc’ defined but not used [-Wunused-function] 1109 | static int udbg_cpm_getc(void) | ^~~~~~~~~~~~~ drivers/tty/serial/cpm_uart/cpm_uart_core.c:1095:13: warning: ‘udbg_cpm_putc’ defined but not used [-Wunused-function] 1095 | static void udbg_cpm_putc(char c) | ^~~~~~~~~~~~~
Fix this by making the udbg definitions depend on CONFIG_SERIAL_CPM_CONSOLE, in addition to CONFIG_CONSOLE_POLL.
Fixes: a60526097f42eb98 ("tty: serial: cpm_uart: Add udbg support for enabling xmon") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Link: https://lore.kernel.org/r/20211027075326.3270785-1-geert@linux-m68k.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/cpm_uart/cpm_uart_core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index c719aa2b18328..d6d3db9c3b1f8 100644 --- a/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1090,6 +1090,7 @@ static void cpm_put_poll_char(struct uart_port *port, cpm_uart_early_write(pinfo, ch, 1, false); }
+#ifdef CONFIG_SERIAL_CPM_CONSOLE static struct uart_port *udbg_port;
static void udbg_cpm_putc(char c) @@ -1114,6 +1115,7 @@ static int udbg_cpm_getc(void) cpu_relax(); return c; } +#endif /* CONFIG_SERIAL_CPM_CONSOLE */
#endif /* CONFIG_CONSOLE_POLL */
From: Xuan Zhuo xuanzhuo@linux.alibaba.com
[ Upstream commit fc6d70f40b3d0b3219e2026d05be0409695f620d ]
When using indirect with packed, we don't check for allocation failures. This patch checks that and fall back on direct.
Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") Signed-off-by: Xuan Zhuo xuanzhuo@linux.alibaba.com Link: https://lore.kernel.org/r/20211020112323.67466-3-xuanzhuo@linux.alibaba.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/virtio/virtio_ring.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 3035bb6f54585..d1f47327f6cfe 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1065,6 +1065,8 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq,
head = vq->packed.next_avail_idx; desc = alloc_indirect_packed(total_sg, gfp); + if (!desc) + return -ENOMEM;
if (unlikely(vq->vq.num_free < 1)) { pr_debug("Can't add buf len 1 - avail = 0\n"); @@ -1176,6 +1178,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, unsigned int i, n, c, descs_used, err_idx; __le16 head_flags, flags; u16 head, id, prev, curr, avail_used_flags; + int err;
START_USE(vq);
@@ -1191,9 +1194,14 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq,
BUG_ON(total_sg == 0);
- if (virtqueue_use_indirect(_vq, total_sg)) - return virtqueue_add_indirect_packed(vq, sgs, total_sg, - out_sgs, in_sgs, data, gfp); + if (virtqueue_use_indirect(_vq, total_sg)) { + err = virtqueue_add_indirect_packed(vq, sgs, total_sg, out_sgs, + in_sgs, data, gfp); + if (err != -ENOMEM) + return err; + + /* fall back on direct */ + }
head = vq->packed.next_avail_idx; avail_used_flags = vq->packed.avail_used_flags;
From: Parav Pandit parav@nvidia.com
[ Upstream commit ef76eb83a17e803a66b64ac95b36ae48b3d17c22 ]
Cited patch in the fixes tag clears the features bit during reset. mlx5 vdpa device feature bits are static decided by device capabilities. These feature bits (including VIRTIO_NET_F_MAC) are initialized during device addition time.
Clearing features bit in reset callback cleared the VIRTIO_NET_F_MAC. Due to this, MAC address provided by the device is not honored.
Fix it by not clearing the static feature bits during reset.
Fixes: 0686082dbf7a ("vdpa: Add reset callback in vdpa_config_ops") Signed-off-by: Parav Pandit parav@nvidia.com Reviewed-by: Eli Cohen elic@nvidia.com Link: https://lore.kernel.org/r/20211026175519.87795-7-parav@nvidia.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Acked-by: Jason Wang jasowang@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vdpa/mlx5/net/mlx5_vnet.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index bd56de7484dcb..ae85d2dd6eb76 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -2192,7 +2192,6 @@ static int mlx5_vdpa_reset(struct vdpa_device *vdev) clear_vqs_ready(ndev); mlx5_vdpa_destroy_mr(&ndev->mvdev); ndev->mvdev.status = 0; - ndev->mvdev.mlx_features = 0; memset(ndev->event_cbs, 0, sizeof(ndev->event_cbs)); ndev->mvdev.actual_features = 0; ++mvdev->generation;
From: Geert Uytterhoeven geert+renesas@glider.be
[ Upstream commit 18b8f5b6fc53d097cadb94a93d8d6566ba88e389 ]
mips_cm_error_report() extracts the cause and other cause from the error register using shifts. This works fine for the former, as it is stored in the top bits, and the shift will thus remove all non-related bits. However, the latter is stored in the bottom bits, hence thus needs masking to get rid of non-related bits. Without such masking, using it as an index into the cm2_causes[] array will lead to an out-of-bounds access, probably causing a crash.
Fix this by using FIELD_GET() instead. Bite the bullet and convert all MIPS CM handling to the bitfield API, to improve readability and safety.
Fixes: 3885c2b463f6a236 ("MIPS: CM: Add support for reporting CM cache errors") Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Jiaxun Yang jiaxun.yang@flygoat.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/mips-cm.h | 12 ++++++------ arch/mips/kernel/mips-cm.c | 21 ++++++++++----------- 2 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index aeae2effa123d..23c67c0871b17 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -11,6 +11,7 @@ #ifndef __MIPS_ASM_MIPS_CM_H__ #define __MIPS_ASM_MIPS_CM_H__
+#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/errno.h>
@@ -153,8 +154,8 @@ GCR_ACCESSOR_RO(32, 0x030, rev) #define CM_GCR_REV_MINOR GENMASK(7, 0)
#define CM_ENCODE_REV(major, minor) \ - (((major) << __ffs(CM_GCR_REV_MAJOR)) | \ - ((minor) << __ffs(CM_GCR_REV_MINOR))) + (FIELD_PREP(CM_GCR_REV_MAJOR, major) | \ + FIELD_PREP(CM_GCR_REV_MINOR, minor))
#define CM_REV_CM2 CM_ENCODE_REV(6, 0) #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) @@ -362,10 +363,10 @@ static inline int mips_cm_revision(void) static inline unsigned int mips_cm_max_vp_width(void) { extern int smp_num_siblings; - uint32_t cfg;
if (mips_cm_revision() >= CM_REV_CM3) - return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW; + return FIELD_GET(CM_GCR_SYS_CONFIG2_MAXVPW, + read_gcr_sys_config2());
if (mips_cm_present()) { /* @@ -373,8 +374,7 @@ static inline unsigned int mips_cm_max_vp_width(void) * number of VP(E)s, and if that ever changes then this will * need revisiting. */ - cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE; - return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1; + return FIELD_GET(CM_GCR_Cx_CONFIG_PVPE, read_gcr_cl_config()) + 1; }
if (IS_ENABLED(CONFIG_SMP)) diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 90f1c3df1f0e4..b4f7d950c8468 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -221,8 +221,7 @@ static void mips_cm_probe_l2sync(void) phys_addr_t addr;
/* L2-only sync was introduced with CM major revision 6 */ - major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >> - __ffs(CM_GCR_REV_MAJOR); + major_rev = FIELD_GET(CM_GCR_REV_MAJOR, read_gcr_rev()); if (major_rev < 6) return;
@@ -306,13 +305,13 @@ void mips_cm_lock_other(unsigned int cluster, unsigned int core, preempt_disable();
if (cm_rev >= CM_REV_CM3) { - val = core << __ffs(CM3_GCR_Cx_OTHER_CORE); - val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP); + val = FIELD_PREP(CM3_GCR_Cx_OTHER_CORE, core) | + FIELD_PREP(CM3_GCR_Cx_OTHER_VP, vp);
if (cm_rev >= CM_REV_CM3_5) { val |= CM_GCR_Cx_OTHER_CLUSTER_EN; - val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER); - val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK); + val |= FIELD_PREP(CM_GCR_Cx_OTHER_CLUSTER, cluster); + val |= FIELD_PREP(CM_GCR_Cx_OTHER_BLOCK, block); } else { WARN_ON(cluster != 0); WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); @@ -342,7 +341,7 @@ void mips_cm_lock_other(unsigned int cluster, unsigned int core, spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core));
- val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM); + val = FIELD_PREP(CM_GCR_Cx_OTHER_CORENUM, core); }
write_gcr_cl_other(val); @@ -386,8 +385,8 @@ void mips_cm_error_report(void) cm_other = read_gcr_error_mult();
if (revision < CM_REV_CM3) { /* CM2 */ - cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE); - ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); + cause = FIELD_GET(CM_GCR_ERROR_CAUSE_ERRTYPE, cm_error); + ocause = FIELD_GET(CM_GCR_ERROR_MULT_ERR2ND, cm_other);
if (!cause) return; @@ -445,8 +444,8 @@ void mips_cm_error_report(void) ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit;
- cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE); - ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); + cause = FIELD_GET(CM3_GCR_ERROR_CAUSE_ERRTYPE, cm_error); + ocause = FIELD_GET(CM_GCR_ERROR_MULT_ERR2ND, cm_other);
if (!cause) return;
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit cdf10ffe8f626d8a2edc354abf063df0078b2d71 ]
When registering the IRQ handler fails, do not just return the error code, this will free the devm_kzalloc()-ed data struct while leaving the queued work queued and the registered power_supply registered with both of them now pointing to free-ed memory, resulting in various kernel crashes soon afterwards.
Instead properly tear-down things on IRQ handler register errors.
Fixes: 703df6c09795 ("power: bq27xxx_battery: Reorganize I2C into a module") Cc: Andrew F. Davis afd@ti.com Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Andy Shevchenko andy.shevchenko@gmail.com Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/power/supply/bq27xxx_battery_i2c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/bq27xxx_battery_i2c.c b/drivers/power/supply/bq27xxx_battery_i2c.c index 46f078350fd3f..cf38cbfe13e9d 100644 --- a/drivers/power/supply/bq27xxx_battery_i2c.c +++ b/drivers/power/supply/bq27xxx_battery_i2c.c @@ -187,7 +187,8 @@ static int bq27xxx_battery_i2c_probe(struct i2c_client *client, dev_err(&client->dev, "Unable to register IRQ %d error %d\n", client->irq, ret); - return ret; + bq27xxx_battery_teardown(di); + goto err_failed; } }
From: Aharon Landau aharonl@nvidia.com
[ Upstream commit f1a090f09f42be5a5542009f0be310fdb3e768fc ]
If the driver returns a new MR during rereg it has to fill it with the IOVA from the proper source. If IB_MR_REREG_TRANS is set then the IOVA is cmd.hca_va, otherwise the IOVA comes from the old MR. mlx5 for example has two calls inside rereg_mr:
return create_real_mr(new_pd, umem, mr->ibmr.iova, new_access_flags); and return create_real_mr(new_pd, new_umem, iova, new_access_flags);
Unconditionally overwriting the iova in the newly allocated MR will corrupt the iova if the first path is used.
Remove the redundant initializations from ib_uverbs_rereg_mr().
Fixes: 6e0954b11c05 ("RDMA/uverbs: Allow drivers to create a new HW object during rereg_mr") Link: https://lore.kernel.org/r/4b0a31bbc372842613286a10d7a8cbb0ee6069c7.163540047... Signed-off-by: Aharon Landau aharonl@nvidia.com Signed-off-by: Leon Romanovsky leonro@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/core/uverbs_cmd.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 740e6b2efe0e7..d1345d76d9b12 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -837,11 +837,8 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) new_mr->device = new_pd->device; new_mr->pd = new_pd; new_mr->type = IB_MR_TYPE_USER; - new_mr->dm = NULL; - new_mr->sig_attrs = NULL; new_mr->uobject = uobj; atomic_inc(&new_pd->usecnt); - new_mr->iova = cmd.hca_va; new_uobj->object = new_mr;
rdma_restrack_new(&new_mr->res, RDMA_RESTRACK_MR);
From: Tom Rix trix@redhat.com
[ Upstream commit d108370c644b153382632b3e5511ade575c91c86 ]
clang static analysis reports this representative problem:
label.c:1463:16: warning: Assigned value is garbage or undefined label->hname = name; ^ ~~~~
In aa_update_label_name(), this the problem block of code
if (aa_label_acntsxprint(&name, ...) == -1) return res;
On failure, aa_label_acntsxprint() has a more complicated return that just -1. So check for a negative return.
It was also noted that the aa_label_acntsxprint() main comment refers to a nonexistent parameter, so clean up the comment.
Fixes: f1bd904175e8 ("apparmor: add the base fns() for domain labels") Signed-off-by: Tom Rix trix@redhat.com Reviewed-by: Nick Desaulniers ndesaulniers@google.com Signed-off-by: John Johansen john.johansen@canonical.com Signed-off-by: Sasha Levin sashal@kernel.org --- security/apparmor/label.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/security/apparmor/label.c b/security/apparmor/label.c index e68bcedca976b..6222fdfebe4e5 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -1454,7 +1454,7 @@ bool aa_update_label_name(struct aa_ns *ns, struct aa_label *label, gfp_t gfp) if (label->hname || labels_ns(label) != ns) return res;
- if (aa_label_acntsxprint(&name, ns, label, FLAGS_NONE, gfp) == -1) + if (aa_label_acntsxprint(&name, ns, label, FLAGS_NONE, gfp) < 0) return res;
ls = labels_set(label); @@ -1704,7 +1704,7 @@ int aa_label_asxprint(char **strp, struct aa_ns *ns, struct aa_label *label,
/** * aa_label_acntsxprint - allocate a __counted string buffer and print label - * @strp: buffer to write to. (MAY BE NULL if @size == 0) + * @strp: buffer to write to. * @ns: namespace profile is being viewed from * @label: label to view (NOT NULL) * @flags: flags controlling what label info is printed
From: Arnaud Pouliquen arnaud.pouliquen@foss.st.com
[ Upstream commit 537d3af1bee8ad1415fda9b622d1ea6d1ae76dfa ]
According to the description of the rpmsg_create_ept in rpmsg_core.c the function should return NULL on error.
Fixes: 2c8a57088045 ("rpmsg: Provide function stubs for API") Signed-off-by: Arnaud Pouliquen arnaud.pouliquen@foss.st.com Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org Link: https://lore.kernel.org/r/20210712123912.10672-1-arnaud.pouliquen@foss.st.co... Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/rpmsg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index d97dcd049f18f..a8dcf8a9ae885 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h @@ -231,7 +231,7 @@ static inline struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_device *rpdev /* This shouldn't be possible */ WARN_ON(1);
- return ERR_PTR(-ENXIO); + return NULL; }
static inline int rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len)
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 46a0dc10fb32bec3e765e51bf71fbc070dc77ca3 ]
ebu_nand_probe() read the value of u32 variable "cs" from the device firmware description and used it as the index for array ebu_host->cs that can contain MAX_CS (2) elements at most. That could result in a buffer overflow and various bad consequences later.
Fix the potential buffer overflow by restricting values of "cs" with MAX_CS in probe.
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC") Signed-off-by: Evgeny Novikov novikov@ispras.ru Co-developed-by: Kirill Shilimanov kirill.shilimanov@huawei.com Signed-off-by: Kirill Shilimanov kirill.shilimanov@huawei.com Co-developed-by: Anton Vasilyev vasilyev@ispras.ru Signed-off-by: Anton Vasilyev vasilyev@ispras.ru Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210903082653.16441-1-novikov@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/raw/intel-nand-controller.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c index b9784f3da7a11..7c1c80dae826a 100644 --- a/drivers/mtd/nand/raw/intel-nand-controller.c +++ b/drivers/mtd/nand/raw/intel-nand-controller.c @@ -609,6 +609,11 @@ static int ebu_nand_probe(struct platform_device *pdev) dev_err(dev, "failed to get chip select: %d\n", ret); return ret; } + if (cs >= MAX_CS) { + dev_err(dev, "got invalid chip select: %d\n", cs); + return -EINVAL; + } + ebu_host->cs_num = cs;
resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
From: J. Bruce Fields bfields@redhat.com
[ Upstream commit 9b6e27d01adcec58e046c624874f8a124e8b07ec ]
Dan Carpenter says:
The patch d20c11d86d8f: "nfsd: Protect session creation and client confirm using client_lock" from Jul 30, 2014, leads to the following Smatch static checker warning:
net/sunrpc/addr.c:178 rpc_parse_scope_id() warn: sleeping in atomic context
Reported-by: Dan Carpenter dan.carpenter@oracle.com Fixes: d20c11d86d8f ("nfsd: Protect session creation and client...") Signed-off-by: J. Bruce Fields bfields@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/addr.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 6e4dbd577a39f..d435bffc61999 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c @@ -162,8 +162,10 @@ static int rpc_parse_scope_id(struct net *net, const char *buf, const size_t buflen, const char *delim, struct sockaddr_in6 *sin6) { - char *p; + char p[IPV6_SCOPE_ID_LEN + 1]; size_t len; + u32 scope_id = 0; + struct net_device *dev;
if ((buf + buflen) == delim) return 1; @@ -175,29 +177,23 @@ static int rpc_parse_scope_id(struct net *net, const char *buf, return 0;
len = (buf + buflen) - delim - 1; - p = kmemdup_nul(delim + 1, len, GFP_KERNEL); - if (p) { - u32 scope_id = 0; - struct net_device *dev; - - dev = dev_get_by_name(net, p); - if (dev != NULL) { - scope_id = dev->ifindex; - dev_put(dev); - } else { - if (kstrtou32(p, 10, &scope_id) != 0) { - kfree(p); - return 0; - } - } - - kfree(p); - - sin6->sin6_scope_id = scope_id; - return 1; + if (len > IPV6_SCOPE_ID_LEN) + return 0; + + memcpy(p, delim + 1, len); + p[len] = 0; + + dev = dev_get_by_name(net, p); + if (dev != NULL) { + scope_id = dev->ifindex; + dev_put(dev); + } else { + if (kstrtou32(p, 10, &scope_id) != 0) + return 0; }
- return 0; + sin6->sin6_scope_id = scope_id; + return 1; }
static size_t rpc_pton6(struct net *net, const char *buf, const size_t buflen,
From: Mark Brown broonie@kernel.org
[ Upstream commit 8719a17613e0233d707eb22e1645d217594631ef ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210923194922.53386-2-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-ds1302.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index b3de6d2e680a4..2f83adef966eb 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -199,11 +199,18 @@ static const struct of_device_id ds1302_dt_ids[] = { MODULE_DEVICE_TABLE(of, ds1302_dt_ids); #endif
+static const struct spi_device_id ds1302_spi_ids[] = { + { .name = "ds1302", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, ds1302_spi_ids); + static struct spi_driver ds1302_driver = { .driver.name = "rtc-ds1302", .driver.of_match_table = of_match_ptr(ds1302_dt_ids), .probe = ds1302_probe, .remove = ds1302_remove, + .id_table = ds1302_spi_ids, };
module_spi_driver(ds1302_driver);
From: Mark Brown broonie@kernel.org
[ Upstream commit da87639d6312afb8855717c791768bf2d4ca8ac8 ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210923194922.53386-3-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-ds1390.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index 66fc8617d07ee..93ce72b9ae59e 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -219,12 +219,19 @@ static const struct of_device_id ds1390_of_match[] = { }; MODULE_DEVICE_TABLE(of, ds1390_of_match);
+static const struct spi_device_id ds1390_spi_ids[] = { + { .name = "ds1390" }, + {} +}; +MODULE_DEVICE_TABLE(spi, ds1390_spi_ids); + static struct spi_driver ds1390_driver = { .driver = { .name = "rtc-ds1390", .of_match_table = of_match_ptr(ds1390_of_match), }, .probe = ds1390_probe, + .id_table = ds1390_spi_ids, };
module_spi_driver(ds1390_driver);
From: Mark Brown broonie@kernel.org
[ Upstream commit 5f84478e14aa8b43a4ea85d2e091931741947749 ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210923194922.53386-4-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-pcf2123.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 0f58cac81d8c0..7473e6c8a183b 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -451,12 +451,21 @@ static const struct of_device_id pcf2123_dt_ids[] = { MODULE_DEVICE_TABLE(of, pcf2123_dt_ids); #endif
+static const struct spi_device_id pcf2123_spi_ids[] = { + { .name = "pcf2123", }, + { .name = "rv2123", }, + { .name = "rtc-pcf2123", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(spi, pcf2123_spi_ids); + static struct spi_driver pcf2123_driver = { .driver = { .name = "rtc-pcf2123", .of_match_table = of_match_ptr(pcf2123_dt_ids), }, .probe = pcf2123_probe, + .id_table = pcf2123_spi_ids, };
module_spi_driver(pcf2123_driver);
From: Dong Aisheng aisheng.dong@nxp.com
[ Upstream commit 91bb26637353f35241f5472eedf3202ebe13e2e5 ]
is_iomem was introduced in the commit 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va"), but the driver seemed missed to provide the io type correctly. This patch updates remoteproc driver to indicate the TCM on IMX are io memories. Without the change, remoteproc kick will fail.
Cc: Bjorn Andersson bjorn.andersson@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Cc: Peng Fan peng.fan@nxp.com Reviewed-and-tested-by: Peng Fan peng.fan@nxp.com Fixes: 79806d32d5aa ("remoteproc: imx_rproc: support i.MX8MN/P") Signed-off-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210910090621.3073540-4-peng.fan@oss.nxp.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/imx_rproc.c | 35 ++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index d88f76f5305eb..71dcc6dd32e40 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -71,6 +71,7 @@ struct imx_rproc_mem { /* att flags */ /* M4 own area. Can be mapped at probe */ #define ATT_OWN BIT(1) +#define ATT_IOMEM BIT(2)
/* address translation table */ struct imx_rproc_att { @@ -117,7 +118,7 @@ struct imx_rproc { static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { /* dev addr , sys addr , size , flags */ /* ITCM */ - { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN }, + { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM }, /* OCRAM_S */ { 0x00180000, 0x00180000, 0x00009000, 0 }, /* OCRAM */ @@ -131,7 +132,7 @@ static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { /* DDR (Code) - alias */ { 0x10000000, 0x40000000, 0x0FFE0000, 0 }, /* DTCM */ - { 0x20000000, 0x00800000, 0x00020000, ATT_OWN }, + { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM }, /* OCRAM_S - alias */ { 0x20180000, 0x00180000, 0x00008000, ATT_OWN }, /* OCRAM */ @@ -147,7 +148,7 @@ static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { static const struct imx_rproc_att imx_rproc_att_imx8mq[] = { /* dev addr , sys addr , size , flags */ /* TCML - alias */ - { 0x00000000, 0x007e0000, 0x00020000, 0 }, + { 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM}, /* OCRAM_S */ { 0x00180000, 0x00180000, 0x00008000, 0 }, /* OCRAM */ @@ -159,9 +160,9 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = { /* DDR (Code) - alias */ { 0x10000000, 0x80000000, 0x0FFE0000, 0 }, /* TCML */ - { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN }, + { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM}, /* TCMU */ - { 0x20000000, 0x00800000, 0x00020000, ATT_OWN }, + { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM}, /* OCRAM_S */ { 0x20180000, 0x00180000, 0x00008000, ATT_OWN }, /* OCRAM */ @@ -199,12 +200,12 @@ static const struct imx_rproc_att imx_rproc_att_imx7d[] = { /* OCRAM_PXP (Code) - alias */ { 0x00940000, 0x00940000, 0x00008000, 0 }, /* TCML (Code) */ - { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN }, + { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM }, /* DDR (Code) - alias, first part of DDR (Data) */ { 0x10000000, 0x80000000, 0x0FFF0000, 0 },
/* TCMU (Data) */ - { 0x20000000, 0x00800000, 0x00008000, ATT_OWN }, + { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM }, /* OCRAM (Data) */ { 0x20200000, 0x00900000, 0x00020000, 0 }, /* OCRAM_EPDC (Data) */ @@ -218,18 +219,18 @@ static const struct imx_rproc_att imx_rproc_att_imx7d[] = { static const struct imx_rproc_att imx_rproc_att_imx6sx[] = { /* dev addr , sys addr , size , flags */ /* TCML (M4 Boot Code) - alias */ - { 0x00000000, 0x007F8000, 0x00008000, 0 }, + { 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM }, /* OCRAM_S (Code) */ { 0x00180000, 0x008F8000, 0x00004000, 0 }, /* OCRAM_S (Code) - alias */ { 0x00180000, 0x008FC000, 0x00004000, 0 }, /* TCML (Code) */ - { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN }, + { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM }, /* DDR (Code) - alias, first part of DDR (Data) */ { 0x10000000, 0x80000000, 0x0FFF8000, 0 },
/* TCMU (Data) */ - { 0x20000000, 0x00800000, 0x00008000, ATT_OWN }, + { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM }, /* OCRAM_S (Data) - alias? */ { 0x208F8000, 0x008F8000, 0x00004000, 0 }, /* DDR (Data) */ @@ -341,7 +342,7 @@ static int imx_rproc_stop(struct rproc *rproc) }
static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da, - size_t len, u64 *sys) + size_t len, u64 *sys, bool *is_iomem) { const struct imx_rproc_dcfg *dcfg = priv->dcfg; int i; @@ -354,6 +355,8 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da, unsigned int offset = da - att->da;
*sys = att->sa + offset; + if (is_iomem) + *is_iomem = att->flags & ATT_IOMEM; return 0; } } @@ -377,7 +380,7 @@ static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *i * On device side we have many aliases, so we need to convert device * address (M4) to system bus address first. */ - if (imx_rproc_da_to_sys(priv, da, len, &sys)) + if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem)) return NULL;
for (i = 0; i < IMX_RPROC_MEM_MAX; i++) { @@ -553,8 +556,12 @@ static int imx_rproc_addr_init(struct imx_rproc *priv, if (b >= IMX_RPROC_MEM_MAX) break;
- priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, - att->sa, att->size); + if (att->flags & ATT_IOMEM) + priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, + att->sa, att->size); + else + priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, + att->sa, att->size); if (!priv->mem[b].cpu_addr) { dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa); return -ENOMEM;
From: Heiner Kallweit hkallweit1@gmail.com
[ Upstream commit 7d6b61c394a42b8385858bb9e306d48a0112823c ]
As pointed out by Andy in [0] using a local mutex here isn't strictly wrong but not sufficient. We should hold the PCI rescan lock for P2SB operations.
[0] https://www.spinics.net/lists/linux-i2c/msg52717.html
Fixes: 1a987c69ce2c ("i2c: i801: make p2sb_spinlock a mutex") Reported-by: Andy Shevchenko andriy.shevchenko@intel.com Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Reviewed-by: Andy Shevchenko andriy.shevchenko@intel.com Reviewed-by: Jean Delvare jdelvare@suse.de Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-i801.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 89ae78ef1a1cc..1f929e6c30bea 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -1493,7 +1493,6 @@ static struct platform_device * i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, struct resource *tco_res) { - static DEFINE_MUTEX(p2sb_mutex); struct resource *res; unsigned int devfn; u64 base64_addr; @@ -1506,7 +1505,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, * enumerated by the PCI subsystem, so we need to unhide/hide it * to lookup the P2SB BAR. */ - mutex_lock(&p2sb_mutex); + pci_lock_rescan_remove();
devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 1);
@@ -1524,7 +1523,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, /* Hide the P2SB device, if it was hidden before */ if (hidden) pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); - mutex_unlock(&p2sb_mutex); + pci_unlock_rescan_remove();
res = &tco_res[1]; if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS)
From: Dave Jiang dave.jiang@intel.com
[ Upstream commit 85f604af9c83a4656b1d07bec73298c3ba7d7c1e ]
percpu_ref_tryget_live() is safe to call as long as ref is between init and exit according to the function comment. Move percpu_ref_exit() so it is called after the dma channel is no longer valid to ensure this holds true.
Fixes: 93a40a6d7428 ("dmaengine: idxd: add percpu_ref to descriptor submission path") Suggested-by: Kevin Tian kevin.tian@intel.com Signed-off-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/163294293832.914350.10326422026738506152.stgit@dji... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/idxd/device.c | 1 - drivers/dma/idxd/dma.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 83a5ff2ecf2a0..cbbfa17d8d11b 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -427,7 +427,6 @@ void idxd_wq_quiesce(struct idxd_wq *wq) { percpu_ref_kill(&wq->wq_active); wait_for_completion(&wq->wq_dead); - percpu_ref_exit(&wq->wq_active); }
/* Device control bits */ diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index e0f056c1d1f56..b90b085d18cff 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -311,6 +311,7 @@ static int idxd_dmaengine_drv_probe(struct idxd_dev *idxd_dev)
err_dma: idxd_wq_quiesce(wq); + percpu_ref_exit(&wq->wq_active); err_ref: idxd_wq_free_resources(wq); err_res_alloc: @@ -329,6 +330,7 @@ static void idxd_dmaengine_drv_remove(struct idxd_dev *idxd_dev) idxd_wq_quiesce(wq); idxd_unregister_dma_channel(wq); __drv_disable_wq(wq); + percpu_ref_exit(&wq->wq_active); idxd_wq_free_resources(wq); wq->type = IDXD_WQT_NONE; mutex_unlock(&wq->wq_lock);
From: Mark Brown broonie@kernel.org
[ Upstream commit 3109151c47343c80300177ec7704e0757064efdc ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding an id_table listing the SPI IDs for everything.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20210927130240.33693-1-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-mcp795.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c index bad7792b6ca58..0d515b3df5710 100644 --- a/drivers/rtc/rtc-mcp795.c +++ b/drivers/rtc/rtc-mcp795.c @@ -430,12 +430,19 @@ static const struct of_device_id mcp795_of_match[] = { MODULE_DEVICE_TABLE(of, mcp795_of_match); #endif
+static const struct spi_device_id mcp795_spi_ids[] = { + { .name = "mcp795" }, + { } +}; +MODULE_DEVICE_TABLE(spi, mcp795_spi_ids); + static struct spi_driver mcp795_driver = { .driver = { .name = "rtc-mcp795", .of_match_table = of_match_ptr(mcp795_of_match), }, .probe = mcp795_probe, + .id_table = mcp795_spi_ids, };
module_spi_driver(mcp795_driver);
From: Mark Brown broonie@kernel.org
[ Upstream commit 5c4c2c8e6fac26fa0b80c234d6e9f75d637193af ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding a SPI device ID table.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Link: https://lore.kernel.org/r/20210927134104.38648-1-broonie@kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/misc/ariel-pwrbutton.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/input/misc/ariel-pwrbutton.c b/drivers/input/misc/ariel-pwrbutton.c index 17bbaac8b80c8..cdc80715b5fd6 100644 --- a/drivers/input/misc/ariel-pwrbutton.c +++ b/drivers/input/misc/ariel-pwrbutton.c @@ -149,12 +149,19 @@ static const struct of_device_id ariel_pwrbutton_of_match[] = { }; MODULE_DEVICE_TABLE(of, ariel_pwrbutton_of_match);
+static const struct spi_device_id ariel_pwrbutton_spi_ids[] = { + { .name = "wyse-ariel-ec-input" }, + { } +}; +MODULE_DEVICE_TABLE(spi, ariel_pwrbutton_spi_ids); + static struct spi_driver ariel_pwrbutton_driver = { .driver = { .name = "dell-wyse-ariel-ec-input", .of_match_table = ariel_pwrbutton_of_match, }, .probe = ariel_pwrbutton_probe, + .id_table = ariel_pwrbutton_spi_ids, }; module_spi_driver(ariel_pwrbutton_driver);
From: Kewei Xu kewei.xu@mediatek.com
[ Upstream commit b8228aea5a19d5111a7bf44f7de6749d1f5d487a ]
The reason for the modification here is that the previous offset information is incorrect, OFFSET_DEBUGSTAT = 0xE4 is the correct value.
Fixes: 25708278f810 ("i2c: mediatek: Add i2c support for MediaTek MT8183") Signed-off-by: Kewei Xu kewei.xu@mediatek.com Reviewed-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Qii Wang qii.wang@mediatek.com Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-mt65xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 7d4b3eb7077ad..72acda59eb399 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -195,7 +195,7 @@ static const u16 mt_i2c_regs_v2[] = { [OFFSET_CLOCK_DIV] = 0x48, [OFFSET_SOFTRESET] = 0x50, [OFFSET_SCL_MIS_COMP_POINT] = 0x90, - [OFFSET_DEBUGSTAT] = 0xe0, + [OFFSET_DEBUGSTAT] = 0xe4, [OFFSET_DEBUGCTRL] = 0xe8, [OFFSET_FIFO_STAT] = 0xf4, [OFFSET_FIFO_THRESH] = 0xf8,
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit eea413308f2e6deb00f061f18081a53f3ecc8cc6 ]
Both NFSv3 and NFSv2 generate their change attribute from the ctime value that was supplied by the server. However the problem is that there are plenty of servers out there with ctime resolutions of 1ms or worse. In a modern performance system, this is insufficient when trying to decide which is the most recent set of attributes when, for instance, a READ or GETATTR call races with a WRITE or SETATTR.
For this reason, let's revert to labelling the NFSv2/v3 change attributes as NFS4_CHANGE_TYPE_IS_UNDEFINED. This will ensure we protect against such races.
Fixes: 7b24dacf0840 ("NFS: Another inode revalidation improvement") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Tested-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 4 +++- fs/nfs/nfs3xdr.c | 2 +- fs/nfs/proc.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 853213b3a2095..6ea1bde33cb62 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1777,8 +1777,10 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr, NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER | NFS_INO_INVALID_NLINK; unsigned long cache_validity = NFS_I(inode)->cache_validity; + enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type;
- if (!(cache_validity & NFS_INO_INVALID_CHANGE) && + if (ctype != NFS4_CHANGE_TYPE_IS_UNDEFINED && + !(cache_validity & NFS_INO_INVALID_CHANGE) && (cache_validity & check_valid) != 0 && (fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && nfs_inode_attrs_cmp_monotonic(fattr, inode) == 0) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index e6eca1d7481b8..9274c9c5efea6 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -2227,7 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr,
/* ignore properties */ result->lease_time = 0; - result->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA; + result->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED; return 0; }
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index ea19dbf123014..ecc4e717808c4 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -91,7 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, info->dtpref = fsinfo.tsize; info->maxfilesize = 0x7FFFFFFF; info->lease_time = 0; - info->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA; + info->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED; return 0; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 488796ec1e39fb9194cc8175f770823d40fbf0ed ]
NFS_INO_DATA_INVAL_DEFER and NFS_INO_INVALID_DATA should be considered mutually exclusive.
Fixes: 1c341b777501 ("NFS: Add deferred cache invalidation for close-to-open consistency violations") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Tested-by: Benjamin Coddington bcodding@redhat.com Reviewed-by: Benjamin Coddington bcodding@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6ea1bde33cb62..f9d3ad3acf114 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -210,10 +210,15 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) flags &= ~NFS_INO_INVALID_XATTR; if (flags & NFS_INO_INVALID_DATA) nfs_fscache_invalidate(inode); - if (inode->i_mapping->nrpages == 0) - flags &= ~(NFS_INO_INVALID_DATA|NFS_INO_DATA_INVAL_DEFER); flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED); + nfsi->cache_validity |= flags; + + if (inode->i_mapping->nrpages == 0) + nfsi->cache_validity &= ~(NFS_INO_INVALID_DATA | + NFS_INO_DATA_INVAL_DEFER); + else if (nfsi->cache_validity & NFS_INO_INVALID_DATA) + nfsi->cache_validity &= ~NFS_INO_DATA_INVAL_DEFER; } EXPORT_SYMBOL_GPL(nfs_set_cache_invalid);
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit a6a361c4ca3cc3e6f3b39d1b6bca1de90f5f4b11 ]
If we want to revalidate the directory, then just mark the change attribute as invalid.
Fixes: 13c0b082b6a9 ("NFS: Replace use of NFS_INO_REVAL_PAGECACHE when checking cache validity") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Tested-by: Benjamin Coddington bcodding@redhat.com Reviewed-by: Benjamin Coddington bcodding@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 1a6d2867fba4f..085b8ecdc17d9 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1413,7 +1413,7 @@ out_force: static void nfs_mark_dir_for_revalidate(struct inode *inode) { spin_lock(&inode->i_lock); - nfs_set_cache_invalid(inode, NFS_INO_REVAL_PAGECACHE); + nfs_set_cache_invalid(inode, NFS_INO_INVALID_CHANGE); spin_unlock(&inode->i_lock); }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit cec08f452a687fce9dfdf47946d00a1d12a8bec5 ]
If the directory changed while we were revalidating the dentry, then don't update the dentry verifier. There is no value in setting the verifier to an older value, and we could end up overwriting a more up to date verifier from a parallel revalidation.
Fixes: efeda80da38d ("NFSv4: Fix revalidation of dentries with delegations") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Tested-by: Benjamin Coddington bcodding@redhat.com Reviewed-by: Benjamin Coddington bcodding@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/dir.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 085b8ecdc17d9..5b68c44848caf 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1269,13 +1269,12 @@ static bool nfs_verifier_is_delegated(struct dentry *dentry) static void nfs_set_verifier_locked(struct dentry *dentry, unsigned long verf) { struct inode *inode = d_inode(dentry); + struct inode *dir = d_inode(dentry->d_parent);
- if (!nfs_verifier_is_delegated(dentry) && - !nfs_verify_change_attribute(d_inode(dentry->d_parent), verf)) - goto out; + if (!nfs_verify_change_attribute(dir, verf)) + return; if (inode && NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) nfs_set_verifier_delegated(&verf); -out: dentry->d_time = verf; }
From: Baptiste Lepers baptiste.lepers@gmail.com
[ Upstream commit a2915fa06227b056a8f9b0d79b61dca08ad5cfc6 ]
_nfs4_pnfs_v3/v4_ds_connect do some work smp_wmb ds->ds_clp = clp;
And nfs4_ff_layout_prepare_ds currently does smp_rmb if(ds->ds_clp) ...
This patch places the smp_rmb after the if. This ensures that following reads only happen once nfs4_ff_layout_prepare_ds has checked that data has been properly initialized.
Fixes: d67ae825a59d6 ("pnfs/flexfiles: Add the FlexFile Layout Driver") Signed-off-by: Baptiste Lepers baptiste.lepers@gmail.com Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 4 ++-- fs/nfs/pnfs_nfs.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index c9b61b818ec11..bfa7202ca7be1 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -378,10 +378,10 @@ nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, goto noconnect;
ds = mirror->mirror_ds->ds; + if (READ_ONCE(ds->ds_clp)) + goto out; /* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */ smp_rmb(); - if (ds->ds_clp) - goto out;
/* FIXME: For now we assume the server sent only one version of NFS * to use for the DS. diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index cf19914fec817..02bd6e83961d9 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -895,7 +895,7 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv, }
smp_wmb(); - ds->ds_clp = clp; + WRITE_ONCE(ds->ds_clp, clp); dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr); out: return status; @@ -973,7 +973,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv, }
smp_wmb(); - ds->ds_clp = clp; + WRITE_ONCE(ds->ds_clp, clp); dprintk("%s [new] addr: %s\n", __func__, ds->ds_remotestr); out: return status;
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 15184965783aab3ca7ee4f939e2598943b3f40f9 ]
- set DRM_CONNECTOR_POLL_HPD as the connector will generate hotplug events on its own
- do not call drm_kms_helper_hotplug_event() unless mode_config.funcs pointer is not NULL to remove possible kernel oops.
Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler") Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Robert Foss robert.foss@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20210708230329.395976-1-dmitry... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 3cac16db970f0..010657ea7af78 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -167,9 +167,10 @@ static void lt9611uxc_hpd_work(struct work_struct *work) struct lt9611uxc *lt9611uxc = container_of(work, struct lt9611uxc, work); bool connected;
- if (lt9611uxc->connector.dev) - drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); - else { + if (lt9611uxc->connector.dev) { + if (lt9611uxc->connector.dev->mode_config.funcs) + drm_kms_helper_hotplug_event(lt9611uxc->connector.dev); + } else {
mutex_lock(<9611uxc->ocm_lock); connected = lt9611uxc->hdmi_connected; @@ -339,6 +340,8 @@ static int lt9611uxc_connector_init(struct drm_bridge *bridge, struct lt9611uxc return -ENODEV; }
+ lt9611uxc->connector.polled = DRM_CONNECTOR_POLL_HPD; + drm_connector_helper_add(<9611uxc->connector, <9611uxc_bridge_connector_helper_funcs); ret = drm_connector_init(bridge->dev, <9611uxc->connector,
From: Alex Xu (Hello71) alex_y_xu@yahoo.ca
[ Upstream commit 7be28bd73f23e53d6e7f5fe891ba9503fc0c7210 ]
drivers/gpu/drm/drm_plane_helper.c: In function 'drm_primary_helper_update': drivers/gpu/drm/drm_plane_helper.c:113:32: error: 'visible' is used uninitialized [-Werror=uninitialized] 113 | struct drm_plane_state plane_state = { | ^~~~~~~~~~~ drivers/gpu/drm/drm_plane_helper.c:178:14: note: 'visible' was declared here 178 | bool visible; | ^~~~~~~ cc1: all warnings being treated as errors
visible is an output, not an input. in practice this use might turn out OK but it's still UB.
Fixes: df86af9133b4 ("drm/plane-helper: Add drm_plane_helper_check_state()") Reviewed-by: Simon Ser contact@emersion.fr Signed-off-by: Alex Xu (Hello71) alex_y_xu@yahoo.ca Signed-off-by: Simon Ser contact@emersion.fr Link: https://patchwork.freedesktop.org/patch/msgid/20211007063706.305984-1-alex_y... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_plane_helper.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 5b2d0ca03705c..838b32b70bce6 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -123,7 +123,6 @@ static int drm_plane_helper_check_update(struct drm_plane *plane, .crtc_w = drm_rect_width(dst), .crtc_h = drm_rect_height(dst), .rotation = rotation, - .visible = *visible, }; struct drm_crtc_state crtc_state = { .crtc = crtc,
From: Marek Behún kabel@kernel.org
[ Upstream commit 464de7e7fff767e87429cd7be09c4f2cb50a6ccb ]
Use dev_dbg() instead of dev_err() in advk_pcie_check_pio_status().
For example CRS is not an error status, it just says that the request should be retried.
Link: https://lore.kernel.org/r/20211005180952.6812-4-kabel@kernel.org Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver") Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pci-aardvark.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 0dd42435e7289..589ddb4c50100 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -778,7 +778,7 @@ static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u3 else str_posted = "Posted";
- dev_err(dev, "%s PIO Response Status: %s, %#x @ %#x\n", + dev_dbg(dev, "%s PIO Response Status: %s, %#x @ %#x\n", str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS));
return -EFAULT;
From: Pali Rohár pali@kernel.org
[ Upstream commit d419052bc6c60fa4ab2b5a51d5f1e55a66e2b4ff ]
Commit 43f5c77bcbd2 ("PCI: aardvark: Fix reporting CRS value") started using CRSSVE flag for handling CRS responses.
PCI_EXP_RTCTL_CRSSVE flag is stored only in emulated config space buffer and there is handler for PCI_EXP_RTCTL register. So every read operation from config space automatically clears CRSSVE flag as it is not defined in PCI_EXP_RTCTL read handler.
Fix this by reading current CRSSVE bit flag from emulated space buffer and appending it to PCI_EXP_RTCTL read response.
Link: https://lore.kernel.org/r/20211005180952.6812-5-kabel@kernel.org Fixes: 43f5c77bcbd2 ("PCI: aardvark: Fix reporting CRS value") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pci-aardvark.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 589ddb4c50100..b792a779f1059 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -885,6 +885,7 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, case PCI_EXP_RTCTL: { u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE; + *value |= le16_to_cpu(bridge->pcie_conf.rootctl) & PCI_EXP_RTCTL_CRSSVE; *value |= PCI_EXP_RTCAP_CRSVIS << 16; return PCI_BRIDGE_EMUL_HANDLED; }
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 27ff8187f13ecfec8a26fb1928e906f46f326cc5 ]
Fix sparse warning: drivers/opp/of.c:924 _opp_add_static_v2() warn: passing zero to 'ERR_PTR'
For duplicate OPPs 'ret' be set to zero.
Fixes: deac8703da5f ("PM / OPP: _of_add_opp_table_v2(): increment count only if OPP is added") Signed-off-by: YueHaibing yuehaibing@huawei.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/opp/of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 2a97c6535c4c6..c32ae7497392b 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -921,7 +921,7 @@ free_required_opps: free_opp: _opp_free(new_opp);
- return ERR_PTR(ret); + return ret ? ERR_PTR(ret) : NULL; }
/* Initializes OPP tables based on new bindings */
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 64a93dbf25d3a1368bb58ddf0f61d0a92d7479e3 ]
Partially revert commit 2ce209c42c01 ("NFS: Wait for requests that are locked on the commit list"), since it can lead to deadlocks between commit requests and nfs_join_page_group(). For now we should assume that any locked requests on the commit list are either about to be removed and committed by another task, or the writes they describe are about to be retransmitted. In either case, we should not need to worry.
Fixes: 2ce209c42c01 ("NFS: Wait for requests that are locked on the commit list") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/write.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index eae9bf1140417..735a054747752 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1038,25 +1038,11 @@ nfs_scan_commit_list(struct list_head *src, struct list_head *dst, struct nfs_page *req, *tmp; int ret = 0;
-restart: list_for_each_entry_safe(req, tmp, src, wb_list) { kref_get(&req->wb_kref); if (!nfs_lock_request(req)) { - int status; - - /* Prevent deadlock with nfs_lock_and_join_requests */ - if (!list_empty(dst)) { - nfs_release_request(req); - continue; - } - /* Ensure we make progress to prevent livelock */ - mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); - status = nfs_wait_on_request(req); nfs_release_request(req); - mutex_lock(&NFS_I(cinfo->inode)->commit_mutex); - if (status < 0) - break; - goto restart; + continue; } nfs_request_remove_commit_list(req, cinfo); clear_bit(PG_COMMIT_TO_DS, &req->wb_flags); @@ -1936,6 +1922,7 @@ static int __nfs_commit_inode(struct inode *inode, int how, int may_wait = how & FLUSH_SYNC; int ret, nscan;
+ how &= ~FLUSH_SYNC; nfs_init_cinfo_from_inode(&cinfo, inode); nfs_commit_begin(cinfo.mds); for (;;) {
From: Kees Cook keescook@chromium.org
[ Upstream commit a3c7ca2b141b9735eb383246e966a4f4322e3e65 ]
Fix observed warning:
/builds/linux/arch/sparc/boot/Makefile:35: FORCE prerequisite is missing
Fixes: e1f86d7b4b2a ("kbuild: warn if FORCE is missing for if_changed(_dep,_rule) and filechk") Signed-off-by: Kees Cook keescook@chromium.org Acked-by: Nicolas Schier n.schier@avm.de Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sparc/boot/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index 849236d4eca48..45e5c76d449ea 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile @@ -22,7 +22,7 @@ ifeq ($(CONFIG_SPARC64),y)
# Actual linking
-$(obj)/zImage: $(obj)/image +$(obj)/zImage: $(obj)/image FORCE $(call if_changed,gzip) @echo ' kernel: $@ is ready'
@@ -31,7 +31,7 @@ $(obj)/vmlinux.aout: vmlinux FORCE @echo ' kernel: $@ is ready' else
-$(obj)/zImage: $(obj)/image +$(obj)/zImage: $(obj)/image FORCE $(call if_changed,strip) @echo ' kernel: $@ is ready'
@@ -44,7 +44,7 @@ OBJCOPYFLAGS_image.bin := -S -O binary -R .note -R .comment $(obj)/image.bin: $(obj)/image FORCE $(call if_changed,objcopy)
-$(obj)/image.gz: $(obj)/image.bin +$(obj)/image.gz: $(obj)/image.bin FORCE $(call if_changed,gzip)
UIMAGE_LOADADDR = $(CONFIG_UBOOT_LOAD_ADDR) @@ -56,7 +56,7 @@ quiet_cmd_uimage.o = UIMAGE.O $@ -r -b binary $@ -o $@.o
targets += uImage -$(obj)/uImage: $(obj)/image.gz +$(obj)/uImage: $(obj)/image.gz FORCE $(call if_changed,uimage) $(call if_changed,uimage.o) @echo ' Image $@ is ready'
From: Jia-Ju Bai baijiaju1990@gmail.com
[ Upstream commit 4c2b46c824a78fc8190d8eafaaea5a9078fe7479 ]
When op_alloc() returns NULL to new_op, no error return code of orangefs_revalidate_lookup() is assigned. To fix this bug, ret is assigned with -ENOMEM in this case.
Fixes: 8bb8aefd5afb ("OrangeFS: Change almost all instances of the string PVFS2 to OrangeFS.") Reported-by: TOTE Robot oslab@tsinghua.edu.cn Signed-off-by: Jia-Ju Bai baijiaju1990@gmail.com Signed-off-by: Mike Marshall hubcap@omnibond.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/orangefs/dcache.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/orangefs/dcache.c b/fs/orangefs/dcache.c index fe484cf93e5cd..8bbe9486e3a62 100644 --- a/fs/orangefs/dcache.c +++ b/fs/orangefs/dcache.c @@ -26,8 +26,10 @@ static int orangefs_revalidate_lookup(struct dentry *dentry) gossip_debug(GOSSIP_DCACHE_DEBUG, "%s: attempting lookup.\n", __func__);
new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP); - if (!new_op) + if (!new_op) { + ret = -ENOMEM; goto out_put_parent; + }
new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW; new_op->upcall.req.lookup.parent_refn = parent->refn;
From: John Keeping john@metanate.com
[ Upstream commit 2667f6b7af99e81958fa97c03bb519fcb09d0055 ]
I have a ST1633 touch controller which fails to probe due to a timeout waiting for the controller to become ready. Increasing the minimum delay to 100ms ensures that the probe sequence completes successfully.
The ST1633 datasheet says nothing about the maximum delay here and the ST1232 I2C protocol document says "wait until" with no notion of a timeout.
Since this only runs once during probe, being generous with the timout seems reasonable and most likely the device will become ready eventually.
(It may be worth noting that I saw this issue with a PREEMPT_RT patched kernel which probably has tighter wakeups from usleep_range() than other preemption models.)
Fixes: f605be6a57b4 ("Input: st1232 - wait until device is ready before reading resolution") Signed-off-by: John Keeping john@metanate.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/r/20210929152609.2421483-1-john@metanate.com Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/input/touchscreen/st1232.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 6abae665ca71d..9d1dea6996a22 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -92,7 +92,7 @@ static int st1232_ts_wait_ready(struct st1232_ts_data *ts) unsigned int retries; int error;
- for (retries = 10; retries; retries--) { + for (retries = 100; retries; retries--) { error = st1232_ts_read_data(ts, REG_STATUS, 1); if (!error) { switch (ts->read_buf[0]) {
From: Guido Günther agx@sigxcpu.org
[ Upstream commit 2f1495fac8d38bfade18bd7e31fa787cd7815626 ]
Components further up in the chain might ask us for supported formats.
Without this MEDIA_BUS_FMT_FIXED is assumed which then breaks display output with mxsfb since it can't determine a proper bus format.
We handle the bus formats that correspond to the DSI formats the bridge can potentially output (see chapter 13.6 of the i.MX 8MQ reference manual) - which matches what xsfb can input.
Fixes: b776b0f00f24 ("drm: mxsfb: Use bus_format from the nearest bridge if present")
Signed-off-by: Guido Günther agx@sigxcpu.org Reviewed-by: Lucas Stach l.stach@pengutronix.de Reviewed-by: Sam Ravnborg sam@ravnborg.org Link: https://patchwork.freedesktop.org/patch/msgid/1712f2b952694fd4484dfd8576fbc5... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/nwl-dsi.c | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index ed8ac5059cd26..a7389a0facfb4 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -939,6 +939,40 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) drm_of_panel_bridge_remove(dsi->dev->of_node, 1, 0); }
+static u32 *nwl_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts, input_fmt; + + *num_input_fmts = 0; + + switch (output_fmt) { + /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */ + case MEDIA_BUS_FMT_FIXED: + input_fmt = MEDIA_BUS_FMT_RGB888_1X24; + break; + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_RGB565_1X16: + input_fmt = output_fmt; + break; + default: + return NULL; + } + + input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = input_fmt; + *num_input_fmts = 1; + + return input_fmts; +} + static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, @@ -946,6 +980,7 @@ static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { .atomic_check = nwl_dsi_bridge_atomic_check, .atomic_enable = nwl_dsi_bridge_atomic_enable, .atomic_disable = nwl_dsi_bridge_atomic_disable, + .atomic_get_input_bus_fmts = nwl_bridge_atomic_get_input_bus_fmts, .mode_set = nwl_dsi_bridge_mode_set, .mode_valid = nwl_dsi_bridge_mode_valid, .attach = nwl_dsi_bridge_attach,
From: Evgeny Novikov novikov@ispras.ru
[ Upstream commit 78e4d342187625585932bb437ec26e1060f7fc6f ]
hisi_spi_nor_probe() invokes clk_disable_unprepare() on all paths after successful call of clk_prepare_enable(). Besides, the clock is enabled by hispi_spi_nor_prep() and disabled by hispi_spi_nor_unprep(). So at remove time it is not possible to have the clock enabled. The patch removes excessive clk_disable_unprepare() from hisi_spi_nor_remove().
Found by Linux Driver Verification project (linuxtesting.org).
Fixes: e523f11141bd ("mtd: spi-nor: add hisilicon spi-nor flash controller driver") Signed-off-by: Evgeny Novikov novikov@ispras.ru Signed-off-by: Tudor Ambarus tudor.ambarus@microchip.com Reviewed-by: Pratyush Yadav p.yadav@ti.com Link: https://lore.kernel.org/r/20210709144529.31379-1-novikov@ispras.ru Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/spi-nor/controllers/hisi-sfc.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/controllers/hisi-sfc.c b/drivers/mtd/spi-nor/controllers/hisi-sfc.c index 47fbf1d1e5573..516e502694780 100644 --- a/drivers/mtd/spi-nor/controllers/hisi-sfc.c +++ b/drivers/mtd/spi-nor/controllers/hisi-sfc.c @@ -477,7 +477,6 @@ static int hisi_spi_nor_remove(struct platform_device *pdev)
hisi_spi_nor_unregister_all(host); mutex_destroy(&host->lock); - clk_disable_unprepare(host->clk); return 0; }
From: Kunihiko Hayashi hayashi.kunihiko@socionext.com
[ Upstream commit 4caab28a6215da5f3c1b505ff08810bc6acfe365 ]
The condition register PCI_RCV_INTX is used in irq_mask() and irq_unmask() callbacks. Accesses to register can occur at the same time without a lock. Add a lock into each callback to prevent the issue.
And INTX mask and unmask fields in PCL_RCV_INTX register should only be set/reset for each bit. Clearing by PCL_RCV_INTX_ALL_MASK should be removed.
INTX status fields in PCL_RCV_INTX register only indicates each INTX interrupt status, so the handler can't clear by writing 1 to the field. The status is expected to be cleared by the interrupt origin. The ack function has no meaning, so should remove it.
Suggested-by: Pali Rohár pali@kernel.org Link: https://lore.kernel.org/r/1631924579-24567-1-git-send-email-hayashi.kunihiko... Fixes: 7e6d5cd88a6f ("PCI: uniphier: Add UniPhier PCIe host controller support") Signed-off-by: Kunihiko Hayashi hayashi.kunihiko@socionext.com Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Acked-by: Pali Rohár pali@kernel.org Acked-by: Marc Zyngier maz@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-uniphier.c | 26 +++++++++------------- 1 file changed, 10 insertions(+), 16 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-uniphier.c b/drivers/pci/controller/dwc/pcie-uniphier.c index d842fd0181299..d05be942956e2 100644 --- a/drivers/pci/controller/dwc/pcie-uniphier.c +++ b/drivers/pci/controller/dwc/pcie-uniphier.c @@ -168,30 +168,21 @@ static void uniphier_pcie_irq_enable(struct uniphier_pcie_priv *priv) writel(PCL_RCV_INTX_ALL_ENABLE, priv->base + PCL_RCV_INTX); }
-static void uniphier_pcie_irq_ack(struct irq_data *d) -{ - struct pcie_port *pp = irq_data_get_irq_chip_data(d); - struct dw_pcie *pci = to_dw_pcie_from_pp(pp); - struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); - u32 val; - - val = readl(priv->base + PCL_RCV_INTX); - val &= ~PCL_RCV_INTX_ALL_STATUS; - val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_STATUS_SHIFT); - writel(val, priv->base + PCL_RCV_INTX); -} - static void uniphier_pcie_irq_mask(struct irq_data *d) { struct pcie_port *pp = irq_data_get_irq_chip_data(d); struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); + unsigned long flags; u32 val;
+ raw_spin_lock_irqsave(&pp->lock, flags); + val = readl(priv->base + PCL_RCV_INTX); - val &= ~PCL_RCV_INTX_ALL_MASK; val |= BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT); writel(val, priv->base + PCL_RCV_INTX); + + raw_spin_unlock_irqrestore(&pp->lock, flags); }
static void uniphier_pcie_irq_unmask(struct irq_data *d) @@ -199,17 +190,20 @@ static void uniphier_pcie_irq_unmask(struct irq_data *d) struct pcie_port *pp = irq_data_get_irq_chip_data(d); struct dw_pcie *pci = to_dw_pcie_from_pp(pp); struct uniphier_pcie_priv *priv = to_uniphier_pcie(pci); + unsigned long flags; u32 val;
+ raw_spin_lock_irqsave(&pp->lock, flags); + val = readl(priv->base + PCL_RCV_INTX); - val &= ~PCL_RCV_INTX_ALL_MASK; val &= ~BIT(irqd_to_hwirq(d) + PCL_RCV_INTX_MASK_SHIFT); writel(val, priv->base + PCL_RCV_INTX); + + raw_spin_unlock_irqrestore(&pp->lock, flags); }
static struct irq_chip uniphier_pcie_irq_chip = { .name = "PCI", - .irq_ack = uniphier_pcie_irq_ack, .irq_mask = uniphier_pcie_irq_mask, .irq_unmask = uniphier_pcie_irq_unmask, };
From: Miquel Raynal miquel.raynal@bootlin.com
[ Upstream commit fc9e18f9e987ad46722dad53adab1c12148c213c ]
Under the following conditions: * after rounding up by 4 the number of bytes to transfer (this is related to the controller's internal constraints), * if this (rounded) amount of data is situated beyond the end of the device, * and only in NV-DDR mode, the Arasan NAND controller timeouts.
This currently can happen in a particular helper used when picking software ECC algorithms. Let's prevent this situation by refusing to use the NV-DDR interface with software engines.
Fixes: 4edde6031458 ("mtd: rawnand: arasan: Support NV-DDR interface") Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20211008163640.1753821-1-miquel.raynal@boo... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/nand/raw/arasan-nand-controller.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c index 9cbcc698c64d8..53bd10738418b 100644 --- a/drivers/mtd/nand/raw/arasan-nand-controller.c +++ b/drivers/mtd/nand/raw/arasan-nand-controller.c @@ -973,6 +973,21 @@ static int anfc_setup_interface(struct nand_chip *chip, int target, nvddr = nand_get_nvddr_timings(conf); if (IS_ERR(nvddr)) return PTR_ERR(nvddr); + + /* + * The controller only supports data payload requests which are + * a multiple of 4. In practice, most data accesses are 4-byte + * aligned and this is not an issue. However, rounding up will + * simply be refused by the controller if we reached the end of + * the device *and* we are using the NV-DDR interface(!). In + * this situation, unaligned data requests ending at the device + * boundary will confuse the controller and cannot be performed. + * + * This is something that happens in nand_read_subpage() when + * selecting software ECC support and must be avoided. + */ + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT) + return -ENOTSUPP; } else { sdr = nand_get_sdr_timings(conf); if (IS_ERR(sdr))
From: Zev Weiss zev@bewilderbeest.net
[ Upstream commit c13de2386c78e890d4ae6f01a85eefd0b293fb08 ]
Previously, if del_mtd_device() failed with -EBUSY due to a non-zero usecount, a subsequent call to attempt the deletion again would try to remove a debugfs directory that had already been removed and panic. With this change the second call can instead proceed safely.
Fixes: e8e3edb95ce6 ("mtd: create per-device and module-scope debugfs entries") Signed-off-by: Zev Weiss zev@bewilderbeest.net Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20211014203953.5424-1-zev@bewilderbeest.ne... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mtd/mtdcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index c8fd7f758938b..1532291989471 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -724,8 +724,6 @@ int del_mtd_device(struct mtd_info *mtd)
mutex_lock(&mtd_table_mutex);
- debugfs_remove_recursive(mtd->dbg.dfs_dir); - if (idr_find(&mtd_idr, mtd->index) != mtd) { ret = -ENODEV; goto out_error; @@ -741,6 +739,8 @@ int del_mtd_device(struct mtd_info *mtd) mtd->index, mtd->name, mtd->usecount); ret = -EBUSY; } else { + debugfs_remove_recursive(mtd->dbg.dfs_dir); + /* Try to remove the NVMEM provider */ if (mtd->nvmem) nvmem_unregister(mtd->nvmem);
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 0374a4ea7269645c46c3eb288526ea072fa19e79 ]
If 'copy_dma_range_map() fails, the memory allocated for 'rvdev' will leak. Move the 'copy_dma_range_map()' call after the device registration so that 'rproc_rvdev_release()' can be called to free some resources.
Also, branch to the error handling path if 'copy_dma_range_map()' instead of a direct return to avoid some other leaks.
Fixes: e0d072782c73 ("dma-mapping: introduce DMA range map, supplanting dma_pfn_offset") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Reviewed-by: Jim Quinlan james.quinlan@broadcom.com Reviewed-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Link: https://lore.kernel.org/r/e6d0dad6620da4fdf847faa903f79b735d35f262.163075537... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/remoteproc/remoteproc_core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 502b6604b757b..775df165eb450 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -556,9 +556,6 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr, /* Initialise vdev subdevice */ snprintf(name, sizeof(name), "vdev%dbuffer", rvdev->index); rvdev->dev.parent = &rproc->dev; - ret = copy_dma_range_map(&rvdev->dev, rproc->dev.parent); - if (ret) - return ret; rvdev->dev.release = rproc_rvdev_release; dev_set_name(&rvdev->dev, "%s#%s", dev_name(rvdev->dev.parent), name); dev_set_drvdata(&rvdev->dev, rvdev); @@ -568,6 +565,11 @@ static int rproc_handle_vdev(struct rproc *rproc, void *ptr, put_device(&rvdev->dev); return ret; } + + ret = copy_dma_range_map(&rvdev->dev, rproc->dev.parent); + if (ret) + goto free_rvdev; + /* Make device dma capable by inheriting from parent's capabilities */ set_dma_ops(&rvdev->dev, get_dma_ops(rproc->dev.parent));
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit c3336b8ac6091df60a5c1049a8c685d0b947cc61 ]
Do not call rv3032_exit_eerd() if the enter function fails but don't forget to call the exit when the enter succeeds.
Fixes: 2eeaa532acca ("rtc: rv3032: Add a driver for Microcrystal RV-3032") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Link: https://lore.kernel.org/r/20211012101028.GT2083@kadam Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-rv3032.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-rv3032.c b/drivers/rtc/rtc-rv3032.c index d63102d5cb1e4..1b62ed2f14594 100644 --- a/drivers/rtc/rtc-rv3032.c +++ b/drivers/rtc/rtc-rv3032.c @@ -617,11 +617,11 @@ static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
ret = rv3032_enter_eerd(rv3032, &eerd); if (ret) - goto exit_eerd; + return ret;
ret = regmap_write(rv3032->regmap, RV3032_CLKOUT1, hfd & 0xff); if (ret) - return ret; + goto exit_eerd;
ret = regmap_write(rv3032->regmap, RV3032_CLKOUT2, RV3032_CLKOUT2_OS | FIELD_PREP(RV3032_CLKOUT2_HFD_MSK, hfd >> 8));
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit fa5270ec2f2688d98a82895be7039b81c87d856c ]
at_xdmac could be used on SoCs which supports backup mode (where most of the SoC power, including power to DMA controller, is closed at suspend time). Thus, on resume, the settings which were previously done need to be restored. Do the same for axi configuration.
Fixes: f40566f220a1 ("dmaengine: at_xdmac: add AXI priority support and recommended settings") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Tudor Ambarus tudor.ambarus@microchip.com Link: https://lore.kernel.org/r/20211007111230.2331837-2-claudiu.beznea@microchip.... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/at_xdmac.c | 51 ++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index ab78e0f6afd70..c66ad5706cb5a 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1926,6 +1926,30 @@ static void at_xdmac_free_chan_resources(struct dma_chan *chan) return; }
+static void at_xdmac_axi_config(struct platform_device *pdev) +{ + struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); + bool dev_m2m = false; + u32 dma_requests; + + if (!atxdmac->layout->axi_config) + return; /* Not supported */ + + if (!of_property_read_u32(pdev->dev.of_node, "dma-requests", + &dma_requests)) { + dev_info(&pdev->dev, "controller in mem2mem mode.\n"); + dev_m2m = true; + } + + if (dev_m2m) { + at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_M2M); + at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_M2M); + } else { + at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_P2M); + at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_P2M); + } +} + #ifdef CONFIG_PM static int atmel_xdmac_prepare(struct device *dev) { @@ -1975,6 +1999,7 @@ static int atmel_xdmac_resume(struct device *dev) struct at_xdmac *atxdmac = dev_get_drvdata(dev); struct at_xdmac_chan *atchan; struct dma_chan *chan, *_chan; + struct platform_device *pdev = container_of(dev, struct platform_device, dev); int i; int ret;
@@ -1982,6 +2007,8 @@ static int atmel_xdmac_resume(struct device *dev) if (ret) return ret;
+ at_xdmac_axi_config(pdev); + /* Clear pending interrupts. */ for (i = 0; i < atxdmac->dma.chancnt; i++) { atchan = &atxdmac->chan[i]; @@ -2007,30 +2034,6 @@ static int atmel_xdmac_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */
-static void at_xdmac_axi_config(struct platform_device *pdev) -{ - struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); - bool dev_m2m = false; - u32 dma_requests; - - if (!atxdmac->layout->axi_config) - return; /* Not supported */ - - if (!of_property_read_u32(pdev->dev.of_node, "dma-requests", - &dma_requests)) { - dev_info(&pdev->dev, "controller in mem2mem mode.\n"); - dev_m2m = true; - } - - if (dev_m2m) { - at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_M2M); - at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_M2M); - } else { - at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_P2M); - at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_P2M); - } -} - static int at_xdmac_probe(struct platform_device *pdev) { struct at_xdmac *atxdmac;
From: Claudiu Beznea claudiu.beznea@microchip.com
[ Upstream commit 320c88a3104dc955f928a1eecebd551ff89530c0 ]
AT_XDMAC_CC_PERID() should be used to setup bits 24..30 of XDMAC_CC register. Using it without parenthesis around 0x7f & (i) will lead to setting all the time zero for bits 24..30 of XDMAC_CC as the << operator has higher precedence over bitwise &. Thus, add paranthesis around 0x7f & (i).
Fixes: 15a03850ab8f ("dmaengine: at_xdmac: fix macro typo") Signed-off-by: Claudiu Beznea claudiu.beznea@microchip.com Reviewed-by: Tudor Ambarus tudor.ambarus@microchip.com Link: https://lore.kernel.org/r/20211007111230.2331837-3-claudiu.beznea@microchip.... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/at_xdmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index c66ad5706cb5a..e18abbd56fb51 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -155,7 +155,7 @@ #define AT_XDMAC_CC_WRIP (0x1 << 23) /* Write in Progress (read only) */ #define AT_XDMAC_CC_WRIP_DONE (0x0 << 23) #define AT_XDMAC_CC_WRIP_IN_PROGRESS (0x1 << 23) -#define AT_XDMAC_CC_PERID(i) (0x7f & (i) << 24) /* Channel Peripheral Identifier */ +#define AT_XDMAC_CC_PERID(i) ((0x7f & (i)) << 24) /* Channel Peripheral Identifier */ #define AT_XDMAC_CDS_MSP 0x2C /* Channel Data Stride Memory Set Pattern */ #define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */ #define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit b20fd5fa310cbf7ec367f263a34382a24c4cee73 ]
buf_addr parameter of stm32_dma_set_xfer_param function is a dma_addr_t. We only need to check the remainder of buf_addr/max_width, so, no need to use do_div and extra u64 addr. Use '%' instead.
Fixes: e0ebdbdcb42a ("dmaengine: stm32-dma: take address into account when computing max width") Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20211011094259.315023-3-amelie.delaunay@foss.st.co... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/stm32-dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index 9063c727962ed..fdda916555ec5 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -270,7 +270,6 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len, u32 threshold) { enum dma_slave_buswidth max_width; - u64 addr = buf_addr;
if (threshold == STM32_DMA_FIFO_THRESHOLD_FULL) max_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -281,7 +280,7 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len, max_width > DMA_SLAVE_BUSWIDTH_1_BYTE) max_width = max_width >> 1;
- if (do_div(addr, max_width)) + if (buf_addr % max_width) max_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
return max_width;
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 133a48abf6ecc535d7eddc6da1c3e4c972445882 ]
If O_DIRECT bumps the commit_info rpcs_out field, then that could lead to fsync() hangs. The fix is to ensure that O_DIRECT calls nfs_commit_end().
Fixes: 723c921e7dfc ("sched/wait, fs/nfs: Convert wait_on_atomic_t() usage to the new wait_var_event() API") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/direct.c | 2 +- fs/nfs/pnfs_nfs.c | 2 -- fs/nfs/write.c | 9 ++++++--- include/linux/nfs_fs.h | 1 + 4 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 2e894fec036b0..3c0335c15a730 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -620,7 +620,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) nfs_unlock_and_release_request(req); }
- if (atomic_dec_and_test(&cinfo.mds->rpcs_out)) + if (nfs_commit_end(cinfo.mds)) nfs_direct_write_complete(dreq); }
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 02bd6e83961d9..316f68f96e573 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -468,7 +468,6 @@ pnfs_bucket_alloc_ds_commits(struct list_head *list, goto out_error; data->ds_commit_index = i; list_add_tail(&data->list, list); - atomic_inc(&cinfo->mds->rpcs_out); nreq++; } mutex_unlock(&NFS_I(cinfo->inode)->commit_mutex); @@ -520,7 +519,6 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages, data->ds_commit_index = -1; list_splice_init(mds_pages, &data->pages); list_add_tail(&data->list, &list); - atomic_inc(&cinfo->mds->rpcs_out); nreq++; }
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 735a054747752..7dce3e735fc53 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -1657,10 +1657,13 @@ static void nfs_commit_begin(struct nfs_mds_commit_info *cinfo) atomic_inc(&cinfo->rpcs_out); }
-static void nfs_commit_end(struct nfs_mds_commit_info *cinfo) +bool nfs_commit_end(struct nfs_mds_commit_info *cinfo) { - if (atomic_dec_and_test(&cinfo->rpcs_out)) + if (atomic_dec_and_test(&cinfo->rpcs_out)) { wake_up_var(&cinfo->rpcs_out); + return true; + } + return false; }
void nfs_commitdata_release(struct nfs_commit_data *data) @@ -1760,6 +1763,7 @@ void nfs_init_commit(struct nfs_commit_data *data, data->res.fattr = &data->fattr; data->res.verf = &data->verf; nfs_fattr_init(&data->fattr); + nfs_commit_begin(cinfo->mds); } EXPORT_SYMBOL_GPL(nfs_init_commit);
@@ -1806,7 +1810,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
/* Set up the argument struct */ nfs_init_commit(data, head, NULL, cinfo); - atomic_inc(&cinfo->mds->rpcs_out); if (NFS_SERVER(inode)->nfs_client->cl_minorversion) task_flags = RPC_TASK_MOVEABLE; return nfs_initiate_commit(NFS_CLIENT(inode), data, NFS_PROTO(inode), diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index b9a8b925db430..4d95cc999d121 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -569,6 +569,7 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); extern int nfs_commit_inode(struct inode *, int); extern struct nfs_commit_data *nfs_commitdata_alloc(bool never_fail); extern void nfs_commit_free(struct nfs_commit_data *data); +bool nfs_commit_end(struct nfs_mds_commit_info *cinfo);
static inline int nfs_have_writebacks(struct inode *inode)
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit f0caea8882a7412a2ad4d8274f0280cdf849c9e2 ]
Olga reports seeing the following Oops when doing O_DIRECT writes to a pNFS flexfiles server:
Oops: 0000 [#1] SMP PTI CPU: 1 PID: 234186 Comm: kworker/u8:1 Not tainted 5.15.0-rc4+ #4 Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.13.0-2.module+el8.3.0+7353+9de0a3cc 04/01/2014 Workqueue: nfsiod rpc_async_release [sunrpc] RIP: 0010:nfs_mark_request_commit+0x12/0x30 [nfs] Code: ff ff be 03 00 00 00 e8 ac 34 83 eb e9 29 ff ff ff e8 22 bc d7 eb 66 90 0f 1f 44 00 00 48 85 f6 74 16 48 8b 42 10 48 8b 40 18 <48> 8b 40 18 48 85 c0 74 05 e9 70 fc 15 ec 48 89 d6 e9 68 ed ff ff RSP: 0018:ffffa82f0159fe00 EFLAGS: 00010286 RAX: 0000000000000000 RBX: ffff8f3393141880 RCX: 0000000000000000 RDX: ffffa82f0159fe08 RSI: ffff8f3381252500 RDI: ffff8f3393141880 RBP: ffff8f33ac317c00 R08: 0000000000000000 R09: ffff8f3487724cb0 R10: 0000000000000008 R11: 0000000000000001 R12: 0000000000000001 R13: ffff8f3485bccee0 R14: ffff8f33ac317c10 R15: ffff8f33ac317cd8 FS: 0000000000000000(0000) GS:ffff8f34fbc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000018 CR3: 0000000122120006 CR4: 0000000000770ee0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: nfs_direct_write_completion+0x13b/0x250 [nfs] rpc_free_task+0x39/0x60 [sunrpc] rpc_async_release+0x29/0x40 [sunrpc] process_one_work+0x1ce/0x370 worker_thread+0x30/0x380 ? process_one_work+0x370/0x370 kthread+0x11a/0x140 ? set_kthread_struct+0x40/0x40 ret_from_fork+0x22/0x30
Reported-by: Olga Kornievskaia aglo@umich.edu Fixes: 9c455a8c1e14 ("NFS/pNFS: Clean up pNFS commit operations") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/pnfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index d810ae674f4e8..a0f6ff094b3a4 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -517,7 +517,7 @@ pnfs_mark_request_commit(struct nfs_page *req, struct pnfs_layout_segment *lseg, { struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
- if (!lseg || !fl_cinfo->ops->mark_request_commit) + if (!lseg || !fl_cinfo->ops || !fl_cinfo->ops->mark_request_commit) return false; fl_cinfo->ops->mark_request_commit(req, lseg, cinfo, ds_commit_idx); return true;
From: Alexey Gladkov legion@kernel.org
[ Upstream commit d5f458a979650e5ed37212f6134e4ee2b28cb6ed ]
Fixes: 61ca2c4afd9d ("NFS: Only reference user namespace from nfs4idmap struct instead of cred") Signed-off-by: Alexey Gladkov legion@kernel.org Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4idmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 8d8aba305ecca..f331866dd4182 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -487,7 +487,7 @@ nfs_idmap_new(struct nfs_client *clp) err_destroy_pipe: rpc_destroy_pipe_data(idmap->idmap_pipe); err: - get_user_ns(idmap->user_ns); + put_user_ns(idmap->user_ns); kfree(idmap); return error; }
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit afcb5a811ff3ab3969f09666535eb6018a160358 ]
While writing an empty string to a device attribute is a no-op, and thus does not need explicit safeguards, the user can still write a single newline to an attribute file:
echo > .../message
If that happens, img_ascii_lcd_display() trims the newline, yielding an empty string, and causing an infinite loop in img_ascii_lcd_scroll().
Fix this by adding a check for empty strings. Clear the display in case one is encountered.
Fixes: 0cad855fbd083ee5 ("auxdisplay: img-ascii-lcd: driver for simple ASCII LCD displays") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/auxdisplay/img-ascii-lcd.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c index 1cce409ce5cac..e33ce0151cdfd 100644 --- a/drivers/auxdisplay/img-ascii-lcd.c +++ b/drivers/auxdisplay/img-ascii-lcd.c @@ -280,6 +280,16 @@ static int img_ascii_lcd_display(struct img_ascii_lcd_ctx *ctx, if (msg[count - 1] == '\n') count--;
+ if (!count) { + /* clear the LCD */ + devm_kfree(&ctx->pdev->dev, ctx->message); + ctx->message = NULL; + ctx->message_len = 0; + memset(ctx->curr, ' ', ctx->cfg->num_chars); + ctx->cfg->update(ctx); + return 0; + } + new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL); if (!new_msg) return -ENOMEM;
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 80f9eb70fd9276938f0a131f76d438021bfd8b34 ]
Currently /sys/class/graphics/fb0/bl_curve is not accessible (-ENODEV), as the driver does not connect the backlight to the frame buffer device. Fix this moving backlight initialization up, and filling in fb_info.bl_dev.
Fixes: 8992da44c6805d53 ("auxdisplay: ht16k33: Driver for LED controller") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Reviewed-by: Robin van der Gracht robin@protonic.nl Signed-off-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/auxdisplay/ht16k33.c | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 1e69cc6d21a0d..2b630e194570f 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -413,6 +413,33 @@ static int ht16k33_probe(struct i2c_client *client, if (err) return err;
+ /* Backlight */ + memset(&bl_props, 0, sizeof(struct backlight_properties)); + bl_props.type = BACKLIGHT_RAW; + bl_props.max_brightness = MAX_BRIGHTNESS; + + bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", + &client->dev, priv, + &ht16k33_bl_ops, &bl_props); + if (IS_ERR(bl)) { + dev_err(&client->dev, "failed to register backlight\n"); + return PTR_ERR(bl); + } + + err = of_property_read_u32(node, "default-brightness-level", + &dft_brightness); + if (err) { + dft_brightness = MAX_BRIGHTNESS; + } else if (dft_brightness > MAX_BRIGHTNESS) { + dev_warn(&client->dev, + "invalid default brightness level: %u, using %u\n", + dft_brightness, MAX_BRIGHTNESS); + dft_brightness = MAX_BRIGHTNESS; + } + + bl->props.brightness = dft_brightness; + ht16k33_bl_update_status(bl); + /* Framebuffer (2 bytes per column) */ BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE); fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL); @@ -445,6 +472,7 @@ static int ht16k33_probe(struct i2c_client *client, fbdev->info->screen_size = HT16K33_FB_SIZE; fbdev->info->fix = ht16k33_fb_fix; fbdev->info->var = ht16k33_fb_var; + fbdev->info->bl_dev = bl; fbdev->info->pseudo_palette = NULL; fbdev->info->flags = FBINFO_FLAG_DEFAULT; fbdev->info->par = priv; @@ -460,34 +488,6 @@ static int ht16k33_probe(struct i2c_client *client, goto err_fbdev_unregister; }
- /* Backlight */ - memset(&bl_props, 0, sizeof(struct backlight_properties)); - bl_props.type = BACKLIGHT_RAW; - bl_props.max_brightness = MAX_BRIGHTNESS; - - bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", - &client->dev, priv, - &ht16k33_bl_ops, &bl_props); - if (IS_ERR(bl)) { - dev_err(&client->dev, "failed to register backlight\n"); - err = PTR_ERR(bl); - goto err_fbdev_unregister; - } - - err = of_property_read_u32(node, "default-brightness-level", - &dft_brightness); - if (err) { - dft_brightness = MAX_BRIGHTNESS; - } else if (dft_brightness > MAX_BRIGHTNESS) { - dev_warn(&client->dev, - "invalid default brightness level: %u, using %u\n", - dft_brightness, MAX_BRIGHTNESS); - dft_brightness = MAX_BRIGHTNESS; - } - - bl->props.brightness = dft_brightness; - ht16k33_bl_update_status(bl); - ht16k33_fb_queue(priv); return 0;
From: Geert Uytterhoeven geert@linux-m68k.org
[ Upstream commit 840fe258332544aa7321921e1723d37b772af7a9 ]
As the ht16k33 frame buffer sub-driver does not register an fb_ops.fb_blank() handler, blanking does not work:
$ echo 1 > /sys/class/graphics/fb0/blank sh: write error: Invalid argument
Fix this by providing a handler that always returns zero, to make sure blank events will be sent to the actual device handling the backlight.
Reported-by: Robin van der Gracht robin@protonic.nl Suggested-by: Robin van der Gracht robin@protonic.nl Fixes: 8992da44c6805d53 ("auxdisplay: ht16k33: Driver for LED controller") Signed-off-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/auxdisplay/ht16k33.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c index 2b630e194570f..ed58083499907 100644 --- a/drivers/auxdisplay/ht16k33.c +++ b/drivers/auxdisplay/ht16k33.c @@ -219,6 +219,15 @@ static const struct backlight_ops ht16k33_bl_ops = { .check_fb = ht16k33_bl_check_fb, };
+/* + * Blank events will be passed to the actual device handling the backlight when + * we return zero here. + */ +static int ht16k33_blank(int blank, struct fb_info *info) +{ + return 0; +} + static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct ht16k33_priv *priv = info->par; @@ -231,6 +240,7 @@ static const struct fb_ops ht16k33_fb_ops = { .owner = THIS_MODULE, .fb_read = fb_sys_read, .fb_write = fb_sys_write, + .fb_blank = ht16k33_blank, .fb_fillrect = sys_fillrect, .fb_copyarea = sys_copyarea, .fb_imageblit = sys_imageblit,
From: Robert-Ionut Alexa robert-ionut.alexa@nxp.com
[ Upstream commit 8120bd469f5525da229953c1197f2b826c0109f4 ]
Free the kbuf buffer before returning from the dpaa2_console_read() function. The variable no longer goes out of scope, leaking the storage it points to.
Fixes: c93349d8c170 ("soc: fsl: add DPAA2 console support") Signed-off-by: Robert-Ionut Alexa robert-ionut.alexa@nxp.com Signed-off-by: Ioana Ciornei ioana.ciornei@nxp.com Signed-off-by: Li Yang leoyang.li@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/fsl/dpaa2-console.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/soc/fsl/dpaa2-console.c b/drivers/soc/fsl/dpaa2-console.c index 27243f706f376..53917410f2bdb 100644 --- a/drivers/soc/fsl/dpaa2-console.c +++ b/drivers/soc/fsl/dpaa2-console.c @@ -231,6 +231,7 @@ static ssize_t dpaa2_console_read(struct file *fp, char __user *buf, cd->cur_ptr += bytes; written += bytes;
+ kfree(kbuf); return written;
err_free_buf:
From: Florian Westphal fw@strlen.de
[ Upstream commit 5648b5e1169ff1d6d6a46c35c0b5fbebd2a5cbb2 ]
On 64bit platforms the MAC header is set to 0xffff on allocation and also when a helper like skb_unset_mac_header() is called.
dev_parse_header may call skb_mac_header() which assumes valid mac offset:
BUG: KASAN: use-after-free in eth_header_parse+0x75/0x90 Read of size 6 at addr ffff8881075a5c05 by task nf-queue/1364 Call Trace: memcpy+0x20/0x60 eth_header_parse+0x75/0x90 __nfqnl_enqueue_packet+0x1a61/0x3380 __nf_queue+0x597/0x1300 nf_queue+0xf/0x40 nf_hook_slow+0xed/0x190 nf_hook+0x184/0x440 ip_output+0x1c0/0x2a0 nf_reinject+0x26f/0x700 nfqnl_recv_verdict+0xa16/0x18b0 nfnetlink_rcv_msg+0x506/0xe70
The existing code only works if the skb has a mac header.
Fixes: 2c38de4c1f8da7 ("netfilter: fix looped (broad|multi)cast's MAC handling") Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/netfilter/nfnetlink_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 4c3fbaaeb1030..4acc4b8e9fe5a 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -560,7 +560,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue, goto nla_put_failure;
if (indev && entskb->dev && - entskb->mac_header != entskb->network_header) { + skb_mac_header_was_set(entskb)) { struct nfqnl_msg_packet_hw phw; int len;
From: Lars-Peter Clausen lars@metafoo.de
[ Upstream commit e7e1e880b114ca640a2f280b0d5d38aed98f98c6 ]
Before the `callback_result` callback was introduced drivers coded their invocation to the callback in a similar way to:
if (cb->callback) { spin_unlock(&dma->lock); cb->callback(cb->callback_param); spin_lock(&dma->lock); }
With the introduction of `callback_result` two helpers where introduced to transparently handle both types of callbacks. And drivers where updated to look like this:
if (dmaengine_desc_callback_valid(cb)) { spin_unlock(&dma->lock); dmaengine_desc_callback_invoke(cb, ...); spin_lock(&dma->lock); }
dmaengine_desc_callback_invoke() correctly handles both `callback_result` and `callback`. But we forgot to update the dmaengine_desc_callback_valid() function to check for `callback_result`. As a result DMA descriptors that use the `callback_result` rather than `callback` don't have their callback invoked by drivers that follow the pattern above.
Fix this by checking for both `callback` and `callback_result` in dmaengine_desc_callback_valid().
Fixes: f067025bc676 ("dmaengine: add support to provide error result from a DMA transation") Signed-off-by: Lars-Peter Clausen lars@metafoo.de Acked-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/20211023134101.28042-1-lars@metafoo.de Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dmaengine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/dmaengine.h b/drivers/dma/dmaengine.h index 1bfbd64b13717..53f16d3f00294 100644 --- a/drivers/dma/dmaengine.h +++ b/drivers/dma/dmaengine.h @@ -176,7 +176,7 @@ dmaengine_desc_get_callback_invoke(struct dma_async_tx_descriptor *tx, static inline bool dmaengine_desc_callback_valid(struct dmaengine_desc_callback *cb) { - return (cb->callback) ? true : false; + return cb->callback || cb->callback_result; }
struct dma_chan *dma_get_slave_channel(struct dma_chan *chan);
From: Dongliang Mu mudongliangabcd@gmail.com
[ Upstream commit c5a51fc89c0103c03b8a54cf12dac7d014b3a2bf ]
The previous commit 059e969c2a7d ("dmaengine: tegra210-adma: Using pm_runtime_resume_and_get to replace open coding") forgets to replace the pm_runtime_get_sync in the tegra_adma_probe, but removes the pm_runtime_put_noidle.
Fix this by continuing to replace pm_runtime_get_sync with pm_runtime_resume_and_get in tegra_adma_probe.
Fixes: 059e969c2a7d ("dmaengine: tegra210-adma: Using pm_runtime_resume_and_get to replace open coding") Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Reviewed-by: Jon Hunter jonathanh@nvidia.com Link: https://lore.kernel.org/r/20211021030538.3465287-1-mudongliangabcd@gmail.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/tegra210-adma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index b1115a6d1935c..d1dff3a29db59 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -867,7 +867,7 @@ static int tegra_adma_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) goto rpm_disable;
From: Dave Jiang dave.jiang@intel.com
[ Upstream commit 98da0106aac0d3c5d4a3c95d238f1ff88957bbfc ]
Fault triggers on ioread32() when pci driver unbind is envoked. The placement of idxd sub-driver removal causes the probing of the device mmio region after the mmio mapping being torn down. The driver needs the sub-drivers to be unbound but not release the idxd context until all shutdown activities has been done. Move the sub-driver unregistering up before the remove() calls shutdown(). But take a device ref on the idxd->conf_dev so that the memory does not get freed in ->release(). When all cleanup activities has been done, release the ref to allow the idxd memory to be freed.
[57159.542766] RIP: 0010:ioread32+0x27/0x60 [57159.547097] Code: 00 66 90 48 81 ff ff ff 03 00 77 1e 48 81 ff 00 00 01 00 76 05 0f b7 d7 ed c3 8b 15 03 50 41 01 b8 ff ff ff ff 85 d2 75 04 c3 <8b> 07 c3 55 83 ea 01 48 89 fe 48 c7 c7 00 70 5f 82 48 89 e5 48 83 [57159.566647] RSP: 0018:ffffc900011abb60 EFLAGS: 00010292 [57159.572295] RAX: ffffc900011e0000 RBX: ffff888107d39800 RCX: 0000000000000000 [57159.579842] RDX: 0000000000000000 RSI: ffffffff82b1e448 RDI: ffffc900011e0090 [57159.587421] RBP: ffffc900011abb88 R08: 0000000000000000 R09: 0000000000000001 [57159.594972] R10: 0000000000000001 R11: 0000000000000000 R12: ffff8881019840d0 [57159.602533] R13: ffff8881097e9000 R14: ffffffffa08542a0 R15: 00000000000003a8 [57159.610093] FS: 00007f991e0a8740(0000) GS:ffff888459900000(0000) knlGS:00000000000 00000 [57159.618614] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [57159.624814] CR2: ffffc900011e0090 CR3: 000000010862a002 CR4: 00000000003706e0 [57159.632397] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [57159.639973] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [57159.647601] Call Trace: [57159.650502] ? idxd_device_disable+0x41/0x110 [idxd] [57159.655948] idxd_device_drv_remove+0x2b/0x80 [idxd] [57159.661374] idxd_config_bus_remove+0x16/0x20 [57159.666191] __device_release_driver+0x163/0x240 [57159.671320] device_release_driver+0x2b/0x40 [57159.676052] bus_remove_device+0xf5/0x160 [57159.680524] device_del+0x19c/0x400 [57159.684440] device_unregister+0x18/0x60 [57159.688792] idxd_remove+0x140/0x1c0 [idxd] [57159.693406] pci_device_remove+0x3e/0xb0 [57159.697758] __device_release_driver+0x163/0x240 [57159.702788] device_driver_detach+0x43/0xb0 [57159.707424] unbind_store+0x11e/0x130 [57159.711537] drv_attr_store+0x24/0x30 [57159.715646] sysfs_kf_write+0x4b/0x60 [57159.719710] kernfs_fop_write_iter+0x153/0x1e0 [57159.724563] new_sync_write+0x120/0x1b0 [57159.728812] vfs_write+0x23e/0x350 [57159.732624] ksys_write+0x70/0xf0 [57159.736335] __x64_sys_write+0x1a/0x20 [57159.740492] do_syscall_64+0x3b/0x90 [57159.744465] entry_SYSCALL_64_after_hwframe+0x44/0xae [57159.749908] RIP: 0033:0x7f991e19c387 [57159.753898] Code: 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24 [57159.773564] RSP: 002b:00007ffc2ce2d6a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [57159.781550] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007f991e19c387 [57159.789133] RDX: 000000000000000c RSI: 000055ee2630e140 RDI: 0000000000000001 [57159.796695] RBP: 000055ee2630e140 R08: 0000000000000000 R09: 00007f991e2324e0 [57159.804246] R10: 00007f991e2323e0 R11: 0000000000000246 R12: 000000000000000c [57159.811800] R13: 00007f991e26f520 R14: 000000000000000c R15: 00007f991e26f700 [57159.819373] Modules linked in: idxd bridge stp llc bnep sunrpc nls_iso8859_1 intel_ rapl_msr intel_rapl_common x86_pkg_temp_thermal intel_powerclamp coretemp snd_hda_code c_realtek iTCO_wdt 8250_dw snd_hda_codec_generic kvm_intel ledtrig_audio iTCO_vendor_s upport snd_hda_intel snd_intel_dspcfg ppdev kvm snd_hda_codec intel_wmi_thunderbolt sn d_hwdep irqbypass iwlwifi btusb snd_hda_core rapl btrtl intel_cstate snd_seq btbcm snd _seq_device btintel snd_pcm cfg80211 bluetooth pcspkr psmouse input_leds snd_timer int el_lpss_pci mei_me intel_lpss snd ecdh_generic ecc mei ucsi_acpi i2c_i801 idma64 i2c_s mbus virt_dma soundcore typec_ucsi typec wmi parport_pc parport video mac_hid acpi_pad sch_fq_codel drm ip_tables x_tables crct10dif_pclmul crc32_pclmul ghash_clmulni_intel usbkbd hid_generic usbmouse aesni_intel usbhid crypto_simd cryptd e1000e hid serio_ra w ahci libahci pinctrl_sunrisepoint fuse msr autofs4 [last unloaded: idxd] [57159.904082] CR2: ffffc900011e0090 [57159.907877] ---[ end trace b4e32f49ce9176a4 ]---
Fixes: 49c4959f04b5 ("dmaengine: idxd: fix sequence for pci driver remove() and shutdown()") Reported-by: Ziye Yang ziye.yang@intel.com Signed-off-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/163225535868.4152687.9318737776682088722.stgit@dji... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/idxd/init.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index eb09bc591c316..7bf03f371ce19 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -797,11 +797,19 @@ static void idxd_remove(struct pci_dev *pdev) int msixcnt = pci_msix_vec_count(pdev); int i;
- dev_dbg(&pdev->dev, "%s called\n", __func__); + idxd_unregister_devices(idxd); + /* + * When ->release() is called for the idxd->conf_dev, it frees all the memory related + * to the idxd context. The driver still needs those bits in order to do the rest of + * the cleanup. However, we do need to unbound the idxd sub-driver. So take a ref + * on the device here to hold off the freeing while allowing the idxd sub-driver + * to unbind. + */ + get_device(idxd_confdev(idxd)); + device_unregister(idxd_confdev(idxd)); idxd_shutdown(pdev); if (device_pasid_enabled(idxd)) idxd_disable_system_pasid(idxd); - idxd_unregister_devices(idxd);
for (i = 0; i < msixcnt; i++) { irq_entry = &idxd->irq_entries[i]; @@ -815,7 +823,7 @@ static void idxd_remove(struct pci_dev *pdev) pci_disable_device(pdev); destroy_workqueue(idxd->wq); perfmon_pmu_remove(idxd); - device_unregister(idxd_confdev(idxd)); + put_device(idxd_confdev(idxd)); }
static struct pci_driver idxd_pci_driver = {
From: Dave Jiang dave.jiang@intel.com
[ Upstream commit e530a9f3db4188d1f4e3704b0948ef69c04d5ca6 ]
Device reset clears the MSIXPERM table and the device registers. Re-program the MSIXPERM table and re-enable the error interrupts post reset.
Fixes: 745e92a6d816 ("dmaengine: idxd: idxd: move remove() bits for idxd 'struct device' to device.c") Reported-by: Sanjay Kumar sanjay.k.kumar@intel.com Signed-off-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/163054188513.2853562.12077053294595278181.stgit@dj... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/idxd/device.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index cbbfa17d8d11b..419b206f8a42d 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -583,6 +583,8 @@ void idxd_device_reset(struct idxd_device *idxd) spin_lock(&idxd->dev_lock); idxd_device_clear_state(idxd); idxd->state = IDXD_DEV_DISABLED; + idxd_unmask_error_interrupts(idxd); + idxd_msix_perm_setup(idxd); spin_unlock(&idxd->dev_lock); }
From: Eric W. Biederman ebiederm@xmission.com
[ Upstream commit ce0ee4e6ac99606f3945f4d47775544edc3f7985 ]
Today the sh code allocates memory the first time a process uses the fpu. If that memory allocation fails, kill the affected task with force_sig(SIGKILL) rather than do_group_exit(SIGKILL).
Calling do_group_exit from an exception handler can potentially lead to dead locks as do_group_exit is not designed to be called from interrupt context. Instead use force_sig(SIGKILL) to kill the userspace process. Sending signals in general and force_sig in particular has been tested from interrupt context so there should be no problems.
Cc: Yoshinori Sato ysato@users.sourceforge.jp Cc: Rich Felker dalias@libc.org Cc: linux-sh@vger.kernel.org Fixes: 0ea820cf9bf5 ("sh: Move over to dynamically allocated FPU context.") Link: https://lkml.kernel.org/r/20211020174406.17889-6-ebiederm@xmission.com Signed-off-by: Eric W. Biederman ebiederm@xmission.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/sh/kernel/cpu/fpu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/sh/kernel/cpu/fpu.c b/arch/sh/kernel/cpu/fpu.c index ae354a2931e7e..fd6db0ab19288 100644 --- a/arch/sh/kernel/cpu/fpu.c +++ b/arch/sh/kernel/cpu/fpu.c @@ -62,18 +62,20 @@ void fpu_state_restore(struct pt_regs *regs) }
if (!tsk_used_math(tsk)) { - local_irq_enable(); + int ret; /* * does a slab alloc which can sleep */ - if (init_fpu(tsk)) { + local_irq_enable(); + ret = init_fpu(tsk); + local_irq_disable(); + if (ret) { /* * ran out of memory! */ - do_group_exit(SIGKILL); + force_sig(SIGKILL); return; } - local_irq_disable(); }
grab_fpu(regs);
From: Randy Dunlap rdunlap@infradead.org
[ Upstream commit 1aaa557b2db95c9506ed0981bc34505c32d6b62b ]
'make randconfig' can produce a .config file with "CONFIG_MEMORY_RESERVE=" (no value) since it has no default. When a subsequent 'make all' is done, kconfig restarts the config and prompts for a value for MEMORY_RESERVE. This breaks scripting/automation where there is no interactive user input.
Add a default value for MEMORY_RESERVE. (Any integer value will work here for kconfig.)
Fixes a kconfig warning:
.config:214:warning: symbol value '' invalid for MEMORY_RESERVE * Restart config... Memory reservation (MiB) (MEMORY_RESERVE) [] (NEW)
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") # from beginning of git history Signed-off-by: Randy Dunlap rdunlap@infradead.org Reviewed-by: Geert Uytterhoeven geert@linux-m68k.org Cc: Greg Ungerer gerg@linux-m68k.org Cc: linux-m68k@lists.linux-m68k.org Signed-off-by: Greg Ungerer gerg@linux-m68k.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/m68k/Kconfig.machine | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine index 36fa0c3ef1296..eeab4f3e6c197 100644 --- a/arch/m68k/Kconfig.machine +++ b/arch/m68k/Kconfig.machine @@ -203,6 +203,7 @@ config INIT_LCD config MEMORY_RESERVE int "Memory reservation (MiB)" depends on (UCSIMM || UCDIMM) + default 0 help Reserve certain memory regions on 68x328 based boards.
From: Ahmad Fatoum a.fatoum@pengutronix.de
[ Upstream commit 164483c735190775f29d0dcbac0363adc51a068d ]
The fintek watchdog timer can configure timeouts of second granularity only up to 255 seconds. Beyond that, the timeout needs to be configured with minute granularity. WDIOC_GETTIMEOUT should report the actual timeout configured, not just echo back the timeout configured by the user. Do so.
Fixes: 96cb4eb019ce ("watchdog: f71808e_wdt: new watchdog driver for Fintek F71808E and F71882FG") Suggested-by: Guenter Roeck linux@roeck-us.net Reviewed-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Ahmad Fatoum a.fatoum@pengutronix.de Link: https://lore.kernel.org/r/5e17960fe8cc0e3cb2ba53de4730b75d9a0f33d5.162852595... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/watchdog/f71808e_wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index f60beec1bbaea..f7d82d2619133 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c @@ -228,15 +228,17 @@ static int watchdog_set_timeout(int timeout)
mutex_lock(&watchdog.lock);
- watchdog.timeout = timeout; if (timeout > 0xff) { watchdog.timer_val = DIV_ROUND_UP(timeout, 60); watchdog.minutes_mode = true; + timeout = watchdog.timer_val * 60; } else { watchdog.timer_val = timeout; watchdog.minutes_mode = false; }
+ watchdog.timeout = timeout; + mutex_unlock(&watchdog.lock);
return 0;
From: Jackie Liu liuyun01@kylinos.cn
[ Upstream commit 28b7ee33a2122569ac065cad578bf23f50cc65c3 ]
TI AR7 Watchdog Timer is only build for 32bit.
Avoid error like: In file included from drivers/watchdog/ar7_wdt.c:29: ./arch/mips/include/asm/mach-ar7/ar7.h: In function ‘ar7_is_titan’: ./arch/mips/include/asm/mach-ar7/ar7.h:111:24: error: implicit declaration of function ‘KSEG1ADDR’; did you mean ‘CKSEG1ADDR’? [-Werror=implicit-function-declaration] 111 | return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x24)) & 0xffff) == | ^~~~~~~~~ | CKSEG1ADDR
Fixes: da2a68b3eb47 ("watchdog: Enable COMPILE_TEST where possible") Signed-off-by: Jackie Liu liuyun01@kylinos.cn Reviewed-by: Guenter Roeck linux@roeck-us.net Link: https://lore.kernel.org/r/20210907024904.4127611-1-liu.yun@linux.dev Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Wim Van Sebroeck wim@linux-watchdog.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index bf59faeb3de1b..d937f957f8df8 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1679,7 +1679,7 @@ config SIBYTE_WDOG
config AR7_WDT tristate "TI AR7 Watchdog Timer" - depends on AR7 || (MIPS && COMPILE_TEST) + depends on AR7 || (MIPS && 32BIT && COMPILE_TEST) help Hardware driver for the TI AR7 Watchdog Timer.
From: Dmitry Bogdanov d.bogdanov@yadro.com
[ Upstream commit 12b6fcd0ea7f3cb7c3b34668fc678779924123ae ]
Currently TMF commands are removed from de_device.dev_tmf_list at the very end of se_cmd lifecycle. However, se_lun unlinks from se_cmd upon a command status (response) being queued in transport layer. This means that LUN and backend device can be deleted in the meantime and a panic will occur:
target_tmr_work() cmd->se_tfo->queue_tm_rsp(cmd); // send abort_rsp to a wire transport_lun_remove_cmd(cmd) // unlink se_cmd from se_lun - // - // - // - <<<--- lun remove <<<--- core backend device remove - // - // - // - qlt_handle_abts_completion() tfo->free_mcmd() transport_generic_free_cmd() target_put_sess_cmd() core_tmr_release_req() { if (dev) { // backend device, can not be null spin_lock_irqsave(&dev->se_tmr_lock, flags); //<<<--- CRASH
Call Trace: NIP [c000000000e1683c] _raw_spin_lock_irqsave+0x2c/0xc0 LR [c00800000e433338] core_tmr_release_req+0x40/0xa0 [target_core_mod] Call Trace: (unreliable) 0x0 target_put_sess_cmd+0x2a0/0x370 [target_core_mod] transport_generic_free_cmd+0x6c/0x1b0 [target_core_mod] tcm_qla2xxx_complete_mcmd+0x28/0x50 [tcm_qla2xxx] process_one_work+0x2c4/0x5c0 worker_thread+0x88/0x690
For the iSCSI protocol this is easily reproduced:
- Send some SCSI sommand
- Send Abort of that command over iSCSI
- Remove LUN on target
- Send next iSCSI command to acknowledge the Abort_Response
- Target panics
There is no need to keep the command in tmr_list until response completion, so move the removal from tmr_list from the response completion to the response queueing when the LUN is unlinked. Move the removal from state list too as it is a subject to the same race condition.
Link: https://lore.kernel.org/r/20211018135753.15297-1-d.bogdanov@yadro.com Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") Reviewed-by: Roman Bolshakov r.bolshakov@yadro.com Reviewed-by: Mike Christie michael.christie@oracle.com Signed-off-by: Dmitry Bogdanov d.bogdanov@yadro.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/target/target_core_tmr.c | 17 +-------------- drivers/target/target_core_transport.c | 30 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index e7fcbc09f9dbc..bac111456fa1d 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -50,15 +50,6 @@ EXPORT_SYMBOL(core_tmr_alloc_req);
void core_tmr_release_req(struct se_tmr_req *tmr) { - struct se_device *dev = tmr->tmr_dev; - unsigned long flags; - - if (dev) { - spin_lock_irqsave(&dev->se_tmr_lock, flags); - list_del_init(&tmr->tmr_list); - spin_unlock_irqrestore(&dev->se_tmr_lock, flags); - } - kfree(tmr); }
@@ -156,13 +147,6 @@ void core_tmr_abort_task( se_cmd->state_active = false; spin_unlock_irqrestore(&dev->queues[i].lock, flags);
- /* - * Ensure that this ABORT request is visible to the LU - * RESET code. - */ - if (!tmr->tmr_dev) - WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) < 0); - if (dev->transport->tmr_notify) dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list); @@ -234,6 +218,7 @@ static void core_tmr_drain_tmr_list( }
list_move_tail(&tmr_p->tmr_list, &drain_tmr_list); + tmr_p->tmr_dev = NULL; } spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 14c6f2bb1b01d..e60abd230e90f 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -676,6 +676,21 @@ static void target_remove_from_state_list(struct se_cmd *cmd) spin_unlock_irqrestore(&dev->queues[cmd->cpuid].lock, flags); }
+static void target_remove_from_tmr_list(struct se_cmd *cmd) +{ + struct se_device *dev = NULL; + unsigned long flags; + + if (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) + dev = cmd->se_tmr_req->tmr_dev; + + if (dev) { + spin_lock_irqsave(&dev->se_tmr_lock, flags); + if (cmd->se_tmr_req->tmr_dev) + list_del_init(&cmd->se_tmr_req->tmr_list); + spin_unlock_irqrestore(&dev->se_tmr_lock, flags); + } +} /* * This function is called by the target core after the target core has * finished processing a SCSI command or SCSI TMF. Both the regular command @@ -687,13 +702,6 @@ static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd) { unsigned long flags;
- target_remove_from_state_list(cmd); - - /* - * Clear struct se_cmd->se_lun before the handoff to FE. - */ - cmd->se_lun = NULL; - spin_lock_irqsave(&cmd->t_state_lock, flags); /* * Determine if frontend context caller is requesting the stopping of @@ -728,8 +736,16 @@ static void transport_lun_remove_cmd(struct se_cmd *cmd) if (!lun) return;
+ target_remove_from_state_list(cmd); + target_remove_from_tmr_list(cmd); + if (cmpxchg(&cmd->lun_ref_active, true, false)) percpu_ref_put(&lun->lun_ref); + + /* + * Clear struct se_cmd->se_lun before the handoff to FE. + */ + cmd->se_lun = NULL; }
static void target_complete_failure_work(struct work_struct *work)
From: Quinn Tran qutran@marvell.com
[ Upstream commit bb2ca6b3f09ac20e8357d257d0557ab5ddf6adcd ]
For RSCN of type "Area, Domain, or Fabric", which indicate a portion or entire fabric was disturbed, current driver does not set the scan_need flag to indicate a session was affected by the disturbance. This in turn can lead to I/O timeout and delay of relogin. Hence initiate relogin in the event of fabric disturbance.
Link: https://lore.kernel.org/r/20211026115412.27691-2-njavali@marvell.com Fixes: 1560bafdff9e ("scsi: qla2xxx: Use complete switch scan for RSCN events") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_init.c | 54 +++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 7e64e4730b259..df3884d9f12a2 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1786,16 +1786,52 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea) fc_port_t *fcport; unsigned long flags;
- fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); - if (fcport) { - if (fcport->flags & FCF_FCP2_DEVICE) { - ql_dbg(ql_dbg_disc, vha, 0x2115, - "Delaying session delete for FCP2 portid=%06x %8phC ", - fcport->d_id.b24, fcport->port_name); - return; + switch (ea->id.b.rsvd_1) { + case RSCN_PORT_ADDR: + fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1); + if (fcport) { + if (fcport->flags & FCF_FCP2_DEVICE) { + ql_dbg(ql_dbg_disc, vha, 0x2115, + "Delaying session delete for FCP2 portid=%06x %8phC ", + fcport->d_id.b24, fcport->port_name); + return; + } + fcport->scan_needed = 1; + fcport->rscn_gen++; + } + break; + case RSCN_AREA_ADDR: + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->flags & FCF_FCP2_DEVICE) + continue; + + if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) { + fcport->scan_needed = 1; + fcport->rscn_gen++; + } } - fcport->scan_needed = 1; - fcport->rscn_gen++; + break; + case RSCN_DOM_ADDR: + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->flags & FCF_FCP2_DEVICE) + continue; + + if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) { + fcport->scan_needed = 1; + fcport->rscn_gen++; + } + } + break; + case RSCN_FAB_ADDR: + default: + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (fcport->flags & FCF_FCP2_DEVICE) + continue; + + fcport->scan_needed = 1; + fcport->rscn_gen++; + } + break; }
spin_lock_irqsave(&vha->work_lock, flags);
From: Quinn Tran qutran@marvell.com
[ Upstream commit c98c5daaa24b583cba1369b7d167f93c6ae7299c ]
Current code does list element deletion and addition in and out of lock protection. This patch moves deletion behind lock.
list_add double add: new=ffff9130b5eb89f8, prev=ffff9130b5eb89f8, next=ffff9130c6a715f0. ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:31! invalid opcode: 0000 [#1] SMP PTI CPU: 1 PID: 182395 Comm: kworker/1:37 Kdump: loaded Tainted: G W OE --------- - - 4.18.0-193.el8.x86_64 #1 Hardware name: HP ProLiant DL160 Gen8, BIOS J03 02/10/2014 Workqueue: qla2xxx_wq qla2x00_iocb_work_fn [qla2xxx] RIP: 0010:__list_add_valid+0x41/0x50 Code: 85 94 00 00 00 48 39 c7 74 0b 48 39 d7 74 06 b8 01 00 00 00 c3 48 89 f2 4c 89 c1 48 89 fe 48 c7 c7 60 83 ad 97 e8 4d bd ce ff <0f> 0b 0f 1f 00 66 2e 0f 1f 84 00 00 00 00 00 48 8b 07 48 8b 57 08 RSP: 0018:ffffaba306f47d68 EFLAGS: 00010046 RAX: 0000000000000058 RBX: ffff9130b5eb8800 RCX: 0000000000000006 RDX: 0000000000000000 RSI: 0000000000000096 RDI: ffff9130b7456a00 RBP: ffff9130c6a70a58 R08: 000000000008d7be R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000001 R12: ffff9130c6a715f0 R13: ffff9130b5eb8824 R14: ffff9130b5eb89f8 R15: ffff9130b5eb89f8 FS: 0000000000000000(0000) GS:ffff9130b7440000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007efcaaef11a0 CR3: 000000005200a002 CR4: 00000000000606e0 Call Trace: qla24xx_async_gnl+0x113/0x3c0 [qla2xxx] ? qla2x00_iocb_work_fn+0x53/0x80 [qla2xxx] ? process_one_work+0x1a7/0x3b0 ? worker_thread+0x30/0x390 ? create_worker+0x1a0/0x1a0 ? kthread+0x112/0x130
Link: https://lore.kernel.org/r/20211026115412.27691-3-njavali@marvell.com Fixes: 726b85487067 ("qla2xxx: Add framework for async fabric discovery") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_init.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index df3884d9f12a2..6da4419bcec16 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -987,8 +987,6 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) sp->name, res, sp->u.iocb_cmd.u.mbx.in_mb[1], sp->u.iocb_cmd.u.mbx.in_mb[2]);
- if (res == QLA_FUNCTION_TIMEOUT) - return;
sp->fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE); memset(&ea, 0, sizeof(ea)); @@ -1026,8 +1024,8 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
list_for_each_entry_safe(fcport, tf, &h, gnl_entry) { - list_del_init(&fcport->gnl_entry); spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); + list_del_init(&fcport->gnl_entry); fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); ea.fcport = fcport;
From: Quinn Tran qutran@marvell.com
[ Upstream commit 0b7a9fd934a68ebfc1019811b7bdc1742072ad7b ]
When user uses issue_lip to do link bounce, driver sends additional target reset to remote device before resetting the link. The target reset would affect other paths with active I/Os. This patch will remove the unnecessary target reset.
Link: https://lore.kernel.org/r/20211026115412.27691-4-njavali@marvell.com Fixes: 5854771e314e ("[SCSI] qla2xxx: Add ISPFX00 specific bus reset routine") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_gbl.h | 2 -- drivers/scsi/qla2xxx/qla_mr.c | 23 ----------------------- drivers/scsi/qla2xxx/qla_os.c | 27 ++------------------------- 3 files changed, 2 insertions(+), 50 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 1c3f055d41b8e..0a43ce9317db2 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -171,7 +171,6 @@ extern int ql2xasynctmfenable; extern int ql2xgffidenable; extern int ql2xenabledif; extern int ql2xenablehba_err_chk; -extern int ql2xtargetreset; extern int ql2xdontresethba; extern uint64_t ql2xmaxlun; extern int ql2xmdcapmask; @@ -816,7 +815,6 @@ extern void qlafx00_abort_iocb(srb_t *, struct abort_iocb_entry_fx00 *); extern void qlafx00_fxdisc_iocb(srb_t *, struct fxdisc_entry_fx00 *); extern void qlafx00_timer_routine(scsi_qla_host_t *); extern int qlafx00_rescan_isp(scsi_qla_host_t *); -extern int qlafx00_loop_reset(scsi_qla_host_t *vha);
/* qla82xx related functions */
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 6e920da64863e..350b0c4346fb6 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -738,29 +738,6 @@ qlafx00_lun_reset(fc_port_t *fcport, uint64_t l, int tag) return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag); }
-int -qlafx00_loop_reset(scsi_qla_host_t *vha) -{ - int ret; - struct fc_port *fcport; - struct qla_hw_data *ha = vha->hw; - - if (ql2xtargetreset) { - list_for_each_entry(fcport, &vha->vp_fcports, list) { - if (fcport->port_type != FCT_TARGET) - continue; - - ret = ha->isp_ops->target_reset(fcport, 0, 0); - if (ret != QLA_SUCCESS) { - ql_dbg(ql_dbg_taskm, vha, 0x803d, - "Bus Reset failed: Reset=%d " - "d_id=%x.\n", ret, fcport->d_id.b24); - } - } - } - return QLA_SUCCESS; -} - int qlafx00_iospace_config(struct qla_hw_data *ha) { diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index f800d940a720d..b5346d9066dc6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -202,12 +202,6 @@ MODULE_PARM_DESC(ql2xdbwr, " 0 -- Regular doorbell.\n" " 1 -- CAMRAM doorbell (faster).\n");
-int ql2xtargetreset = 1; -module_param(ql2xtargetreset, int, S_IRUGO); -MODULE_PARM_DESC(ql2xtargetreset, - "Enable target reset." - "Default is 1 - use hw defaults."); - int ql2xgffidenable; module_param(ql2xgffidenable, int, S_IRUGO); MODULE_PARM_DESC(ql2xgffidenable, @@ -1695,27 +1689,10 @@ int qla2x00_loop_reset(scsi_qla_host_t *vha) { int ret; - struct fc_port *fcport; struct qla_hw_data *ha = vha->hw;
- if (IS_QLAFX00(ha)) { - return qlafx00_loop_reset(vha); - } - - if (ql2xtargetreset == 1 && ha->flags.enable_target_reset) { - list_for_each_entry(fcport, &vha->vp_fcports, list) { - if (fcport->port_type != FCT_TARGET) - continue; - - ret = ha->isp_ops->target_reset(fcport, 0, 0); - if (ret != QLA_SUCCESS) { - ql_dbg(ql_dbg_taskm, vha, 0x802c, - "Bus Reset failed: Reset=%d " - "d_id=%x.\n", ret, fcport->d_id.b24); - } - } - } - + if (IS_QLAFX00(ha)) + return QLA_SUCCESS;
if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) { atomic_set(&vha->loop_state, LOOP_DOWN);
From: Quinn Tran qutran@marvell.com
[ Upstream commit 8e6d5df3cb32dddf558a52414d29febecb660396 ]
On app start, all sessions need to be reset to see if secure connection can be made. Fix the broken check which prevents that process.
Link: https://lore.kernel.org/r/20211026115412.27691-5-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index ad746c62f0d44..615596becb7a1 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -529,7 +529,8 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) struct app_start_reply appreply; struct fc_port *fcport, *tf;
- ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app start\n", __func__); + ql_log(ql_log_info, vha, 0x1313, + "EDIF application registration with driver, FC device connections will be re-established.\n");
sg_copy_to_buffer(bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, &appstart, @@ -554,37 +555,36 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) qla2xxx_wake_dpc(vha); } else { list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { + ql_dbg(ql_dbg_edif, vha, 0x2058, + "FCSP - nn %8phN pn %8phN portid=%06x.\n", + fcport->node_name, fcport->port_name, + fcport->d_id.b24); ql_dbg(ql_dbg_edif, vha, 0xf084, - "%s: sess %p %8phC lid %#04x s_id %06x logout %d\n", - __func__, fcport, fcport->port_name, - fcport->loop_id, fcport->d_id.b24, - fcport->logout_on_delete); - - ql_dbg(ql_dbg_edif, vha, 0xf084, - "keep %d els_logo %d disc state %d auth state %d stop state %d\n", - fcport->keep_nport_handle, - fcport->send_els_logo, fcport->disc_state, - fcport->edif.auth_state, fcport->edif.app_stop); + "%s: se_sess %p / sess %p from port %8phC " + "loop_id %#04x s_id %06x logout %d " + "keep %d els_logo %d disc state %d auth state %d" + "stop state %d\n", + __func__, fcport->se_sess, fcport, + fcport->port_name, fcport->loop_id, + fcport->d_id.b24, fcport->logout_on_delete, + fcport->keep_nport_handle, fcport->send_els_logo, + fcport->disc_state, fcport->edif.auth_state, + fcport->edif.app_stop);
if (atomic_read(&vha->loop_state) == LOOP_DOWN) break; - if (!(fcport->flags & FCF_FCSP_DEVICE)) - continue;
fcport->edif.app_started = 1; - if (fcport->edif.app_stop || - (fcport->disc_state != DSC_LOGIN_COMPLETE && - fcport->disc_state != DSC_LOGIN_PEND && - fcport->disc_state != DSC_DELETED)) { - /* no activity */ - fcport->edif.app_stop = 0; - - ql_dbg(ql_dbg_edif, vha, 0x911e, - "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", - __func__, fcport->port_name); - fcport->edif.app_sess_online = 1; - qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); - } + fcport->login_retry = vha->hw->login_retry_count; + + /* no activity */ + fcport->edif.app_stop = 0; + + ql_dbg(ql_dbg_edif, vha, 0x911e, + "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", + __func__, fcport->port_name); + fcport->edif.app_sess_online = 1; + qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); qla_edif_sa_ctl_init(vha, fcport); } }
From: Quinn Tran qutran@marvell.com
[ Upstream commit b492d6a4880fddce098472dec5086d37802c68d3 ]
Current driver does unnecessary pause for each session to get to certain state before allowing the app start call to return. In larger environment, this introduces a long delay. Originally the delay was meant to synchronize app and driver. However, the with current implementation the two sides use various events to synchronize their state.
The same is applied to the authentication failure call.
Link: https://lore.kernel.org/r/20211026115412.27691-6-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 64 ++------------------------------- 1 file changed, 3 insertions(+), 61 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 615596becb7a1..cf62f26ce27d9 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -290,63 +290,6 @@ qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid) return false; }
-static void qla_edif_reset_auth_wait(struct fc_port *fcport, int state, - int waitonly) -{ - int cnt, max_cnt = 200; - bool traced = false; - - fcport->keep_nport_handle = 1; - - if (!waitonly) { - qla2x00_set_fcport_disc_state(fcport, state); - qlt_schedule_sess_for_deletion(fcport); - } else { - qla2x00_set_fcport_disc_state(fcport, state); - } - - ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, - "%s: waiting for session, max_cnt=%u\n", - __func__, max_cnt); - - cnt = 0; - - if (waitonly) { - /* Marker wait min 10 msecs. */ - msleep(50); - cnt += 50; - } - while (1) { - if (!traced) { - ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, - "%s: session sleep.\n", - __func__); - traced = true; - } - msleep(20); - cnt++; - if (waitonly && (fcport->disc_state == state || - fcport->disc_state == DSC_LOGIN_COMPLETE)) - break; - if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) - break; - if (cnt > max_cnt) - break; - } - - if (!waitonly) { - ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, - "%s: waited for session - %8phC, loopid=%x portid=%06x fcport=%p state=%u, cnt=%u\n", - __func__, fcport->port_name, fcport->loop_id, - fcport->d_id.b24, fcport, fcport->disc_state, cnt); - } else { - ql_dbg(ql_dbg_edif, fcport->vha, 0xf086, - "%s: waited ONLY for session - %8phC, loopid=%x portid=%06x fcport=%p state=%u, cnt=%u\n", - __func__, fcport->port_name, fcport->loop_id, - fcport->d_id.b24, fcport, fcport->disc_state, cnt); - } -} - static void qla_edif_free_sa_ctl(fc_port_t *fcport, struct edif_sa_ctl *sa_ctl, int index) @@ -583,8 +526,8 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) ql_dbg(ql_dbg_edif, vha, 0x911e, "%s wwpn %8phC calling qla_edif_reset_auth_wait\n", __func__, fcport->port_name); - fcport->edif.app_sess_online = 1; - qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); + fcport->edif.app_sess_online = 0; + qlt_schedule_sess_for_deletion(fcport); qla_edif_sa_ctl_init(vha, fcport); } } @@ -800,7 +743,6 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job) ql_dbg(ql_dbg_edif, vha, 0x911e, "%s AUTH complete - RESUME with prli for wwpn %8phC\n", __func__, fcport->port_name); - qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 1); qla24xx_post_prli_work(vha, fcport); }
@@ -873,7 +815,7 @@ qla_edif_app_authfail(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
if (qla_ini_mode_enabled(fcport->vha)) { fcport->send_els_logo = 1; - qla_edif_reset_auth_wait(fcport, DSC_LOGIN_PEND, 0); + qlt_schedule_sess_for_deletion(fcport); } }
From: Quinn Tran qutran@marvell.com
[ Upstream commit b1af26c245545a289b331c7b71996ecd88321540 ]
On session down, driver will flush all stale messages and doorbell events. This prevents authentication application from having to process stale data.
Link: https://lore.kernel.org/r/20211026115412.27691-7-njavali@marvell.com Fixes: 4de067e5df12 ("scsi: qla2xxx: edif: Add N2N support for EDIF") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Co-developed-by: Karunakara Merugu kmerugu@marvell.com Signed-off-by: Karunakara Merugu kmerugu@marvell.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 96 ++++++++++++++++++++++++++++++- drivers/scsi/qla2xxx/qla_gbl.h | 2 + drivers/scsi/qla2xxx/qla_target.c | 1 + 3 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index cf62f26ce27d9..3931bae3222b3 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -1593,6 +1593,40 @@ qla_enode_stop(scsi_qla_host_t *vha) spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags); }
+static void qla_enode_clear(scsi_qla_host_t *vha, port_id_t portid) +{ + unsigned long flags; + struct enode *e, *tmp; + struct purexevent *purex; + LIST_HEAD(enode_list); + + if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) { + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s enode not active\n", __func__); + return; + } + spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags); + list_for_each_entry_safe(e, tmp, &vha->pur_cinfo.head, list) { + purex = &e->u.purexinfo; + if (purex->pur_info.pur_sid.b24 == portid.b24) { + ql_dbg(ql_dbg_edif, vha, 0x911d, + "%s free ELS sid=%06x. xchg %x, nb=%xh\n", + __func__, portid.b24, + purex->pur_info.pur_rx_xchg_address, + purex->pur_info.pur_bytes_rcvd); + + list_del_init(&e->list); + list_add_tail(&e->list, &enode_list); + } + } + spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags); + + list_for_each_entry_safe(e, tmp, &enode_list, list) { + list_del_init(&e->list); + qla_enode_free(vha, e); + } +} + /* * allocate enode struct and populate buffer * returns: enode pointer with buffers @@ -1792,6 +1826,57 @@ qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node) node->ntype = N_UNDEF; }
+static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid) +{ + unsigned long flags; + struct edb_node *e, *tmp; + port_id_t sid; + LIST_HEAD(edb_list); + + if (vha->e_dbell.db_flags != EDB_ACTIVE) { + /* doorbell list not enabled */ + ql_dbg(ql_dbg_edif, vha, 0x09102, + "%s doorbell not enabled\n", __func__); + return; + } + + /* grab lock so list doesn't move */ + spin_lock_irqsave(&vha->e_dbell.db_lock, flags); + list_for_each_entry_safe(e, tmp, &vha->e_dbell.head, list) { + switch (e->ntype) { + case VND_CMD_AUTH_STATE_NEEDED: + case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN: + sid = e->u.plogi_did; + break; + case VND_CMD_AUTH_STATE_ELS_RCVD: + sid = e->u.els_sid; + break; + case VND_CMD_AUTH_STATE_SAUPDATE_COMPL: + /* app wants to see this */ + continue; + default: + ql_log(ql_log_warn, vha, 0x09102, + "%s unknown node type: %x\n", __func__, e->ntype); + sid.b24 = 0; + break; + } + if (sid.b24 == portid.b24) { + ql_dbg(ql_dbg_edif, vha, 0x910f, + "%s free doorbell event : node type = %x %p\n", + __func__, e->ntype, e); + list_del_init(&e->list); + list_add_tail(&e->list, &edb_list); + } + } + spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags); + + list_for_each_entry_safe(e, tmp, &edb_list, list) { + qla_edb_node_free(vha, e); + list_del_init(&e->list); + kfree(e); + } +} + /* function called when app is stopping */
void @@ -2378,7 +2463,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) ql_dbg(ql_dbg_edif, host, 0x0910c, "%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n", __func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24, - purex->pur_info.pur_did.b24, p->rx_xchg_addr); + purex->pur_info.pur_did.b24, purex->pur_info.pur_rx_xchg_address);
qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL); } @@ -3401,3 +3486,12 @@ void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess) qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24); } } + +void qla_edif_clear_appdata(struct scsi_qla_host *vha, struct fc_port *fcport) +{ + if (!(fcport->flags & FCF_FCSP_DEVICE)) + return; + + qla_edb_clear(vha, fcport->d_id); + qla_enode_clear(vha, fcport->d_id); +} diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 0a43ce9317db2..2c7e91bffb827 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -142,6 +142,8 @@ void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport, void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport); int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsgjob); void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess); +void qla_edif_clear_appdata(struct scsi_qla_host *vha, + struct fc_port *fcport); const char *sc_to_str(uint16_t cmd);
/* diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 7d8242c120fc7..1aaa4238cb722 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1003,6 +1003,7 @@ void qlt_free_session_done(struct work_struct *work) "%s bypassing release_all_sadb\n", __func__); } + qla_edif_clear_appdata(vha, sess); qla_edif_sess_down(vha, sess); } qla2x00_mark_device_lost(vha, sess, 0);
From: Quinn Tran qutran@marvell.com
[ Upstream commit 0f6d600a26e89d31d8381b324fc970f72579a126 ]
Currently, firmware limits ELS payload to FC frame size/2112. This patch adjusts memory buffer size to be able to handle max ELS payload.
Link: https://lore.kernel.org/r/20211026115412.27691-11-njavali@marvell.com Fixes: 84318a9f01ce ("scsi: qla2xxx: edif: Add send, receive, and accept for auth_els") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 2 +- drivers/scsi/qla2xxx/qla_edif.h | 3 ++- drivers/scsi/qla2xxx/qla_edif_bsg.h | 2 +- drivers/scsi/qla2xxx/qla_init.c | 4 ++++ drivers/scsi/qla2xxx/qla_os.c | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 3931bae3222b3..98235df803aef 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -2384,7 +2384,7 @@ void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp) return; }
- if (totlen > MAX_PAYLOAD) { + if (totlen > ELS_MAX_PAYLOAD) { ql_dbg(ql_dbg_edif, vha, 0x0910d, "%s WARNING: verbose ELS frame received (totlen=%x)\n", __func__, totlen); diff --git a/drivers/scsi/qla2xxx/qla_edif.h b/drivers/scsi/qla2xxx/qla_edif.h index 9e8f28d0caa1b..45cf87e337780 100644 --- a/drivers/scsi/qla2xxx/qla_edif.h +++ b/drivers/scsi/qla2xxx/qla_edif.h @@ -93,7 +93,6 @@ struct sa_update_28xx { };
#define NUM_ENTRIES 256 -#define MAX_PAYLOAD 1024 #define PUR_GET 1
struct dinfo { @@ -128,6 +127,8 @@ struct enode { } u; };
+#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES)) + #define EDIF_SESSION_DOWN(_s) \ (qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \ _s->disc_state == DSC_DELETED || \ diff --git a/drivers/scsi/qla2xxx/qla_edif_bsg.h b/drivers/scsi/qla2xxx/qla_edif_bsg.h index 58b718d35d19a..53026d82ebffe 100644 --- a/drivers/scsi/qla2xxx/qla_edif_bsg.h +++ b/drivers/scsi/qla2xxx/qla_edif_bsg.h @@ -8,7 +8,7 @@ #define __QLA_EDIF_BSG_H
/* BSG Vendor specific commands */ -#define ELS_MAX_PAYLOAD 1024 +#define ELS_MAX_PAYLOAD 2112 #ifndef WWN_SIZE #define WWN_SIZE 8 #endif diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 6da4419bcec16..847a6e5d9cb07 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4467,6 +4467,10 @@ qla2x00_init_rings(scsi_qla_host_t *vha) (ha->flags.fawwpn_enabled) ? "enabled" : "disabled"); }
+ /* ELS pass through payload is limit by frame size. */ + if (ha->flags.edif_enabled) + mid_init_cb->init_cb.frame_payload_size = cpu_to_le16(ELS_MAX_PAYLOAD); + rval = qla2x00_init_firmware(vha, ha->init_cb_size); next_check: if (rval) { diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b5346d9066dc6..8d87cfae9c598 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4337,7 +4337,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
/* allocate the purex dma pool */ ha->purex_dma_pool = dma_pool_create(name, &ha->pdev->dev, - MAX_PAYLOAD, 8, 0); + ELS_MAX_PAYLOAD, 8, 0);
if (!ha->purex_dma_pool) { ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b,
From: Quinn Tran qutran@marvell.com
[ Upstream commit 9fd26c633e8ab5a291c0241533efff161bbe5570 ]
Various EDIF bsgs did not properly fill out the reply_payload_rcv_len field. This causes app to parse empty data in the return payload.
Link: https://lore.kernel.org/r/20211026115412.27691-13-njavali@marvell.com Fixes: 7ebb336e45ef ("scsi: qla2xxx: edif: Add start + stop bsgs") Reviewed-by: Himanshu Madhani himanshu.madhani@oracle.com Signed-off-by: Quinn Tran qutran@marvell.com Signed-off-by: Nilesh Javali njavali@marvell.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/qla2xxx/qla_edif.c | 49 ++++++++++++++++----------------- 1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index 98235df803aef..9240e788b011d 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -544,14 +544,14 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job) appreply.edif_enode_active = vha->pur_cinfo.enode_flags; appreply.edif_edb_active = vha->e_dbell.db_flags;
- bsg_job->reply_len = sizeof(struct fc_bsg_reply) + - sizeof(struct app_start_reply); + bsg_job->reply_len = sizeof(struct fc_bsg_reply);
SET_DID_STATUS(bsg_reply->result, DID_OK);
- sg_copy_from_buffer(bsg_job->reply_payload.sg_list, - bsg_job->reply_payload.sg_cnt, &appreply, - sizeof(struct app_start_reply)); + bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, + &appreply, + sizeof(struct app_start_reply));
ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app start completed with 0x%x\n", @@ -748,9 +748,10 @@ qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
errstate_exit: bsg_job->reply_len = sizeof(struct fc_bsg_reply); - sg_copy_from_buffer(bsg_job->reply_payload.sg_list, - bsg_job->reply_payload.sg_cnt, &appplogireply, - sizeof(struct app_plogi_reply)); + bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, + &appplogireply, + sizeof(struct app_plogi_reply));
return rval; } @@ -833,7 +834,7 @@ static int qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) { int32_t rval = 0; - int32_t num_cnt; + int32_t pcnt = 0; struct fc_bsg_reply *bsg_reply = bsg_job->reply; struct app_pinfo_req app_req; struct app_pinfo_reply *app_reply; @@ -845,16 +846,14 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) bsg_job->request_payload.sg_cnt, &app_req, sizeof(struct app_pinfo_req));
- num_cnt = app_req.num_ports; /* num of ports alloc'd by app */ - app_reply = kzalloc((sizeof(struct app_pinfo_reply) + - sizeof(struct app_pinfo) * num_cnt), GFP_KERNEL); + sizeof(struct app_pinfo) * app_req.num_ports), GFP_KERNEL); + if (!app_reply) { SET_DID_STATUS(bsg_reply->result, DID_ERROR); rval = -1; } else { struct fc_port *fcport = NULL, *tf; - uint32_t pcnt = 0;
list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { if (!(fcport->flags & FCF_FCSP_DEVICE)) @@ -923,9 +922,11 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job) SET_DID_STATUS(bsg_reply->result, DID_OK); }
- sg_copy_from_buffer(bsg_job->reply_payload.sg_list, - bsg_job->reply_payload.sg_cnt, app_reply, - sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * num_cnt); + bsg_job->reply_len = sizeof(struct fc_bsg_reply); + bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list, + bsg_job->reply_payload.sg_cnt, + app_reply, + sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * pcnt);
kfree(app_reply);
@@ -942,10 +943,11 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) { int32_t rval = 0; struct fc_bsg_reply *bsg_reply = bsg_job->reply; - uint32_t ret_size, size; + uint32_t size;
struct app_sinfo_req app_req; struct app_stats_reply *app_reply; + uint32_t pcnt = 0;
sg_copy_to_buffer(bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, &app_req, @@ -961,18 +963,12 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) size = sizeof(struct app_stats_reply) + (sizeof(struct app_sinfo) * app_req.num_ports);
- if (size > bsg_job->reply_payload.payload_len) - ret_size = bsg_job->reply_payload.payload_len; - else - ret_size = size; - app_reply = kzalloc(size, GFP_KERNEL); if (!app_reply) { SET_DID_STATUS(bsg_reply->result, DID_ERROR); rval = -1; } else { struct fc_port *fcport = NULL, *tf; - uint32_t pcnt = 0;
list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) { if (fcport->edif.enable) { @@ -996,9 +992,11 @@ qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job) SET_DID_STATUS(bsg_reply->result, DID_OK); }
+ bsg_job->reply_len = sizeof(struct fc_bsg_reply); bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list, - bsg_job->reply_payload.sg_cnt, app_reply, ret_size); + bsg_job->reply_payload.sg_cnt, app_reply, + sizeof(struct app_stats_reply) + (sizeof(struct app_sinfo) * pcnt));
kfree(app_reply);
@@ -1072,8 +1070,7 @@ qla_edif_app_mgmt(struct bsg_job *bsg_job) __func__, bsg_request->rqst_data.h_vendor.vendor_cmd[1]); rval = EXT_STATUS_INVALID_PARAM; - bsg_job->reply_len = sizeof(struct fc_bsg_reply); - SET_DID_STATUS(bsg_reply->result, DID_ERROR); + done = false; break; }
From: Trond Myklebust trond.myklebust@hammerspace.com
[ Upstream commit 01d29f87fcfef38d51ce2b473981a5c1e861ac0a ]
If we already hold open state on the client, yet the server gives us a completely different stateid to the one we already hold, then we currently treat it as if it were an out-of-sequence update, and wait for 5 seconds for other updates to come in. This commit fixes the behaviour so that we immediately start processing of the new stateid, and then leave it to the call to nfs4_test_and_free_stateid() to decide what to do with the old stateid.
Fixes: b4868b44c562 ("NFSv4: Wait for stateid updates after CLOSE/OPEN_DOWNGRADE") Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e1214bb6b7ee5..1f38f8cd8c3ce 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1609,15 +1609,16 @@ static bool nfs_stateid_is_sequential(struct nfs4_state *state, { if (test_bit(NFS_OPEN_STATE, &state->flags)) { /* The common case - we're updating to a new sequence number */ - if (nfs4_stateid_match_other(stateid, &state->open_stateid) && - nfs4_stateid_is_next(&state->open_stateid, stateid)) { - return true; + if (nfs4_stateid_match_other(stateid, &state->open_stateid)) { + if (nfs4_stateid_is_next(&state->open_stateid, stateid)) + return true; + return false; } - } else { - /* This is the first OPEN in this generation */ - if (stateid->seqid == cpu_to_be32(1)) - return true; + /* The server returned a new stateid */ } + /* This is the first OPEN in this generation */ + if (stateid->seqid == cpu_to_be32(1)) + return true; return false; }
From: Dave Jiang dave.jiang@intel.com
[ Upstream commit a3e340c1574b6679f5b333221284d0959095da52 ]
The wq resources needs to be released before the kernel type is reset by __drv_disable_wq(). With dma channels unregistered and wq quiesced, all the wq resources for dmaengine can be freed. There is no need to wait until wq is disabled. With the wq->type being reset to "unknown", the driver is skipping the freeing of the resources.
Fixes: 0cda4f6986a3 ("dmaengine: idxd: create dmaengine driver for wq 'device'") Reported-by: Jacob Pan jacob.jun.pan@linux.intel.com Tested-by: Jacob Pan jacob.jun.pan@linux.intel.com Signed-off-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/163517405099.3484556.12521975053711345244.stgit@dj... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/idxd/dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/dma/idxd/dma.c b/drivers/dma/idxd/dma.c index b90b085d18cff..c39e9483206ad 100644 --- a/drivers/dma/idxd/dma.c +++ b/drivers/dma/idxd/dma.c @@ -329,10 +329,9 @@ static void idxd_dmaengine_drv_remove(struct idxd_dev *idxd_dev) mutex_lock(&wq->wq_lock); idxd_wq_quiesce(wq); idxd_unregister_dma_channel(wq); + idxd_wq_free_resources(wq); __drv_disable_wq(wq); percpu_ref_exit(&wq->wq_active); - idxd_wq_free_resources(wq); - wq->type = IDXD_WQT_NONE; mutex_unlock(&wq->wq_lock); }
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 7f98960c046ee1136e7096aee168eda03aef8a5d ]
A successful 'clk_prepare()' call should be balanced by a corresponding 'clk_unprepare()' call in the error handling path of the probe, as already done in the remove function.
More specifically, 'clk_prepare_enable()' is used, but 'clk_disable()' is also already called. So just the unprepare step has still to be done.
Update the error handling path accordingly.
Fixes: 75d31c2372e4 ("i2c: xlr: add support for Sigma Designs controller variant") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Wolfram Sang wsa@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i2c/busses/i2c-xlr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-xlr.c b/drivers/i2c/busses/i2c-xlr.c index 126d1393e548b..9ce20652d4942 100644 --- a/drivers/i2c/busses/i2c-xlr.c +++ b/drivers/i2c/busses/i2c-xlr.c @@ -431,11 +431,15 @@ static int xlr_i2c_probe(struct platform_device *pdev) i2c_set_adapdata(&priv->adap, priv); ret = i2c_add_numbered_adapter(&priv->adap); if (ret < 0) - return ret; + goto err_unprepare_clk;
platform_set_drvdata(pdev, priv); dev_info(&priv->adap.dev, "Added I2C Bus.\n"); return 0; + +err_unprepare_clk: + clk_unprepare(clk); + return ret; }
static int xlr_i2c_remove(struct platform_device *pdev)
From: Sander Vanheule sander@svanheule.net
[ Upstream commit 585a07079909ba9061ddd88214c36653e1aef71a ]
The irqchip uses one domain for all GPIO lines, so the line offset should be determined w.r.t. the first line of the first port, not the first line of the triggered port.
Fixes: 0d82fb1127fb ("gpio: Add Realtek Otto GPIO support") Signed-off-by: Sander Vanheule sander@svanheule.net Signed-off-by: Bartosz Golaszewski brgl@bgdev.pl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpio-realtek-otto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c index eeeb39bc171dc..bd75401b549d1 100644 --- a/drivers/gpio/gpio-realtek-otto.c +++ b/drivers/gpio/gpio-realtek-otto.c @@ -205,7 +205,7 @@ static void realtek_gpio_irq_handler(struct irq_desc *desc) status = realtek_gpio_read_isr(ctrl, lines_done / 8); port_pin_count = min(gc->ngpio - lines_done, 8U); for_each_set_bit(offset, &status, port_pin_count) - generic_handle_domain_irq(gc->irq.domain, offset); + generic_handle_domain_irq(gc->irq.domain, offset + lines_done); }
chained_irq_exit(irq_chip, desc);
From: YueHaibing yuehaibing@huawei.com
[ Upstream commit 4745ea2628bb43a7ec34b71763b5a56407b33990 ]
Return NULL instead of passing to ERR_PTR while err is zero, this fix smatch warnings: drivers/xen/xen-pciback/conf_space_capability.c:163 pm_ctrl_init() warn: passing zero to 'ERR_PTR'
Fixes: a92336a1176b ("xen/pciback: Drop two backends, squash and cleanup some code.") Signed-off-by: YueHaibing yuehaibing@huawei.com Reviewed-by: Juergen Gross jgross@suse.com Link: https://lore.kernel.org/r/20211008074417.8260-1-yuehaibing@huawei.com Signed-off-by: Boris Ostrovsky boris.ostrovsky@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/xen-pciback/conf_space_capability.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/xen/xen-pciback/conf_space_capability.c b/drivers/xen/xen-pciback/conf_space_capability.c index 22f13abbe9130..5e53b4817f167 100644 --- a/drivers/xen/xen-pciback/conf_space_capability.c +++ b/drivers/xen/xen-pciback/conf_space_capability.c @@ -160,7 +160,7 @@ static void *pm_ctrl_init(struct pci_dev *dev, int offset) }
out: - return ERR_PTR(err); + return err ? ERR_PTR(err) : NULL; }
static const struct config_field caplist_pm[] = {
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit e4c4871a73944353ea23e319de27ef73ce546623 ]
commit b1a811633f73 ("block: nbd: add sanity check for first_minor") checks that 'first_minor' should not be greater than 0xff, which is wrong. Whitout the commit, the details that when user pass 0x100000, it ends up create sysfs dir "/sys/block/43:0" are as follows:
nbd_dev_add disk->first_minor = index << part_shift -> default part_shift is 5, first_minor is 0x2000000 device_add_disk ddev->devt = MKDEV(disk->major, disk->first_minor) -> (0x2b << 20) | (0x2000000) = 0x2b00000 device_add device_create_sys_dev_entry format_dev_t sprintf(buffer, "%u:%u", MAJOR(dev), MINOR(dev)); -> got 43:0 sysfs_create_link -> /sys/block/43:0
By the way, with the wrong fix, when part_shift is the default value, only 8 ndb devices can be created since 8 << 5 is greater than 0xff.
Since the max bits for 'first_minor' should be the same as what MKDEV() does, which is 20. Change the upper bound of 'first_minor' from 0xff to 0xfffff.
Fixes: b1a811633f73 ("block: nbd: add sanity check for first_minor") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Josef Bacik josef@toxicpanda.com Link: https://lore.kernel.org/r/20211102015237.2309763-2-yebin10@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/nbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 4f1b591c3a555..0d820c4dec176 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1749,11 +1749,11 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) disk->major = NBD_MAJOR;
/* Too big first_minor can cause duplicate creation of - * sysfs files/links, since first_minor will be truncated to - * byte in __device_add_disk(). + * sysfs files/links, since MKDEV() expect that the max bits of + * first_minor is 20. */ disk->first_minor = index << part_shift; - if (disk->first_minor > 0xff) { + if (disk->first_minor > MINORMASK) { err = -EINVAL; goto out_free_idr; }
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 940c264984fd1457918393c49674f6b39ee16506 ]
If 'part_shift' is not zero, then 'index << part_shift' might overflow to a value that is not greater than '0xfffff', then sysfs might complains about duplicate creation.
Fixes: b0d9111a2d53 ("nbd: use an idr to keep track of nbd devices") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Josef Bacik josef@toxicpanda.com Link: https://lore.kernel.org/r/20211102015237.2309763-3-yebin10@huawei.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/nbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 0d820c4dec176..577c7dba5d78d 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -1749,11 +1749,11 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) disk->major = NBD_MAJOR;
/* Too big first_minor can cause duplicate creation of - * sysfs files/links, since MKDEV() expect that the max bits of - * first_minor is 20. + * sysfs files/links, since index << part_shift might overflow, or + * MKDEV() expect that the max bits of first_minor is 20. */ disk->first_minor = index << part_shift; - if (disk->first_minor > MINORMASK) { + if (disk->first_minor < index || disk->first_minor > MINORMASK) { err = -EINVAL; goto out_free_idr; }
From: Beld Zhang beldzhang@gmail.com
[ Upstream commit 71c9ce27bb57c59d8d7f5298e730c8096eef3d1f ]
In io-wq.c:io_wq_max_workers(), new_count[] was changed right after each node's value was set. This caused the following node getting the setting of the previous one.
Returned values are copied from node 0.
Fixes: 2e480058ddc2 ("io-wq: provide a way to limit max number of workers") Signed-off-by: Beld Zhang beldzhang@gmail.com [axboe: minor fixups] Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/io-wq.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/fs/io-wq.c b/fs/io-wq.c index 5d189b24a8d4b..8c61315657546 100644 --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -1318,7 +1318,9 @@ int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask) */ int io_wq_max_workers(struct io_wq *wq, int *new_count) { - int i, node, prev = 0; + int prev[IO_WQ_ACCT_NR]; + bool first_node = true; + int i, node;
BUILD_BUG_ON((int) IO_WQ_ACCT_BOUND != (int) IO_WQ_BOUND); BUILD_BUG_ON((int) IO_WQ_ACCT_UNBOUND != (int) IO_WQ_UNBOUND); @@ -1329,6 +1331,9 @@ int io_wq_max_workers(struct io_wq *wq, int *new_count) new_count[i] = task_rlimit(current, RLIMIT_NPROC); }
+ for (i = 0; i < IO_WQ_ACCT_NR; i++) + prev[i] = 0; + rcu_read_lock(); for_each_node(node) { struct io_wqe *wqe = wq->wqes[node]; @@ -1337,14 +1342,19 @@ int io_wq_max_workers(struct io_wq *wq, int *new_count) raw_spin_lock(&wqe->lock); for (i = 0; i < IO_WQ_ACCT_NR; i++) { acct = &wqe->acct[i]; - prev = max_t(int, acct->max_workers, prev); + if (first_node) + prev[i] = max_t(int, acct->max_workers, prev[i]); if (new_count[i]) acct->max_workers = new_count[i]; - new_count[i] = prev; } raw_spin_unlock(&wqe->lock); + first_node = false; } rcu_read_unlock(); + + for (i = 0; i < IO_WQ_ACCT_NR; i++) + new_count[i] = prev[i]; + return 0; }
From: Maxim Kiselev bigunclemax@gmail.com
[ Upstream commit d52bcb47bdf971a59a2467975d2405fcfcb2fa19 ]
This patch allows to use 0 for `coal->rx_coalesce_usecs` param to disable rx irq coalescing.
Previously we could enable rx irq coalescing via ethtool (For ex: `ethtool -C eth0 rx-usecs 2000`) but we couldn't disable it because this part rejects 0 value:
if (!coal->rx_coalesce_usecs) return -EINVAL;
Fixes: 84da2658a619 ("TI DaVinci EMAC : Implement interrupt pacing functionality.") Signed-off-by: Maxim Kiselev bigunclemax@gmail.com Reviewed-by: Grygorii Strashko grygorii.strashko@ti.com Link: https://lore.kernel.org/r/20211101152343.4193233-1-bigunclemax@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ti/davinci_emac.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index e8291d8488391..d243ca5dfde00 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -420,8 +420,20 @@ static int emac_set_coalesce(struct net_device *ndev, u32 int_ctrl, num_interrupts = 0; u32 prescale = 0, addnl_dvdr = 1, coal_intvl = 0;
- if (!coal->rx_coalesce_usecs) - return -EINVAL; + if (!coal->rx_coalesce_usecs) { + priv->coal_intvl = 0; + + switch (priv->version) { + case EMAC_VERSION_2: + emac_ctrl_write(EMAC_DM646X_CMINTCTRL, 0); + break; + default: + emac_ctrl_write(EMAC_CTRL_EWINTTCNT, 0); + break; + } + + return 0; + }
coal_intvl = coal->rx_coalesce_usecs;
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit ca3676f94b8f40f52d285f9aef36dfd6725bfc14 ]
When generating the selftests to another folder, the icmp.sh test will miss as it is not in Makefile, e.g.
make -C tools/testing/selftests/ install \ TARGETS="net" INSTALL_PATH=/tmp/kselftests
Fixes: 7e9838b7915e ("selftests/net: Add icmp.sh for testing ICMP dummy address responses") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 492b273743b4e..9b1c2dfe12530 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -12,7 +12,7 @@ TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_a TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh traceroute.sh TEST_PROGS += fin_ack_lat.sh fib_nexthop_multiprefix.sh fib_nexthops.sh -TEST_PROGS += altnames.sh icmp_redirect.sh ip6_gre_headroom.sh +TEST_PROGS += altnames.sh icmp.sh icmp_redirect.sh ip6_gre_headroom.sh TEST_PROGS += route_localnet.sh TEST_PROGS += reuseaddr_ports_exhausted.sh TEST_PROGS += txtimestamp.sh
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit b99ac1841147eefd8d8b52fcf00d7d917949ae7f ]
When generating the selftests to another folder, the include file setup_loopback.sh/setup_veth.sh for gro.sh/gre_gro.sh are missing as they are not in Makefile, e.g.
make -C tools/testing/selftests/ install \ TARGETS="net" INSTALL_PATH=/tmp/kselftests
Fixes: 7d1575014a63 ("selftests/net: GRO coalesce test") Fixes: 9af771d2ec04 ("selftests/net: allow GRO coalesce test on veth") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 9b1c2dfe12530..63ee01c1437b6 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -28,7 +28,7 @@ TEST_PROGS += veth.sh TEST_PROGS += ioam6.sh TEST_PROGS += gro.sh TEST_PROGS += gre_gso.sh -TEST_PROGS_EXTENDED := in_netns.sh +TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 653e7f19b4a0a632cead2390281bde352d3d3273 ]
When generating the selftests to another folder, the SRv6 tests are missing as they are not in Makefile, e.g.
make -C tools/testing/selftests/ install \ TARGETS="net" INSTALL_PATH=/tmp/kselftests
Fixes: 03a0b567a03d ("selftests: seg6: add selftest for SRv6 End.DT46 Behavior") Fixes: 2195444e09b4 ("selftests: add selftest for the SRv6 End.DT4 behavior") Fixes: 2bc035538e16 ("selftests: add selftest for the SRv6 End.DT6 (VRF) behavior") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/Makefile | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 63ee01c1437b6..8a6264da52763 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -28,6 +28,9 @@ TEST_PROGS += veth.sh TEST_PROGS += ioam6.sh TEST_PROGS += gro.sh TEST_PROGS += gre_gso.sh +TEST_PROGS += srv6_end_dt46_l3vpn_test.sh +TEST_PROGS += srv6_end_dt4_l3vpn_test.sh +TEST_PROGS += srv6_end_dt6_l3vpn_test.sh TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 8883deb50eb6529ae1fd4641e402da8ab4f720d2 ]
When generating the selftests to another folder, the vrf_strict_mode_test.sh test will miss as it is not in Makefile, e.g.
make -C tools/testing/selftests/ install \ TARGETS="net" INSTALL_PATH=/tmp/kselftests
Fixes: 8735e6eaa438 ("selftests: add selftest for the VRF strict mode") Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 8a6264da52763..7328bede35f05 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -31,6 +31,7 @@ TEST_PROGS += gre_gso.sh TEST_PROGS += srv6_end_dt46_l3vpn_test.sh TEST_PROGS += srv6_end_dt4_l3vpn_test.sh TEST_PROGS += srv6_end_dt6_l3vpn_test.sh +TEST_PROGS += vrf_strict_mode_test.sh TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 17b67370c38de2a878debf39dcbc704a206af4d0 ]
When generating the selftests to another folder, the toeplitz.sh and toeplitz_client.sh are missing as they are not in Makefile, e.g.
make -C tools/testing/selftests/ install \ TARGETS="net" INSTALL_PATH=/tmp/kselftests
Making them under TEST_PROGS_EXTENDED as they test NIC hardware features and are not intended to be run from kselftests.
Fixes: 5ebfb4cc3048 ("selftests/net: toeplitz test") Reviewed-by: Willem de Bruijn willemb@google.com Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 7328bede35f05..6a953ec793ced 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -33,6 +33,7 @@ TEST_PROGS += srv6_end_dt4_l3vpn_test.sh TEST_PROGS += srv6_end_dt6_l3vpn_test.sh TEST_PROGS += vrf_strict_mode_test.sh TEST_PROGS_EXTENDED := in_netns.sh setup_loopback.sh setup_veth.sh +TEST_PROGS_EXTENDED += toeplitz_client.sh toeplitz.sh TEST_GEN_FILES = socket nettest TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 1aabe578dd86e9f2867c4db4fba9a15f4ba1825d ]
ETHTOOL_A_PAUSE_STAT_MAX is the MAX attribute id, so we need to subtract non-stats and add one to get a count (IOW -2+1 == -1).
Otherwise we'll see:
ethnl cmd 21: calculated reply length 40, but consumed 52
Fixes: 9a27a33027f2 ("ethtool: add standard pause stats") Signed-off-by: Jakub Kicinski kuba@kernel.org Reviewed-by: Saeed Mahameed saeedm@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/ethtool_netlink.h | 3 +++ include/uapi/linux/ethtool_netlink.h | 4 +++- net/ethtool/pause.c | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/linux/ethtool_netlink.h b/include/linux/ethtool_netlink.h index 1e7bf78cb3829..aba348d58ff61 100644 --- a/include/linux/ethtool_netlink.h +++ b/include/linux/ethtool_netlink.h @@ -10,6 +10,9 @@ #define __ETHTOOL_LINK_MODE_MASK_NWORDS \ DIV_ROUND_UP(__ETHTOOL_LINK_MODE_MASK_NBITS, 32)
+#define ETHTOOL_PAUSE_STAT_CNT (__ETHTOOL_A_PAUSE_STAT_CNT - \ + ETHTOOL_A_PAUSE_STAT_TX_FRAMES) + enum ethtool_multicast_groups { ETHNL_MCGRP_MONITOR, }; diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index 5545f1ca9237c..f7204bdfe8db1 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -407,7 +407,9 @@ enum { ETHTOOL_A_PAUSE_STAT_TX_FRAMES, ETHTOOL_A_PAUSE_STAT_RX_FRAMES,
- /* add new constants above here */ + /* add new constants above here + * adjust ETHTOOL_PAUSE_STAT_CNT if adding non-stats! + */ __ETHTOOL_A_PAUSE_STAT_CNT, ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1) }; diff --git a/net/ethtool/pause.c b/net/ethtool/pause.c index 9009f412151e7..ee1e5806bc93a 100644 --- a/net/ethtool/pause.c +++ b/net/ethtool/pause.c @@ -56,8 +56,7 @@ static int pause_reply_size(const struct ethnl_req_info *req_base,
if (req_base->flags & ETHTOOL_FLAG_STATS) n += nla_total_size(0) + /* _PAUSE_STATS */ - nla_total_size_64bit(sizeof(u64)) * - (ETHTOOL_A_PAUSE_STAT_MAX - 2); + nla_total_size_64bit(sizeof(u64)) * ETHTOOL_PAUSE_STAT_CNT; return n; }
From: Stafford Horne shorne@gmail.com
[ Upstream commit 27dff9a9c247d4e38d82c2e7234914cfe8499294 ]
Throughout the OpenRISC kernel port VMA is passed as NULL when flushing kernel tlb entries. Somehow this was missed when I was testing c28b27416da9 ("openrisc: Implement proper SMP tlb flushing") and now the SMP kernel fails to completely boot.
In OpenRISC VMA is used only to determine which cores need to have their TLB entries flushed.
This patch updates the logic to flush tlbs on all cores when the VMA is passed as NULL. Also, we update places VMA is passed as NULL to use flush_tlb_kernel_range instead. Now, the only place VMA is passed as NULL is in the implementation of flush_tlb_kernel_range.
Fixes: c28b27416da9 ("openrisc: Implement proper SMP tlb flushing") Reported-by: Jan Henrik Weinstock jan.weinstock@rwth-aachen.de Signed-off-by: Stafford Horne shorne@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/openrisc/kernel/dma.c | 4 ++-- arch/openrisc/kernel/smp.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/openrisc/kernel/dma.c b/arch/openrisc/kernel/dma.c index 1b16d97e7da7f..a82b2caaa560d 100644 --- a/arch/openrisc/kernel/dma.c +++ b/arch/openrisc/kernel/dma.c @@ -33,7 +33,7 @@ page_set_nocache(pte_t *pte, unsigned long addr, * Flush the page out of the TLB so that the new page flags get * picked up next time there's an access */ - flush_tlb_page(NULL, addr); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
/* Flush page out of dcache */ for (cl = __pa(addr); cl < __pa(next); cl += cpuinfo->dcache_block_size) @@ -56,7 +56,7 @@ page_clear_nocache(pte_t *pte, unsigned long addr, * Flush the page out of the TLB so that the new page flags get * picked up next time there's an access */ - flush_tlb_page(NULL, addr); + flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
return 0; } diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c index 415e209732a3d..ba78766cf00b5 100644 --- a/arch/openrisc/kernel/smp.c +++ b/arch/openrisc/kernel/smp.c @@ -272,7 +272,7 @@ static inline void ipi_flush_tlb_range(void *info) local_flush_tlb_range(NULL, fd->addr1, fd->addr2); }
-static void smp_flush_tlb_range(struct cpumask *cmask, unsigned long start, +static void smp_flush_tlb_range(const struct cpumask *cmask, unsigned long start, unsigned long end) { unsigned int cpuid; @@ -320,7 +320,9 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - smp_flush_tlb_range(mm_cpumask(vma->vm_mm), start, end); + const struct cpumask *cmask = vma ? mm_cpumask(vma->vm_mm) + : cpu_online_mask; + smp_flush_tlb_range(cmask, start, end); }
/* Instruction cache invalidate - performed on each cpu */
From: Ziyang Xuan william.xuanziyang@huawei.com
[ Upstream commit 563bcbae3ba233c275c244bfce2efe12938f5363 ]
The real_dev of a vlan net_device may be freed after unregister_vlan_dev(). Access the real_dev continually by vlan_dev_real_dev() will trigger the UAF problem for the real_dev like following:
================================================================== BUG: KASAN: use-after-free in vlan_dev_real_dev+0xf9/0x120 Call Trace: kasan_report.cold+0x83/0xdf vlan_dev_real_dev+0xf9/0x120 is_eth_port_of_netdev_filter.part.0+0xb1/0x2c0 is_eth_port_of_netdev_filter+0x28/0x40 ib_enum_roce_netdev+0x1a3/0x300 ib_enum_all_roce_netdevs+0xc7/0x140 netdevice_event_work_handler+0x9d/0x210 ...
Freed by task 9288: kasan_save_stack+0x1b/0x40 kasan_set_track+0x1c/0x30 kasan_set_free_info+0x20/0x30 __kasan_slab_free+0xfc/0x130 slab_free_freelist_hook+0xdd/0x240 kfree+0xe4/0x690 kvfree+0x42/0x50 device_release+0x9f/0x240 kobject_put+0x1c8/0x530 put_device+0x1b/0x30 free_netdev+0x370/0x540 ppp_destroy_interface+0x313/0x3d0 ...
Move the put_device(real_dev) to vlan_dev_free(). Ensure real_dev not be freed before vlan_dev unregistered.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: syzbot+e4df4e1389e28972e955@syzkaller.appspotmail.com Signed-off-by: Ziyang Xuan william.xuanziyang@huawei.com Reviewed-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/8021q/vlan.c | 3 --- net/8021q/vlan_dev.c | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 55275ef9a31a7..a3a0a5e994f5a 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -123,9 +123,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) }
vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); - - /* Get rid of the vlan's reference to real_dev */ - dev_put(real_dev); }
int vlan_check_real_dev(struct net_device *real_dev, diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 0c21d1fec8522..aeeb5f90417b5 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -843,6 +843,9 @@ static void vlan_dev_free(struct net_device *dev)
free_percpu(vlan->vlan_pcpu_stats); vlan->vlan_pcpu_stats = NULL; + + /* Get rid of the vlan's reference to real_dev */ + dev_put(vlan->real_dev); }
void vlan_setup(struct net_device *dev)
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 92f62485b3715882cd397b0cbd80a96d179b86d6 ]
Normally it is expected that the dsa_device_ops :: rcv() method finishes parsing the DSA tag and consumes it, then never looks at it again.
But commit c0bcf537667c ("net: dsa: ocelot: add hardware timestamping support for Felix") added support for RX timestamping in a very unconventional way. On this switch, a partial timestamp is available in the DSA header, but the driver got away with not parsing that timestamp right away, but instead delayed that parsing for a little longer:
dsa_switch_rcv(): nskb = cpu_dp->rcv(skb, dev); <------------- not here -> ocelot_rcv() ...
skb = nskb; skb_push(skb, ETH_HLEN); skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, skb->dev);
...
if (dsa_skb_defer_rx_timestamp(p, skb)) <--- but here -> felix_rxtstamp() return 0;
When in felix_rxtstamp(), this driver accounted for the fact that eth_type_trans() happened in the meanwhile, so it got a hold of the extraction header again by subtracting (ETH_HLEN + OCELOT_TAG_LEN) bytes from the current skb->data.
This worked for quite some time but was quite fragile from the very beginning. Not to mention that having DSA tag parsing split in two different files, under different folders (net/dsa/tag_ocelot.c vs drivers/net/dsa/ocelot/felix.c) made it quite non-obvious for patches to come that they might break this.
Finally, the blamed commit does the following: at the end of ocelot_rcv(), it checks whether the skb payload contains a VLAN header. If it does, and this port is under a VLAN-aware bridge, that VLAN ID might not be correct in the sense that the packet might have suffered VLAN rewriting due to TCAM rules (VCAP IS1). So we consume the VLAN ID from the skb payload using __skb_vlan_pop(), and take the classified VLAN ID from the DSA tag, and construct a hwaccel VLAN tag with the classified VLAN, and the skb payload is VLAN-untagged.
The big problem is that __skb_vlan_pop() does:
memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN); __skb_pull(skb, VLAN_HLEN);
aka it moves the Ethernet header 4 bytes to the right, and pulls 4 bytes from the skb headroom (effectively also moving skb->data, by definition). So for felix_rxtstamp()'s fragile logic, all bets are off now. Instead of having the "extraction" pointer point to the DSA header, it actually points to 4 bytes _inside_ the extraction header. Corollary, the last 4 bytes of the "extraction" header are in fact 4 stale bytes of the destination MAC address from the Ethernet header, from prior to the __skb_vlan_pop() movement.
So of course, RX timestamps are completely bogus when the system is configured in this way.
The fix is actually very simple: just don't structure the code like that. For better or worse, the DSA PTP timestamping API does not offer a straightforward way for drivers to present their RX timestamps, but other drivers (sja1105) have established a simple mechanism to carry their RX timestamp from dsa_device_ops :: rcv() all the way to dsa_switch_ops :: port_rxtstamp() and even later. That mechanism is to simply save the partial timestamp to the skb->cb, and complete it later.
Question: why don't we simply populate the skb's struct skb_shared_hwtstamps from ocelot_rcv(), and bother with this complication of propagating the timestamp to felix_rxtstamp()?
Answer: dsa_switch_ops :: port_rxtstamp() answers the question whether PTP packets need sleepable context to retrieve the full RX timestamp. Currently felix_rxtstamp() answers "no, thanks" to that question, and calls ocelot_ptp_gettime64() from softirq atomic context. This is understandable, since Felix VSC9959 is a PCIe memory-mapped switch, so hardware access does not require sleeping. But the felix driver is preparing for the introduction of other switches where hardware access is over a slow bus like SPI or MDIO: https://lore.kernel.org/lkml/20210814025003.2449143-1-colin.foster@in-advant...
So I would like to keep this code structure, so the rework needed when that driver will need PTP support will be minimal (answer "yes, I need deferred context for this skb's RX timestamp", then the partial timestamp will still be found in the skb->cb.
Fixes: ea440cd2d9b2 ("net: dsa: tag_ocelot: use VLAN information from tagging header when available") Reported-by: Po Liu po.liu@nxp.com Cc: Yangbo Lu yangbo.lu@nxp.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/ocelot/felix.c | 9 +++------ include/linux/dsa/ocelot.h | 1 + net/dsa/tag_ocelot.c | 3 +++ 3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 341236dcbdb47..6873d5a253afb 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -1368,12 +1368,12 @@ out: static bool felix_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, unsigned int type) { - u8 *extraction = skb->data - ETH_HLEN - OCELOT_TAG_LEN; + u32 tstamp_lo = OCELOT_SKB_CB(skb)->tstamp_lo; struct skb_shared_hwtstamps *shhwtstamps; struct ocelot *ocelot = ds->priv; - u32 tstamp_lo, tstamp_hi; struct timespec64 ts; - u64 tstamp, val; + u32 tstamp_hi; + u64 tstamp;
/* If the "no XTR IRQ" workaround is in use, tell DSA to defer this skb * for RX timestamping. Then free it, and poll for its copy through @@ -1388,9 +1388,6 @@ static bool felix_rxtstamp(struct dsa_switch *ds, int port, ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); tstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
- ocelot_xfh_get_rew_val(extraction, &val); - tstamp_lo = (u32)val; - tstamp_hi = tstamp >> 32; if ((tstamp & 0xffffffff) < tstamp_lo) tstamp_hi--; diff --git a/include/linux/dsa/ocelot.h b/include/linux/dsa/ocelot.h index 8ae999f587c48..289064b51fa9a 100644 --- a/include/linux/dsa/ocelot.h +++ b/include/linux/dsa/ocelot.h @@ -12,6 +12,7 @@ struct ocelot_skb_cb { struct sk_buff *clone; unsigned int ptp_class; /* valid only for clones */ + u32 tstamp_lo; u8 ptp_cmd; u8 ts_id; }; diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c index 605b51ca69210..6e0518aa3a4d2 100644 --- a/net/dsa/tag_ocelot.c +++ b/net/dsa/tag_ocelot.c @@ -62,6 +62,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, struct dsa_port *dp; u8 *extraction; u16 vlan_tpid; + u64 rew_val;
/* Revert skb->data by the amount consumed by the DSA master, * so it points to the beginning of the frame. @@ -91,6 +92,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, ocelot_xfh_get_qos_class(extraction, &qos_class); ocelot_xfh_get_tag_type(extraction, &tag_type); ocelot_xfh_get_vlan_tci(extraction, &vlan_tci); + ocelot_xfh_get_rew_val(extraction, &rew_val);
skb->dev = dsa_master_find_slave(netdev, 0, src_port); if (!skb->dev) @@ -104,6 +106,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb,
dsa_default_offload_fwd_mark(skb); skb->priority = qos_class; + OCELOT_SKB_CB(skb)->tstamp_lo = rew_val;
/* Ocelot switches copy frames unmodified to the CPU. However, it is * possible for the user to request a VLAN modification through
From: Sylwester Dziedziuch sylwesterx.dziedziuch@intel.com
[ Upstream commit ce572a5b88d5ca6737b5e23da9892792fd708ad3 ]
VF was not able to change its hardware MAC address in case the new address was already present in the MAC filter list. Change the handling of VF add mac request to not return if requested MAC address is already present on the list and check if its hardware MAC needs to be updated in this case.
Fixes: ed4c068d46f6 ("ice: Enable ip link show on the PF to display VF unicast MAC(s)") Signed-off-by: Sylwester Dziedziuch sylwesterx.dziedziuch@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/ice/ice_virtchnl_pf.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index a827c6b653a38..9f5da506d8f4b 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -3762,6 +3762,7 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi, struct device *dev = ice_pf_to_dev(vf->pf); u8 *mac_addr = vc_ether_addr->addr; enum ice_status status; + int ret = 0;
/* device MAC already added */ if (ether_addr_equal(mac_addr, vf->dev_lan_addr.addr)) @@ -3774,20 +3775,23 @@ ice_vc_add_mac_addr(struct ice_vf *vf, struct ice_vsi *vsi,
status = ice_fltr_add_mac(vsi, mac_addr, ICE_FWD_TO_VSI); if (status == ICE_ERR_ALREADY_EXISTS) { - dev_err(dev, "MAC %pM already exists for VF %d\n", mac_addr, + dev_dbg(dev, "MAC %pM already exists for VF %d\n", mac_addr, vf->vf_id); - return -EEXIST; + /* don't return since we might need to update + * the primary MAC in ice_vfhw_mac_add() below + */ + ret = -EEXIST; } else if (status) { dev_err(dev, "Failed to add MAC %pM for VF %d\n, error %s\n", mac_addr, vf->vf_id, ice_stat_str(status)); return -EIO; + } else { + vf->num_mac++; }
ice_vfhw_mac_add(vf, vc_ether_addr);
- vf->num_mac++; - - return 0; + return ret; }
/**
From: Brett Creeley brett.creeley@intel.com
[ Upstream commit b385cca47363316c6d9a74ae9db407bbc281f815 ]
When a VF is removed and/or reset its Tx queues need to be stopped from the PF. This is done by calling the ice_dis_vf_qs() function, which calls ice_vsi_stop_lan_tx_rings(). Currently ice_dis_vf_qs() is protected by the VF state bit ICE_VF_STATE_QS_ENA. Unfortunately, this is causing the Tx queues to not be disabled in some cases and when the VF tries to re-enable/reconfigure its Tx queues over virtchnl the op is failing. This is because a VF can be reset and/or removed before the ICE_VF_STATE_QS_ENA bit is set, but the Tx queues were already configured via ice_vsi_cfg_single_txq() in the VIRTCHNL_OP_CONFIG_VSI_QUEUES op. However, the ICE_VF_STATE_QS_ENA bit is set on a successful VIRTCHNL_OP_ENABLE_QUEUES, which will always happen after the VIRTCHNL_OP_CONFIG_VSI_QUEUES op.
This was causing the following error message when loading the ice driver, creating VFs, and modifying VF trust in an endless loop:
[35274.192484] ice 0000:88:00.0: Failed to set LAN Tx queue context, error: ICE_ERR_PARAM [35274.193074] ice 0000:88:00.0: VF 0 failed opcode 6, retval: -5 [35274.193640] iavf 0000:88:01.0: PF returned error -5 (IAVF_ERR_PARAM) to our request 6
Fix this by always calling ice_dis_vf_qs() and silencing the error message in ice_vsi_stop_tx_ring() since the calling code ignores the return anyway. Also, all other places that call ice_vsi_stop_tx_ring() catch the error, so this doesn't affect those flows since there was no change to the values the function returns.
Other solutions were considered (i.e. tracking which VF queues had been "started/configured" in VIRTCHNL_OP_CONFIG_VSI_QUEUES, but it seemed more complicated than it was worth. This solution also brings in the chance for other unexpected conditions due to invalid state bit checks. So, the proposed solution seemed like the best option since there is no harm in failing to stop Tx queues that were never started.
This issue can be seen using the following commands:
for i in {0..50}; do rmmod ice modprobe ice
sleep 1
echo 1 > /sys/class/net/ens785f0/device/sriov_numvfs echo 1 > /sys/class/net/ens785f1/device/sriov_numvfs
ip link set ens785f1 vf 0 trust on ip link set ens785f0 vf 0 trust on
sleep 2
echo 0 > /sys/class/net/ens785f0/device/sriov_numvfs echo 0 > /sys/class/net/ens785f1/device/sriov_numvfs sleep 1 echo 1 > /sys/class/net/ens785f0/device/sriov_numvfs echo 1 > /sys/class/net/ens785f1/device/sriov_numvfs
ip link set ens785f1 vf 0 trust on ip link set ens785f0 vf 0 trust on done
Fixes: 77ca27c41705 ("ice: add support for virtchnl_queue_select.[tx|rx]_queues bitmap") Signed-off-by: Brett Creeley brett.creeley@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/ice/ice_base.c | 2 +- drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c index c36057efc7ae3..f74610442bda7 100644 --- a/drivers/net/ethernet/intel/ice/ice_base.c +++ b/drivers/net/ethernet/intel/ice/ice_base.c @@ -909,7 +909,7 @@ ice_vsi_stop_tx_ring(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, } else if (status == ICE_ERR_DOES_NOT_EXIST) { dev_dbg(ice_pf_to_dev(vsi->back), "LAN Tx queues do not exist, nothing to disable\n"); } else if (status) { - dev_err(ice_pf_to_dev(vsi->back), "Failed to disable LAN Tx queues, error: %s\n", + dev_dbg(ice_pf_to_dev(vsi->back), "Failed to disable LAN Tx queues, error: %s\n", ice_stat_str(status)); return -ENODEV; } diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c index 9f5da506d8f4b..7e3ae4cc17a39 100644 --- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -634,8 +634,7 @@ void ice_free_vfs(struct ice_pf *pf)
/* Avoid wait time by stopping all VFs at the same time */ ice_for_each_vf(pf, i) - if (test_bit(ICE_VF_STATE_QS_ENA, pf->vf[i].vf_states)) - ice_dis_vf_qs(&pf->vf[i]); + ice_dis_vf_qs(&pf->vf[i]);
tmp = pf->num_alloc_vfs; pf->num_qps_per_vf = 0; @@ -1645,8 +1644,7 @@ bool ice_reset_vf(struct ice_vf *vf, bool is_vflr)
vsi = ice_get_vf_vsi(vf);
- if (test_bit(ICE_VF_STATE_QS_ENA, vf->vf_states)) - ice_dis_vf_qs(vf); + ice_dis_vf_qs(vf);
/* Call Disable LAN Tx queue AQ whether or not queues are * enabled. This is needed for successful completion of VFR.
From: Daniel Thompson daniel.thompson@linaro.org
[ Upstream commit b77dbc86d60459b42ab375e4e23172e7245f2854 ]
Currently kdb contains some open-coded routines to generate a summary character for each task. This code currently issues warnings, is almost certainly broken and won't make sense to any kernel dev who has ever used /proc to examine task states.
Fix both the warning and the potential for confusion by adopting the scheduler's task classification. Whilst doing this we also simplify the filtering by using mask strings directly (which means we don't have to guess all the characters the scheduler might give us).
Unfortunately we can't quite match the scheduler classification completely. We add four extra states: - for idle loops and i, m and s for sleeping system daemons (which means kthreads in one of the I, M and S states). These extra states are used to manage the filters for tools to make the output of ps and bta less noisy.
Note: The Fixes below is the last point the original dubious code was moved; it was not introduced by that patch. However it gives us the last point to which this patch can be easily backported. Happily that should be enough to cover the introduction of CONFIG_WERROR!
Fixes: 2f064a59a11f ("sched: Change task_struct::state") Link: https://lore.kernel.org/r/20211102173158.3315227-1-daniel.thompson@linaro.or... Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Daniel Thompson daniel.thompson@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/debug/kdb/kdb_bt.c | 16 ++--- kernel/debug/kdb/kdb_main.c | 37 ++++++----- kernel/debug/kdb/kdb_private.h | 4 +- kernel/debug/kdb/kdb_support.c | 118 +++++++-------------------------- 4 files changed, 53 insertions(+), 122 deletions(-)
diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c index 1f9f0e47aedaa..10b454554ab03 100644 --- a/kernel/debug/kdb/kdb_bt.c +++ b/kernel/debug/kdb/kdb_bt.c @@ -46,7 +46,7 @@ static void kdb_show_stack(struct task_struct *p, void *addr) * btp <pid> Kernel stack for <pid> * btt <address-expression> Kernel stack for task structure at * <address-expression> - * bta [DRSTCZEUIMA] All useful processes, optionally + * bta [state_chars>|A] All useful processes, optionally * filtered by state * btc [<cpu>] The current process on one cpu, * default is all cpus @@ -74,7 +74,7 @@ static void kdb_show_stack(struct task_struct *p, void *addr) */
static int -kdb_bt1(struct task_struct *p, unsigned long mask, bool btaprompt) +kdb_bt1(struct task_struct *p, const char *mask, bool btaprompt) { char ch;
@@ -120,7 +120,7 @@ kdb_bt_cpu(unsigned long cpu) return; }
- kdb_bt1(kdb_tsk, ~0UL, false); + kdb_bt1(kdb_tsk, "A", false); }
int @@ -138,8 +138,8 @@ kdb_bt(int argc, const char **argv) if (strcmp(argv[0], "bta") == 0) { struct task_struct *g, *p; unsigned long cpu; - unsigned long mask = kdb_task_state_string(argc ? argv[1] : - NULL); + const char *mask = argc ? argv[1] : kdbgetenv("PS"); + if (argc == 0) kdb_ps_suppressed(); /* Run the active tasks first */ @@ -167,7 +167,7 @@ kdb_bt(int argc, const char **argv) return diag; p = find_task_by_pid_ns(pid, &init_pid_ns); if (p) - return kdb_bt1(p, ~0UL, false); + return kdb_bt1(p, "A", false); kdb_printf("No process with pid == %ld found\n", pid); return 0; } else if (strcmp(argv[0], "btt") == 0) { @@ -176,7 +176,7 @@ kdb_bt(int argc, const char **argv) diag = kdbgetularg((char *)argv[1], &addr); if (diag) return diag; - return kdb_bt1((struct task_struct *)addr, ~0UL, false); + return kdb_bt1((struct task_struct *)addr, "A", false); } else if (strcmp(argv[0], "btc") == 0) { unsigned long cpu = ~0; if (argc > 1) @@ -212,7 +212,7 @@ kdb_bt(int argc, const char **argv) kdb_show_stack(kdb_current_task, (void *)addr); return 0; } else { - return kdb_bt1(kdb_current_task, ~0UL, false); + return kdb_bt1(kdb_current_task, "A", false); } }
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index fa6deda894a17..0852a537dad4c 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -2203,8 +2203,8 @@ static void kdb_cpu_status(void) state = 'D'; /* cpu is online but unresponsive */ } else { state = ' '; /* cpu is responding to kdb */ - if (kdb_task_state_char(KDB_TSK(i)) == 'I') - state = 'I'; /* idle task */ + if (kdb_task_state_char(KDB_TSK(i)) == '-') + state = '-'; /* idle task */ } if (state != prev_state) { if (prev_state != '?') { @@ -2271,37 +2271,30 @@ static int kdb_cpu(int argc, const char **argv) void kdb_ps_suppressed(void) { int idle = 0, daemon = 0; - unsigned long mask_I = kdb_task_state_string("I"), - mask_M = kdb_task_state_string("M"); unsigned long cpu; const struct task_struct *p, *g; for_each_online_cpu(cpu) { p = kdb_curr_task(cpu); - if (kdb_task_state(p, mask_I)) + if (kdb_task_state(p, "-")) ++idle; } for_each_process_thread(g, p) { - if (kdb_task_state(p, mask_M)) + if (kdb_task_state(p, "ims")) ++daemon; } if (idle || daemon) { if (idle) - kdb_printf("%d idle process%s (state I)%s\n", + kdb_printf("%d idle process%s (state -)%s\n", idle, idle == 1 ? "" : "es", daemon ? " and " : ""); if (daemon) - kdb_printf("%d sleeping system daemon (state M) " + kdb_printf("%d sleeping system daemon (state [ims]) " "process%s", daemon, daemon == 1 ? "" : "es"); kdb_printf(" suppressed,\nuse 'ps A' to see all.\n"); } }
-/* - * kdb_ps - This function implements the 'ps' command which shows a - * list of the active processes. - * ps [DRSTCZEUIMA] All processes, optionally filtered by state - */ void kdb_ps1(const struct task_struct *p) { int cpu; @@ -2330,17 +2323,25 @@ void kdb_ps1(const struct task_struct *p) } }
+/* + * kdb_ps - This function implements the 'ps' command which shows a + * list of the active processes. + * + * ps [<state_chars>] Show processes, optionally selecting only those whose + * state character is found in <state_chars>. + */ static int kdb_ps(int argc, const char **argv) { struct task_struct *g, *p; - unsigned long mask, cpu; + const char *mask; + unsigned long cpu;
if (argc == 0) kdb_ps_suppressed(); kdb_printf("%-*s Pid Parent [*] cpu State %-*s Command\n", (int)(2*sizeof(void *))+2, "Task Addr", (int)(2*sizeof(void *))+2, "Thread"); - mask = kdb_task_state_string(argc ? argv[1] : NULL); + mask = argc ? argv[1] : kdbgetenv("PS"); /* Run the active tasks first */ for_each_online_cpu(cpu) { if (KDB_FLAG(CMD_INTERRUPT)) @@ -2742,8 +2743,8 @@ static kdbtab_t maintab[] = { }, { .name = "bta", .func = kdb_bt, - .usage = "[D|R|S|T|C|Z|E|U|I|M|A]", - .help = "Backtrace all processes matching state flag", + .usage = "[<state_chars>|A]", + .help = "Backtrace all processes whose state matches", .flags = KDB_ENABLE_INSPECT, }, { .name = "btc", @@ -2797,7 +2798,7 @@ static kdbtab_t maintab[] = { }, { .name = "ps", .func = kdb_ps, - .usage = "[<flags>|A]", + .usage = "[<state_chars>|A]", .help = "Display active task list", .flags = KDB_ENABLE_INSPECT, }, diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index 629590084a0dc..0d2f9feea0a46 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -190,10 +190,8 @@ extern char kdb_grep_string[]; extern int kdb_grep_leading; extern int kdb_grep_trailing; extern char *kdb_cmds[]; -extern unsigned long kdb_task_state_string(const char *); extern char kdb_task_state_char (const struct task_struct *); -extern unsigned long kdb_task_state(const struct task_struct *p, - unsigned long mask); +extern bool kdb_task_state(const struct task_struct *p, const char *mask); extern void kdb_ps_suppressed(void); extern void kdb_ps1(const struct task_struct *p); extern void kdb_send_sig(struct task_struct *p, int sig); diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 7507d9a8dc6ac..df2bface866ef 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c @@ -24,6 +24,7 @@ #include <linux/uaccess.h> #include <linux/kdb.h> #include <linux/slab.h> +#include <linux/ctype.h> #include "kdb_private.h"
/* @@ -473,82 +474,7 @@ int kdb_putword(unsigned long addr, unsigned long word, size_t size) return diag; }
-/* - * kdb_task_state_string - Convert a string containing any of the - * letters DRSTCZEUIMA to a mask for the process state field and - * return the value. If no argument is supplied, return the mask - * that corresponds to environment variable PS, DRSTCZEU by - * default. - * Inputs: - * s String to convert - * Returns: - * Mask for process state. - * Notes: - * The mask folds data from several sources into a single long value, so - * be careful not to overlap the bits. TASK_* bits are in the LSB, - * special cases like UNRUNNABLE are in the MSB. As of 2.6.10-rc1 there - * is no overlap between TASK_* and EXIT_* but that may not always be - * true, so EXIT_* bits are shifted left 16 bits before being stored in - * the mask. - */ - -/* unrunnable is < 0 */ -#define UNRUNNABLE (1UL << (8*sizeof(unsigned long) - 1)) -#define RUNNING (1UL << (8*sizeof(unsigned long) - 2)) -#define IDLE (1UL << (8*sizeof(unsigned long) - 3)) -#define DAEMON (1UL << (8*sizeof(unsigned long) - 4))
-unsigned long kdb_task_state_string(const char *s) -{ - long res = 0; - if (!s) { - s = kdbgetenv("PS"); - if (!s) - s = "DRSTCZEU"; /* default value for ps */ - } - while (*s) { - switch (*s) { - case 'D': - res |= TASK_UNINTERRUPTIBLE; - break; - case 'R': - res |= RUNNING; - break; - case 'S': - res |= TASK_INTERRUPTIBLE; - break; - case 'T': - res |= TASK_STOPPED; - break; - case 'C': - res |= TASK_TRACED; - break; - case 'Z': - res |= EXIT_ZOMBIE << 16; - break; - case 'E': - res |= EXIT_DEAD << 16; - break; - case 'U': - res |= UNRUNNABLE; - break; - case 'I': - res |= IDLE; - break; - case 'M': - res |= DAEMON; - break; - case 'A': - res = ~0UL; - break; - default: - kdb_func_printf("unknown flag '%c' ignored\n", *s); - break; - } - ++s; - } - return res; -}
/* * kdb_task_state_char - Return the character that represents the task state. @@ -559,7 +485,6 @@ unsigned long kdb_task_state_string(const char *s) */ char kdb_task_state_char (const struct task_struct *p) { - unsigned int p_state; unsigned long tmp; char state; int cpu; @@ -568,25 +493,18 @@ char kdb_task_state_char (const struct task_struct *p) copy_from_kernel_nofault(&tmp, (char *)p, sizeof(unsigned long))) return 'E';
- cpu = kdb_process_cpu(p); - p_state = READ_ONCE(p->__state); - state = (p_state == 0) ? 'R' : - (p_state < 0) ? 'U' : - (p_state & TASK_UNINTERRUPTIBLE) ? 'D' : - (p_state & TASK_STOPPED) ? 'T' : - (p_state & TASK_TRACED) ? 'C' : - (p->exit_state & EXIT_ZOMBIE) ? 'Z' : - (p->exit_state & EXIT_DEAD) ? 'E' : - (p_state & TASK_INTERRUPTIBLE) ? 'S' : '?'; + state = task_state_to_char((struct task_struct *) p); + if (is_idle_task(p)) { /* Idle task. Is it really idle, apart from the kdb * interrupt? */ + cpu = kdb_process_cpu(p); if (!kdb_task_has_cpu(p) || kgdb_info[cpu].irq_depth == 1) { if (cpu != kdb_initial_cpu) - state = 'I'; /* idle task */ + state = '-'; /* idle task */ } - } else if (!p->mm && state == 'S') { - state = 'M'; /* sleeping system daemon */ + } else if (!p->mm && strchr("IMS", state)) { + state = tolower(state); /* sleeping system daemon */ } return state; } @@ -596,14 +514,28 @@ char kdb_task_state_char (const struct task_struct *p) * given by the mask. * Inputs: * p struct task for the process - * mask mask from kdb_task_state_string to select processes + * mask set of characters used to select processes; both NULL + * and the empty string mean adopt a default filter, which + * is to suppress sleeping system daemons and the idle tasks * Returns: * True if the process matches at least one criteria defined by the mask. */ -unsigned long kdb_task_state(const struct task_struct *p, unsigned long mask) +bool kdb_task_state(const struct task_struct *p, const char *mask) { - char state[] = { kdb_task_state_char(p), '\0' }; - return (mask & kdb_task_state_string(state)) != 0; + char state = kdb_task_state_char(p); + + /* If there is no mask, then we will filter code that runs when the + * scheduler is idling and any system daemons that are currently + * sleeping. + */ + if (!mask || mask[0] == '\0') + return !strchr("-ims", state); + + /* A is a special case that matches all states */ + if (strchr(mask, 'A')) + return true; + + return strchr(mask, state); }
/* Maintain a small stack of kdb_flags to allow recursion without disturbing
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 009a789443fe4c8e6b1ecb7c16b4865c026184cd ]
The handling of PMIC register reads through writing 0 to address 4 of the OpRegion is wrong. Instead of returning the read value through the value64, which is a no-op for function == ACPI_WRITE calls, store the value and then on a subsequent function == ACPI_READ with address == 3 (the address for the value field of the OpRegion) return the stored value.
This has been tested on a Xiaomi Mi Pad 2 and makes the ACPI battery dev there mostly functional (unfortunately there are still other issues).
Here are the SET() / GET() functions of the PMIC ACPI device, which use this OpRegion, which clearly show the new behavior to be correct:
OperationRegion (REGS, 0x8F, Zero, 0x50) Field (REGS, ByteAcc, NoLock, Preserve) { CLNT, 8, SA, 8, OFF, 8, VAL, 8, RWM, 8 }
Method (GET, 3, Serialized) { If ((AVBE == One)) { CLNT = Arg0 SA = Arg1 OFF = Arg2 RWM = Zero If ((AVBG == One)) { GPRW = Zero } }
Return (VAL) /* _SB_.PCI0.I2C7.PMI5.VAL_ */ }
Method (SET, 4, Serialized) { If ((AVBE == One)) { CLNT = Arg0 SA = Arg1 OFF = Arg2 VAL = Arg3 RWM = One If ((AVBG == One)) { GPRW = One } } }
Fixes: 0afa877a5650 ("ACPI / PMIC: intel: add REGS operation region support") Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/pmic/intel_pmic.c | 51 +++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 23 deletions(-)
diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c index a371f273f99dd..9cde299eba880 100644 --- a/drivers/acpi/pmic/intel_pmic.c +++ b/drivers/acpi/pmic/intel_pmic.c @@ -211,31 +211,36 @@ static acpi_status intel_pmic_regs_handler(u32 function, void *handler_context, void *region_context) { struct intel_pmic_opregion *opregion = region_context; - int result = 0; + int result = -EINVAL; + + if (function == ACPI_WRITE) { + switch (address) { + case 0: + return AE_OK; + case 1: + opregion->ctx.addr |= (*value64 & 0xff) << 8; + return AE_OK; + case 2: + opregion->ctx.addr |= *value64 & 0xff; + return AE_OK; + case 3: + opregion->ctx.val = *value64 & 0xff; + return AE_OK; + case 4: + if (*value64) { + result = regmap_write(opregion->regmap, opregion->ctx.addr, + opregion->ctx.val); + } else { + result = regmap_read(opregion->regmap, opregion->ctx.addr, + &opregion->ctx.val); + } + opregion->ctx.addr = 0; + } + }
- switch (address) { - case 0: - return AE_OK; - case 1: - opregion->ctx.addr |= (*value64 & 0xff) << 8; - return AE_OK; - case 2: - opregion->ctx.addr |= *value64 & 0xff; + if (function == ACPI_READ && address == 3) { + *value64 = opregion->ctx.val; return AE_OK; - case 3: - opregion->ctx.val = *value64 & 0xff; - return AE_OK; - case 4: - if (*value64) { - result = regmap_write(opregion->regmap, opregion->ctx.addr, - opregion->ctx.val); - } else { - result = regmap_read(opregion->regmap, opregion->ctx.addr, - &opregion->ctx.val); - if (result == 0) - *value64 = opregion->ctx.val; - } - memset(&opregion->ctx, 0x00, sizeof(opregion->ctx)); }
if (result < 0) {
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 496bb18483cc0474913e81e18a6b313aaea4c120 ]
If an error occurs after a successful cdns_pcie_init_phy() call, it must be undone by a cdns_pcie_disable_phy() call, as already done above and below.
Update the goto to branch at the correct place of the error handling path.
Link: https://lore.kernel.org/r/db477b0cb444891a17c4bb424467667dc30d0bab.162479426... Fixes: 49e0efdce791 ("PCI: j721e: Add support to provide refclk to PCIe connector") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Krzysztof Wilczyński kw@linux.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/cadence/pci-j721e.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index ffb176d288cd9..918e11082e6a7 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -474,7 +474,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) ret = clk_prepare_enable(clk); if (ret) { dev_err(dev, "failed to enable pcie_refclk\n"); - goto err_get_sync; + goto err_pcie_setup; } pcie->refclk = clk;
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit 3aefb5ee843fbe4789d03bb181e190d462df95e4 ]
del_gendisk() should not called if the disk has not been added. Fix this.
Fixes: 41cd8b70c37a ("libnvdimm, btt: add support for blk integrity") Reviewed-by: Dan Williams dan.j.williams@intel.com Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20211103165843.1402142-1-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvdimm/btt.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index 92dec49522972..3fd1bdb9fc05b 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c @@ -1538,7 +1538,6 @@ static int btt_blk_init(struct btt *btt) int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
if (rc) { - del_gendisk(btt->btt_disk); blk_cleanup_disk(btt->btt_disk); return rc; }
From: Jackie Liu liuyun01@kylinos.cn
[ Upstream commit 5f7cf82c1d7373fcf9e1062f5654efd5fa2b9211 ]
When the value of error is printed, it will always be 0. We should print the correct error code when scsi_bsg_register_queue() fails.
Link: https://lore.kernel.org/r/20211022010201.426746-1-liu.yun@linux.dev Fixes: ead09dd3aed5 ("scsi: bsg: Simplify device registration") Cc: Jens Axboe axboe@kernel.dk Cc: Christoph Hellwig hch@lst.de Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Jackie Liu liuyun01@kylinos.cn Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_sysfs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index a35841b34bfd9..8bb79ccc9a8b5 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1388,6 +1388,7 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) * We're treating error on bsg register as non-fatal, so * pretend nothing went wrong. */ + error = PTR_ERR(sdev->bsg_dev); sdev_printk(KERN_INFO, sdev, "Failed to register bsg queue, errno=%d\n", error);
From: Daejun Park daejun7.park@samsung.com
[ Upstream commit 351b3a849ac7d92449dc75c43db8a857b38387ea ]
In ufshpb, pm_runtime_{get,put}_sync() are used to avoid unwanted runtime suspend during query requests. Whereas commit b294ff3e3449 ("scsi: ufs: core: Enable power management for wlun") modified the driver core to use ufshcd_rpm_{get,put}_sync() APIs.
Switch to these APIs in HPB module as well.
Link: https://lore.kernel.org/r/20210902003534epcms2p1937a0f0eeb48a441cb69f5ef13ff... Reviewed-by: Avri Altman avri.altman@wdc.com Signed-off-by: Daejun Park daejun7.park@samsung.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshpb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 026a133149dce..46cdfb0dfca94 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -2371,11 +2371,11 @@ static int ufshpb_get_lu_info(struct ufs_hba *hba, int lun,
ufshcd_map_desc_id_to_length(hba, QUERY_DESC_IDN_UNIT, &size);
- pm_runtime_get_sync(hba->dev); + ufshcd_rpm_get_sync(hba); ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_UNIT, lun, 0, desc_buf, &size); - pm_runtime_put_sync(hba->dev); + ufshcd_rpm_put_sync(hba);
if (ret) { dev_err(hba->dev, @@ -2598,10 +2598,10 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) if (version == HPB_SUPPORT_LEGACY_VERSION) hpb_dev_info->is_legacy = true;
- pm_runtime_get_sync(hba->dev); + ufshcd_rpm_get_sync(hba); ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); - pm_runtime_put_sync(hba->dev); + ufshcd_rpm_put_sync(hba);
if (ret) dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed",
From: Bean Huo beanhuo@micron.com
[ Upstream commit 1da3b0141e74c18c2377d4c2655406a90a87742f ]
Calling ufshcd_rpm_{get/put}_sync() prior to ufshcd_scsi_add_wlus() being called will trigger a NULL pointer dereference. This is because hba->sdev_ufs_device is initialized in ufshcd_scsi_add_wlus().
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000348 Mem abort info: ESR = 0x96000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 [0000000000000348] user address but active_mm is swapper Internal error: Oops: 96000004 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 91 Comm: kworker/u16:1 Not tainted 5.15.0-rc1-beanhuo-linaro-1423 Hardware name: MicronRB (DT) Workqueue: events_unbound async_run_entry_fn pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : pm_runtime_drop_link+0x128/0x338 lr : ufshpb_get_dev_info+0x8c/0x148 sp : ffff800012573c10 x29: ffff800012573c10 x28: 0000000000000000 x27: 0000000000000003 x26: ffff000001d21298 x25: 000000005abcea60 x24: ffff800011d89000 x23: 0000000000000001 x22: ffff000001d21880 x21: ffff000001ec9300 x20: 0000000000000004 x19: 0000000000000198 x18: ffffffffffffffff x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000041400 x14: 5eee00201100200a x13: 000000000000bb03 x12: 0000000000000000 x11: 0000000000000100 x10: 0200000000000000 x9 : bb0000021a162c01 x8 : 0302010021021003 x7 : 0000000000000000 x6 : ffff800012573af0 x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000200 x2 : 0000000000000348 x1 : 0000000000000348 x0 : ffff80001095308c Call trace: pm_runtime_drop_link+0x128/0x338 ufshpb_get_dev_info+0x8c/0x148 ufshcd_probe_hba+0xda0/0x11b8 ufshcd_async_scan+0x34/0x330 async_run_entry_fn+0x38/0x180 process_one_work+0x1f4/0x498 worker_thread+0x48/0x480 kthread+0x140/0x158 ret_from_fork+0x10/0x20 Code: 88027c01 35ffffa2 17fff6c4 f9800051 (885f7c40) ---[ end trace 2ba541335f595c95 ]
ufshpb_get_dev_info() is only called during asynchronous scanning and at that time pm_runtime_get_sync() has been called:
... /* Hold auto suspend until async scan completes */ pm_runtime_get_sync(dev); atomic_set(&hba->scsi_block_reqs_cnt, 0); ... ufshcd_async_scan() ufshcd_probe_hba(hba, true); ufshcd_device_params_init(hba); ufshpb_get_dev_info(); ... pm_runtime_put_sync(hba->dev);
Remove ufshcd_rpm_{get/put}_sync() from ufshpb_get_dev_info() to fix this problem.
Link: https://lore.kernel.org/r/20210929200640.828611-2-huobean@gmail.com Fixes: 351b3a849ac7 ("scsi: ufs: ufshpb: Use proper power management API") Signed-off-by: Bean Huo beanhuo@micron.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshpb.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 46cdfb0dfca94..3b1a90b1d82ac 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -2598,11 +2598,8 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) if (version == HPB_SUPPORT_LEGACY_VERSION) hpb_dev_info->is_legacy = true;
- ufshcd_rpm_get_sync(hba); ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); - ufshcd_rpm_put_sync(hba); - if (ret) dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed", __func__);
From: Avri Altman avri.altman@wdc.com
[ Upstream commit 9ec5128a8b5631d652ed06b37e0166f337802f90 ]
The spec recommends that for transfer length larger than the max-single-cmd attribute (bMAX_DATA_SIZE_FOR_HPB_SINGLE_CMD) it is possible to couple pre-requests with the HPB-READ command. Being a recommendation, using pre-requests can be perceived merely as a means of optimization. A common practice was to send pre-requests for chunks within some interval, and leave the READ10 untouched if larger.
Now that the pre-request flows have been removed, all the commands are single commands. Properly handle this attribute and do not send HPB-READ for transfer lengths larger than max-single-cmd.
[mkp: resolve conflict]
Fixes: 09d9e4d04187 ("scsi: ufs: ufshpb: Remove HPB2.0 flows") Link: https://lore.kernel.org/r/20211031123654.17719-1-avri.altman@wdc.com Reviewed-by: Daejun Park daejun7.park@samsung.com Signed-off-by: Avri Altman avri.altman@wdc.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/ufs/ufshpb.c | 24 +++++++++++++----------- drivers/scsi/ufs/ufshpb.h | 1 - 2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index 3b1a90b1d82ac..a86d0cc50de21 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -394,8 +394,6 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) if (!ufshpb_is_supported_chunk(hpb, transfer_len)) return 0;
- WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH); - if (hpb->is_hcm) { /* * in host control mode, reads are the main source for @@ -1572,7 +1570,7 @@ static void ufshpb_lu_parameter_init(struct ufs_hba *hba, if (ufshpb_is_legacy(hba)) hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH; else - hpb->pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH; + hpb->pre_req_max_tr_len = hpb_dev_info->max_hpb_single_cmd;
hpb->lu_pinned_start = hpb_lu_info->pinned_start; hpb->lu_pinned_end = hpb_lu_info->num_pinned ? @@ -2582,7 +2580,7 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) { struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; int version, ret; - u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW; + int max_single_cmd;
hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL];
@@ -2598,18 +2596,22 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) if (version == HPB_SUPPORT_LEGACY_VERSION) hpb_dev_info->is_legacy = true;
- ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, - QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); - if (ret) - dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed", - __func__); - hpb_dev_info->max_hpb_single_cmd = max_hpb_single_cmd; - /* * Get the number of user logical unit to check whether all * scsi_device finish initialization */ hpb_dev_info->num_lu = desc_buf[DEVICE_DESC_PARAM_NUM_LU]; + + if (hpb_dev_info->is_legacy) + return; + + ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, + QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_single_cmd); + + if (ret) + hpb_dev_info->max_hpb_single_cmd = HPB_LEGACY_CHUNK_HIGH; + else + hpb_dev_info->max_hpb_single_cmd = min(max_single_cmd + 1, HPB_MULTI_CHUNK_HIGH); }
void ufshpb_init(struct ufs_hba *hba) diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h index f15d8fdbce2ef..b475dbd789883 100644 --- a/drivers/scsi/ufs/ufshpb.h +++ b/drivers/scsi/ufs/ufshpb.h @@ -31,7 +31,6 @@
/* hpb support chunk size */ #define HPB_LEGACY_CHUNK_HIGH 1 -#define HPB_MULTI_CHUNK_LOW 7 #define HPB_MULTI_CHUNK_HIGH 255
/* hpb vender defined opcode */
From: Andrea Righi andrea.righi@canonical.com
[ Upstream commit a985442fdecb59504e3a2f1cfdd3c53af017ea5b ]
Explicitly pass -6 to netcat when the test is using IPv6 to prevent failures.
Also make sure to pass "-N" to netcat to close the socket after EOF on the client side, otherwise we would always hit the timeout and the test would fail.
Without this fix applied:
TEST: GREv6/v4 - copy file w/ TSO [FAIL] TEST: GREv6/v4 - copy file w/ GSO [FAIL] TEST: GREv6/v6 - copy file w/ TSO [FAIL] TEST: GREv6/v6 - copy file w/ GSO [FAIL]
With this fix applied:
TEST: GREv6/v4 - copy file w/ TSO [ OK ] TEST: GREv6/v4 - copy file w/ GSO [ OK ] TEST: GREv6/v6 - copy file w/ TSO [ OK ] TEST: GREv6/v6 - copy file w/ GSO [ OK ]
Fixes: 025efa0a82df ("selftests: add simple GSO GRE test") Signed-off-by: Andrea Righi andrea.righi@canonical.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/gre_gso.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/net/gre_gso.sh b/tools/testing/selftests/net/gre_gso.sh index facbb0c804439..fdeb44d621eb9 100755 --- a/tools/testing/selftests/net/gre_gso.sh +++ b/tools/testing/selftests/net/gre_gso.sh @@ -116,17 +116,18 @@ gre_gst_test_checks() { local name=$1 local addr=$2 + local proto=$3
- $NS_EXEC nc -kl $port >/dev/null & + $NS_EXEC nc $proto -kl $port >/dev/null & PID=$! while ! $NS_EXEC ss -ltn | grep -q $port; do ((i++)); sleep 0.01; done
- cat $TMPFILE | timeout 1 nc $addr $port + cat $TMPFILE | timeout 1 nc $proto -N $addr $port log_test $? 0 "$name - copy file w/ TSO"
ethtool -K veth0 tso off
- cat $TMPFILE | timeout 1 nc $addr $port + cat $TMPFILE | timeout 1 nc $proto -N $addr $port log_test $? 0 "$name - copy file w/ GSO"
ethtool -K veth0 tso on @@ -155,7 +156,7 @@ 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 + gre_gst_test_checks GREv6/v6 2001:db8:1::2 -6
cleanup }
From: Chenyuan Mi cymi20@fudan.edu.cn
[ Upstream commit 6bb8c2d51811eb5e6504f49efe3b089d026009d2 ]
The reference counting issue happens in one exception handling path of nouveau_svmm_bind(). When cli->svm.svmm is null, the function forgets to decrease the refcount of mm increased by get_task_mm(), causing a refcount leak.
Fix this issue by using mmput() to decrease the refcount in the exception handling path.
Also, the function forgets to do check against null when get mm by get_task_mm().
Fix this issue by adding null check after get mm by get_task_mm().
Signed-off-by: Chenyuan Mi cymi20@fudan.edu.cn Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Fixes: 822cab6150d3 ("drm/nouveau/svm: check for SVM initialized before migrating") Reviewed-by: Lyude Paul lyude@redhat.com Reviewed-by: Ben Skeggs bskeggs@redhat.com Reviewed-by: Karol Herbst kherbst@redhat.com Signed-off-by: Karol Herbst kherbst@redhat.com Link: https://patchwork.freedesktop.org/patch/msgid/20210907122633.16665-1-cymi20@... Link: https://gitlab.freedesktop.org/drm/nouveau/-/merge_requests/14 Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/nouveau/nouveau_svm.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index b0c3422cb01fa..9985bfde015a6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -162,10 +162,14 @@ nouveau_svmm_bind(struct drm_device *dev, void *data, */
mm = get_task_mm(current); + if (!mm) { + return -EINVAL; + } mmap_read_lock(mm);
if (!cli->svm.svmm) { mmap_read_unlock(mm); + mmput(mm); return -EINVAL; }
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit accf58afb689f81daadde24080ea1164ad2db75f ]
Prior to devm being able to use pmem_release_disk() there are other failure which can occur for which we must account for and release the disk for. Address those few cases.
Fixes: 3dd60fb9d95d ("nvdimm/pmem: stop using q_usage_count as external pgmap refcount") Reviewed-by: Christoph Hellwig hch@lst.de Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20211103230437.1639990-6-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvdimm/pmem.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 054154c22899a..2721dd2ead0a7 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -429,8 +429,10 @@ static int pmem_attach_disk(struct device *dev, bb_range.end = res->end; }
- if (IS_ERR(addr)) - return PTR_ERR(addr); + if (IS_ERR(addr)) { + rc = PTR_ERR(addr); + goto out; + } pmem->virt_addr = addr;
blk_queue_write_cache(q, true, fua); @@ -455,7 +457,8 @@ static int pmem_attach_disk(struct device *dev, flags = DAXDEV_F_SYNC; dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops, flags); if (IS_ERR(dax_dev)) { - return PTR_ERR(dax_dev); + rc = PTR_ERR(dax_dev); + goto out; } dax_write_cache(dax_dev, nvdimm_has_cache(nd_region)); pmem->dax_dev = dax_dev; @@ -470,8 +473,10 @@ static int pmem_attach_disk(struct device *dev, "badblocks"); if (!pmem->bb_state) dev_warn(dev, "'badblocks' notification disabled\n"); - return 0; +out: + blk_cleanup_disk(pmem->disk); + return rc; }
static int nd_pmem_probe(struct device *dev)
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit 44a469b6acae6ad05c4acca8429467d1d50a8b8d ]
Use the helper to replace two lines with one.
Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20210927220302.1073499-12-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ataflop.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 4947e41f89b7d..1a908455ff96f 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -2097,8 +2097,7 @@ static int __init atari_floppy_init (void)
err: while (--i >= 0) { - blk_cleanup_queue(unit[i].disk[0]->queue); - put_disk(unit[i].disk[0]); + blk_cleanup_disk(unit[i].disk[0]); blk_mq_free_tag_set(&unit[i].tag_set); }
@@ -2156,8 +2155,7 @@ static void __exit atari_floppy_exit(void) if (!unit[i].disk[type]) continue; del_gendisk(unit[i].disk[type]); - blk_cleanup_queue(unit[i].disk[type]->queue); - put_disk(unit[i].disk[type]); + blk_cleanup_disk(unit[i].disk[type]); } blk_mq_free_tag_set(&unit[i].tag_set); }
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit 573effb298011d3fcabc9b12025cf637f8a07911 ]
The ataflop assumes del_gendisk() is safe to call, this is only true because add_disk() does not return a failure, but that will change soon. And so, before we get to adding error handling for that case, let's make sure we keep track of which disks actually get registered. Then we use this to only call del_gendisk for them.
Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20210927220302.1073499-13-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ataflop.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 1a908455ff96f..55f6d6f6dbd34 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -298,6 +298,7 @@ static struct atari_floppy_struct { disk change detection) */ int flags; /* flags */ struct gendisk *disk[NUM_DISK_MINORS]; + bool registered[NUM_DISK_MINORS]; int ref; int type; struct blk_mq_tag_set tag_set; @@ -2021,8 +2022,10 @@ static void ataflop_probe(dev_t dev) return; mutex_lock(&ataflop_probe_lock); if (!unit[drive].disk[type]) { - if (ataflop_alloc_disk(drive, type) == 0) + if (ataflop_alloc_disk(drive, type) == 0) { add_disk(unit[drive].disk[type]); + unit[drive].registered[type] = true; + } } mutex_unlock(&ataflop_probe_lock); } @@ -2086,6 +2089,7 @@ static int __init atari_floppy_init (void) unit[i].track = -1; unit[i].flags = 0; add_disk(unit[i].disk[0]); + unit[i].registered[0] = true; }
printk(KERN_INFO "Atari floppy driver: max. %cD, %strack buffering\n", @@ -2154,7 +2158,8 @@ static void __exit atari_floppy_exit(void) for (type = 0; type < NUM_DISK_MINORS; type++) { if (!unit[i].disk[type]) continue; - del_gendisk(unit[i].disk[type]); + if (unit[i].registered[type]) + del_gendisk(unit[i].disk[type]); blk_cleanup_disk(unit[i].disk[type]); } blk_mq_free_tag_set(&unit[i].tag_set);
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit deae1138d04758c7f8939fcb8aee330bc37e3015 ]
Instead of using two separate code paths for cleaning up an atari disk, use one. We take the more careful approach to check for *all* disk types, as is done on exit. The init path didn't have that check as the alternative disk types are only probed for later, they are not initialized by default.
Yes, there is a shared tag for all disks.
Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20210927220302.1073499-14-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ataflop.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 55f6d6f6dbd34..123ad58193098 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -2030,6 +2030,20 @@ static void ataflop_probe(dev_t dev) mutex_unlock(&ataflop_probe_lock); }
+static void atari_cleanup_floppy_disk(struct atari_floppy_struct *fs) +{ + int type; + + for (type = 0; type < NUM_DISK_MINORS; type++) { + if (!fs->disk[type]) + continue; + if (fs->registered[type]) + del_gendisk(fs->disk[type]); + blk_cleanup_disk(fs->disk[type]); + } + blk_mq_free_tag_set(&fs->tag_set); +} + static int __init atari_floppy_init (void) { int i; @@ -2100,10 +2114,8 @@ static int __init atari_floppy_init (void) return 0;
err: - while (--i >= 0) { - blk_cleanup_disk(unit[i].disk[0]); - blk_mq_free_tag_set(&unit[i].tag_set); - } + while (--i >= 0) + atari_cleanup_floppy_disk(&unit[i]);
unregister_blkdev(FLOPPY_MAJOR, "fd"); out_unlock: @@ -2152,18 +2164,10 @@ __setup("floppy=", atari_floppy_setup);
static void __exit atari_floppy_exit(void) { - int i, type; + int i;
- for (i = 0; i < FD_MAX_UNITS; i++) { - for (type = 0; type < NUM_DISK_MINORS; type++) { - if (!unit[i].disk[type]) - continue; - if (unit[i].registered[type]) - del_gendisk(unit[i].disk[type]); - blk_cleanup_disk(unit[i].disk[type]); - } - blk_mq_free_tag_set(&unit[i].tag_set); - } + for (i = 0; i < FD_MAX_UNITS; i++) + atari_cleanup_floppy_disk(&unit[i]); unregister_blkdev(FLOPPY_MAJOR, "fd");
del_timer_sync(&fd_timer);
From: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp
[ Upstream commit 4ddb85d36613c45bde00d368bf9f357bd0708a0c ]
Commit bf9c0538e485b591 ("ataflop: use a separate gendisk for each media format") introduced ataflop_probe_lock mutex, but forgot to unlock the mutex when atari_floppy_init() (i.e. module loading) succeeded. This will result in double lock deadlock if ataflop_probe() is called. Also, unregister_blkdev() must not be called from atari_floppy_init() with ataflop_probe_lock held when atari_floppy_init() failed, for ataflop_probe() waits for ataflop_probe_lock with major_names_lock held (i.e. AB-BA deadlock).
__register_blkdev() needs to be called last in order to avoid calling ataflop_probe() when atari_floppy_init() is about to fail, for memory for completing already-started ataflop_probe() safely will be released as soon as atari_floppy_init() released ataflop_probe_lock mutex.
As with commit 8b52d8be86d72308 ("loop: reorder loop_exit"), unregister_blkdev() needs to be called first in order to avoid calling ataflop_alloc_disk() from ataflop_probe() after del_gendisk() from atari_floppy_exit().
By relocating __register_blkdev() / unregister_blkdev() as explained above, we can remove ataflop_probe_lock mutex, for probe function and __exit function are serialized by major_names_lock mutex.
Signed-off-by: Tetsuo Handa penguin-kernel@I-love.SAKURA.ne.jp Fixes: bf9c0538e485b591 ("ataflop: use a separate gendisk for each media format") Reviewed-by: Luis Chamberlain mcgrof@kernel.org Tested-by: Michael Schmitz schmitzmic@gmail.com Link: https://lore.kernel.org/r/20211103230437.1639990-11-mcgrof@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ataflop.c | 47 +++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 123ad58193098..aab48b292a3bb 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -2008,8 +2008,6 @@ static int ataflop_alloc_disk(unsigned int drive, unsigned int type) return 0; }
-static DEFINE_MUTEX(ataflop_probe_lock); - static void ataflop_probe(dev_t dev) { int drive = MINOR(dev) & 3; @@ -2020,14 +2018,32 @@ static void ataflop_probe(dev_t dev)
if (drive >= FD_MAX_UNITS || type >= NUM_DISK_MINORS) return; - mutex_lock(&ataflop_probe_lock); if (!unit[drive].disk[type]) { if (ataflop_alloc_disk(drive, type) == 0) { add_disk(unit[drive].disk[type]); unit[drive].registered[type] = true; } } - mutex_unlock(&ataflop_probe_lock); +} + +static void atari_floppy_cleanup(void) +{ + int i; + int type; + + for (i = 0; i < FD_MAX_UNITS; i++) { + for (type = 0; type < NUM_DISK_MINORS; type++) { + if (!unit[i].disk[type]) + continue; + del_gendisk(unit[i].disk[type]); + blk_cleanup_queue(unit[i].disk[type]->queue); + put_disk(unit[i].disk[type]); + } + blk_mq_free_tag_set(&unit[i].tag_set); + } + + del_timer_sync(&fd_timer); + atari_stram_free(DMABuffer); }
static void atari_cleanup_floppy_disk(struct atari_floppy_struct *fs) @@ -2053,11 +2069,6 @@ static int __init atari_floppy_init (void) /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ return -ENODEV;
- mutex_lock(&ataflop_probe_lock); - ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe); - if (ret) - goto out_unlock; - for (i = 0; i < FD_MAX_UNITS; i++) { memset(&unit[i].tag_set, 0, sizeof(unit[i].tag_set)); unit[i].tag_set.ops = &ataflop_mq_ops; @@ -2111,15 +2122,17 @@ static int __init atari_floppy_init (void) UseTrackbuffer ? "" : "no "); config_types();
- return 0; + ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe); + if (ret) { + printk(KERN_ERR "atari_floppy_init: cannot register block device\n"); + atari_floppy_cleanup(); + } + return ret;
err: while (--i >= 0) atari_cleanup_floppy_disk(&unit[i]);
- unregister_blkdev(FLOPPY_MAJOR, "fd"); -out_unlock: - mutex_unlock(&ataflop_probe_lock); return ret; }
@@ -2164,14 +2177,8 @@ __setup("floppy=", atari_floppy_setup);
static void __exit atari_floppy_exit(void) { - int i; - - for (i = 0; i < FD_MAX_UNITS; i++) - atari_cleanup_floppy_disk(&unit[i]); unregister_blkdev(FLOPPY_MAJOR, "fd"); - - del_timer_sync(&fd_timer); - atari_stram_free( DMABuffer ); + atari_floppy_cleanup(); }
module_init(atari_floppy_init)
From: Selvin Xavier selvin.xavier@broadcom.com
[ Upstream commit 5ec0a6fcb60ea430f8ee7e0bec22db9b22f856d3 ]
Host crashes when pci_enable_atomic_ops_to_root() is called for VFs with virtual buses. The virtual buses added to SR-IOV have bus->self set to NULL and host crashes due to this.
PID: 4481 TASK: ffff89c6941b0000 CPU: 53 COMMAND: "bash" ... #3 [ffff9a9481713808] oops_end at ffffffffb9025cd6 #4 [ffff9a9481713828] page_fault_oops at ffffffffb906e417 #5 [ffff9a9481713888] exc_page_fault at ffffffffb9a0ad14 #6 [ffff9a94817138b0] asm_exc_page_fault at ffffffffb9c00ace [exception RIP: pcie_capability_read_dword+28] RIP: ffffffffb952fd5c RSP: ffff9a9481713960 RFLAGS: 00010246 RAX: 0000000000000001 RBX: ffff89c6b1096000 RCX: 0000000000000000 RDX: ffff9a9481713990 RSI: 0000000000000024 RDI: 0000000000000000 RBP: 0000000000000080 R8: 0000000000000008 R9: ffff89c64341a2f8 R10: 0000000000000002 R11: 0000000000000000 R12: ffff89c648bab000 R13: 0000000000000000 R14: 0000000000000000 R15: ffff89c648bab0c8 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #7 [ffff9a9481713988] pci_enable_atomic_ops_to_root at ffffffffb95359a6 #8 [ffff9a94817139c0] bnxt_qplib_determine_atomics at ffffffffc08c1a33 [bnxt_re] #9 [ffff9a94817139d0] bnxt_re_dev_init at ffffffffc08ba2d1 [bnxt_re]
Per PCIe r5.0, sec 9.3.5.10, the AtomicOp Requester Enable bit in Device Control 2 is reserved for VFs. The PF value applies to all associated VFs.
Return -EINVAL if pci_enable_atomic_ops_to_root() is called for a VF.
Link: https://lore.kernel.org/r/1631354585-16597-1-git-send-email-selvin.xavier@br... Fixes: 35f5ace5dea4 ("RDMA/bnxt_re: Enable global atomic ops if platform supports") Fixes: 430a23689dea ("PCI: Add pci_enable_atomic_ops_to_root()") Signed-off-by: Selvin Xavier selvin.xavier@broadcom.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Andy Gospodarek gospo@broadcom.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/pci.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ce2ab62b64cfa..a101faf3e88a9 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3719,6 +3719,14 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) struct pci_dev *bridge; u32 cap, ctl2;
+ /* + * Per PCIe r5.0, sec 9.3.5.10, the AtomicOp Requester Enable bit + * in Device Control 2 is reserved in VFs and the PF value applies + * to all associated VFs. + */ + if (dev->is_virtfn) + return -EINVAL; + if (!pci_is_pcie(dev)) return -EINVAL;
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit dbea75fe18f60e364de6d994fc938a24ba249d81 ]
Commit a365ab6b9dfb ("cpufreq: intel_pstate: Implement the ->adjust_perf() callback") caused intel_pstate to use nonzero HWP desired values in certain usage scenarios, but it did not prevent them from being leaked into the confugirations in which HWP desired is expected to be 0.
The failing scenarios are switching the driver from the passive mode to the active mode and starting a new kernel via kexec() while intel_pstate is running in the passive mode.
To address this issue, ensure that HWP desired will be cleared on offline and suspend/shutdown.
Fixes: a365ab6b9dfb ("cpufreq: intel_pstate: Implement the ->adjust_perf() callback") Reported-by: Julia Lawall julia.lawall@inria.fr Tested-by: Julia Lawall julia.lawall@inria.fr Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/intel_pstate.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index fc7a429f22d33..dafa631582bac 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -999,9 +999,16 @@ static void intel_pstate_hwp_offline(struct cpudata *cpu) */ value &= ~GENMASK_ULL(31, 24); value |= HWP_ENERGY_PERF_PREFERENCE(cpu->epp_cached); - WRITE_ONCE(cpu->hwp_req_cached, value); }
+ /* + * Clear the desired perf field in the cached HWP request value to + * prevent nonzero desired values from being leaked into the active + * mode. + */ + value &= ~HWP_DESIRED_PERF(~0L); + WRITE_ONCE(cpu->hwp_req_cached, value); + value &= ~GENMASK_ULL(31, 0); min_perf = HWP_LOWEST_PERF(READ_ONCE(cpu->hwp_cap_cached));
@@ -2903,6 +2910,27 @@ static int intel_cpufreq_cpu_exit(struct cpufreq_policy *policy) return intel_pstate_cpu_exit(policy); }
+static int intel_cpufreq_suspend(struct cpufreq_policy *policy) +{ + intel_pstate_suspend(policy); + + if (hwp_active) { + struct cpudata *cpu = all_cpu_data[policy->cpu]; + u64 value = READ_ONCE(cpu->hwp_req_cached); + + /* + * Clear the desired perf field in MSR_HWP_REQUEST in case + * intel_cpufreq_adjust_perf() is in use and the last value + * written by it may not be suitable. + */ + value &= ~HWP_DESIRED_PERF(~0L); + wrmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, value); + WRITE_ONCE(cpu->hwp_req_cached, value); + } + + return 0; +} + static struct cpufreq_driver intel_cpufreq = { .flags = CPUFREQ_CONST_LOOPS, .verify = intel_cpufreq_verify_policy, @@ -2912,7 +2940,7 @@ static struct cpufreq_driver intel_cpufreq = { .exit = intel_cpufreq_cpu_exit, .offline = intel_cpufreq_cpu_offline, .online = intel_pstate_cpu_online, - .suspend = intel_pstate_suspend, + .suspend = intel_cpufreq_suspend, .resume = intel_pstate_resume, .update_limits = intel_pstate_update_limits, .name = "intel_cpufreq",
From: Heiner Kallweit hkallweit1@gmail.com
[ Upstream commit a4db9055fdb9cf607775c66d39796caf6439ec92 ]
As reported by Zhang there's a small issue if in forced mode the duplex mode changes with the link staying up [0]. In this case the MAC isn't notified about the change.
The proposed patch relies on the phylib state machine and ignores the fact that there are drivers that uses phylib but not the phylib state machine. So let's don't change the behavior for such drivers and fix it w/o re-adding state PHY_FORCING for the case that phylib state machine is used.
[0] https://lore.kernel.org/netdev/a5c26ffd-4ee4-a5e6-4103-873208ce0dc5@huawei.c...
Fixes: 2bd229df5e2e ("net: phy: remove state PHY_FORCING") Reported-by: Zhang Changzhong zhangchangzhong@huawei.com Tested-by: Zhang Changzhong zhangchangzhong@huawei.com Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Link: https://lore.kernel.org/r/7b8b9456-a93f-abbc-1dc5-a2c2542f932c@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index a3bfb156c83d7..beb2b66da1324 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -815,7 +815,12 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev, phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl;
/* Restart the PHY */ - _phy_start_aneg(phydev); + if (phy_is_started(phydev)) { + phydev->state = PHY_UP; + phy_trigger_machine(phydev); + } else { + _phy_start_aneg(phydev); + }
mutex_unlock(&phydev->lock); return 0;
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit fe7d064fa3faec5d8157029fb8720b4fddc9e1e8 ]
Commit 83cbce957446 ("block: add error handling for device_add_disk / add_disk") added error handling to device_add_disk(), however the goto label for the kobject_create_and_add() failure did not set the return value correctly, and so we can end up in a situation where kobject_create_and_add() fails but we report success.
Fixes: 83cbce957446 ("block: add error handling for device_add_disk / add_disk") Reported-by: kernel test robot lkp@intel.com Reported-by: Dan Carpenter dan.carpenter@oracle.com Signed-off-by: Luis Chamberlain mcgrof@kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20211103164023.1384821-1-mcgrof@kernel.org [axboe: fold in followup fix from Wu Bo wubo40@huawei.com] Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/genhd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/block/genhd.c b/block/genhd.c index ab12ae6e636e8..6accd0b185e9e 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -467,11 +467,15 @@ int device_add_disk(struct device *parent, struct gendisk *disk,
disk->part0->bd_holder_dir = kobject_create_and_add("holders", &ddev->kobj); - if (!disk->part0->bd_holder_dir) + if (!disk->part0->bd_holder_dir) { + ret = -ENOMEM; goto out_del_integrity; + } disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); - if (!disk->slave_dir) + if (!disk->slave_dir) { + ret = -ENOMEM; goto out_put_holder_dir; + }
ret = bd_register_pending_holders(disk); if (ret < 0)
From: Jason Gunthorpe jgg@nvidia.com
[ Upstream commit 0d979509539ed1df883a30d442177ca7be609565 ]
The huge page functionality in TTM does not work safely because PUD and PMD entries do not have a special bit.
get_user_pages_fast() considers any page that passed pmd_huge() as usable:
if (unlikely(pmd_trans_huge(pmd) || pmd_huge(pmd) || pmd_devmap(pmd))) {
And vmf_insert_pfn_pmd_prot() unconditionally sets
entry = pmd_mkhuge(pfn_t_pmd(pfn, prot));
eg on x86 the page will be _PAGE_PRESENT | PAGE_PSE.
As such gup_huge_pmd() will try to deref a struct page:
head = try_grab_compound_head(pmd_page(orig), refs, flags);
and thus crash.
Thomas further notices that the drivers are not expecting the struct page to be used by anything - in particular the refcount incr above will cause them to malfunction.
Thus everything about this is not able to fully work correctly considering GUP_fast. Delete it entirely. It can return someday along with a proper PMD/PUD_SPECIAL bit in the page table itself to gate GUP_fast.
Fixes: 314b6580adc5 ("drm/ttm, drm/vmwgfx: Support huge TTM pagefaults") Signed-off-by: Jason Gunthorpe jgg@nvidia.com Reviewed-by: Thomas Hellström thomas.helllstrom@linux.intel.com Reviewed-by: Christian König christian.koenig@amd.com [danvet: Update subject per Thomas' &Christian's review] Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/0-v2-a44694790652+4ac-ttm_pmd_... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/ttm/ttm_bo_vm.c | 94 +--------------------- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 4 - drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c | 72 +---------------- drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 3 - include/drm/ttm/ttm_bo_api.h | 3 +- 8 files changed, 7 insertions(+), 175 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index d6aa032890ee8..a1e63ba4c54a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -61,7 +61,7 @@ static vm_fault_t amdgpu_gem_fault(struct vm_fault *vmf) }
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, - TTM_BO_VM_NUM_PREFAULT, 1); + TTM_BO_VM_NUM_PREFAULT);
drm_dev_exit(idx); } else { diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 8c2ecc2827232..c89d5964148fd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -56,7 +56,7 @@ static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)
nouveau_bo_del_io_reserve_lru(bo); prot = vm_get_page_prot(vma->vm_flags); - ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1); + ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT); nouveau_bo_add_io_reserve_lru(bo); if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) return ret; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 458f92a708879..a36a4f2c76b09 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -61,7 +61,7 @@ static vm_fault_t radeon_gem_fault(struct vm_fault *vmf) goto unlock_resv;
ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, - TTM_BO_VM_NUM_PREFAULT, 1); + TTM_BO_VM_NUM_PREFAULT); if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) goto unlock_mclk;
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 5b9b7fd01a692..4a655ab23c89d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -171,89 +171,6 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_vm_reserve);
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE -/** - * ttm_bo_vm_insert_huge - Insert a pfn for PUD or PMD faults - * @vmf: Fault data - * @bo: The buffer object - * @page_offset: Page offset from bo start - * @fault_page_size: The size of the fault in pages. - * @pgprot: The page protections. - * Does additional checking whether it's possible to insert a PUD or PMD - * pfn and performs the insertion. - * - * Return: VM_FAULT_NOPAGE on successful insertion, VM_FAULT_FALLBACK if - * a huge fault was not possible, or on insertion error. - */ -static vm_fault_t ttm_bo_vm_insert_huge(struct vm_fault *vmf, - struct ttm_buffer_object *bo, - pgoff_t page_offset, - pgoff_t fault_page_size, - pgprot_t pgprot) -{ - pgoff_t i; - vm_fault_t ret; - unsigned long pfn; - pfn_t pfnt; - struct ttm_tt *ttm = bo->ttm; - bool write = vmf->flags & FAULT_FLAG_WRITE; - - /* Fault should not cross bo boundary. */ - page_offset &= ~(fault_page_size - 1); - if (page_offset + fault_page_size > bo->resource->num_pages) - goto out_fallback; - - if (bo->resource->bus.is_iomem) - pfn = ttm_bo_io_mem_pfn(bo, page_offset); - else - pfn = page_to_pfn(ttm->pages[page_offset]); - - /* pfn must be fault_page_size aligned. */ - if ((pfn & (fault_page_size - 1)) != 0) - goto out_fallback; - - /* Check that memory is contiguous. */ - if (!bo->resource->bus.is_iomem) { - for (i = 1; i < fault_page_size; ++i) { - if (page_to_pfn(ttm->pages[page_offset + i]) != pfn + i) - goto out_fallback; - } - } else if (bo->bdev->funcs->io_mem_pfn) { - for (i = 1; i < fault_page_size; ++i) { - if (ttm_bo_io_mem_pfn(bo, page_offset + i) != pfn + i) - goto out_fallback; - } - } - - pfnt = __pfn_to_pfn_t(pfn, PFN_DEV); - if (fault_page_size == (HPAGE_PMD_SIZE >> PAGE_SHIFT)) - ret = vmf_insert_pfn_pmd_prot(vmf, pfnt, pgprot, write); -#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD - else if (fault_page_size == (HPAGE_PUD_SIZE >> PAGE_SHIFT)) - ret = vmf_insert_pfn_pud_prot(vmf, pfnt, pgprot, write); -#endif - else - WARN_ON_ONCE(ret = VM_FAULT_FALLBACK); - - if (ret != VM_FAULT_NOPAGE) - goto out_fallback; - - return VM_FAULT_NOPAGE; -out_fallback: - count_vm_event(THP_FAULT_FALLBACK); - return VM_FAULT_FALLBACK; -} -#else -static vm_fault_t ttm_bo_vm_insert_huge(struct vm_fault *vmf, - struct ttm_buffer_object *bo, - pgoff_t page_offset, - pgoff_t fault_page_size, - pgprot_t pgprot) -{ - return VM_FAULT_FALLBACK; -} -#endif - /** * ttm_bo_vm_fault_reserved - TTM fault helper * @vmf: The struct vm_fault given as argument to the fault callback @@ -261,7 +178,6 @@ static vm_fault_t ttm_bo_vm_insert_huge(struct vm_fault *vmf, * @num_prefault: Maximum number of prefault pages. The caller may want to * specify this based on madvice settings and the size of the GPU object * backed by the memory. - * @fault_page_size: The size of the fault in pages. * * This function inserts one or more page table entries pointing to the * memory backing the buffer object, and then returns a return code @@ -275,8 +191,7 @@ static vm_fault_t ttm_bo_vm_insert_huge(struct vm_fault *vmf, */ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, pgprot_t prot, - pgoff_t num_prefault, - pgoff_t fault_page_size) + pgoff_t num_prefault) { struct vm_area_struct *vma = vmf->vma; struct ttm_buffer_object *bo = vma->vm_private_data; @@ -327,11 +242,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, prot = pgprot_decrypted(prot); }
- /* We don't prefault on huge faults. Yet. */ - if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && fault_page_size != 1) - return ttm_bo_vm_insert_huge(vmf, bo, page_offset, - fault_page_size, prot); - /* * Speculatively prefault a number of pages. Only error on * first page. @@ -429,7 +339,7 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
prot = vma->vm_page_prot; if (drm_dev_enter(ddev, &idx)) { - ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1); + ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT); drm_dev_exit(idx); } else { ret = ttm_bo_vm_dummy_page(vmf, prot); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index a833751099b55..858aff99a3fe5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1550,10 +1550,6 @@ void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, pgoff_t start, pgoff_t end); vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf); vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf); -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, - enum page_entry_size pe_size); -#endif
/* Transparent hugepage support - vmwgfx_thp.c */ #ifdef CONFIG_TRANSPARENT_HUGEPAGE diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index e5a9a5cbd01a7..922317d1acc8a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -477,7 +477,7 @@ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf) else prot = vm_get_page_prot(vma->vm_flags);
- ret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault, 1); + ret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault); if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) return ret;
@@ -486,73 +486,3 @@ out_unlock:
return ret; } - -#ifdef CONFIG_TRANSPARENT_HUGEPAGE -vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, - enum page_entry_size pe_size) -{ - struct vm_area_struct *vma = vmf->vma; - struct ttm_buffer_object *bo = (struct ttm_buffer_object *) - vma->vm_private_data; - struct vmw_buffer_object *vbo = - container_of(bo, struct vmw_buffer_object, base); - pgprot_t prot; - vm_fault_t ret; - pgoff_t fault_page_size; - bool write = vmf->flags & FAULT_FLAG_WRITE; - - switch (pe_size) { - case PE_SIZE_PMD: - fault_page_size = HPAGE_PMD_SIZE >> PAGE_SHIFT; - break; -#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD - case PE_SIZE_PUD: - fault_page_size = HPAGE_PUD_SIZE >> PAGE_SHIFT; - break; -#endif - default: - WARN_ON_ONCE(1); - return VM_FAULT_FALLBACK; - } - - /* Always do write dirty-tracking and COW on PTE level. */ - if (write && (READ_ONCE(vbo->dirty) || is_cow_mapping(vma->vm_flags))) - return VM_FAULT_FALLBACK; - - ret = ttm_bo_vm_reserve(bo, vmf); - if (ret) - return ret; - - if (vbo->dirty) { - pgoff_t allowed_prefault; - unsigned long page_offset; - - page_offset = vmf->pgoff - - drm_vma_node_start(&bo->base.vma_node); - if (page_offset >= bo->resource->num_pages || - vmw_resources_clean(vbo, page_offset, - page_offset + PAGE_SIZE, - &allowed_prefault)) { - ret = VM_FAULT_SIGBUS; - goto out_unlock; - } - - /* - * Write protect, so we get a new fault on write, and can - * split. - */ - prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED); - } else { - prot = vm_get_page_prot(vma->vm_flags); - } - - ret = ttm_bo_vm_fault_reserved(vmf, prot, 1, fault_page_size); - if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) - return ret; - -out_unlock: - dma_resv_unlock(bo->base.resv); - - return ret; -} -#endif diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c index e6b1f98ec99f0..0a4c340252ec4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -61,9 +61,6 @@ int vmw_mmap(struct file *filp, struct vm_area_struct *vma) .fault = vmw_bo_vm_fault, .open = ttm_bo_vm_open, .close = ttm_bo_vm_close, -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - .huge_fault = vmw_bo_vm_huge_fault, -#endif }; struct drm_file *file_priv = filp->private_data; struct vmw_private *dev_priv = vmw_priv(file_priv->minor->dev); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index f681bbdbc6982..36f7eb9d06639 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -594,8 +594,7 @@ vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, pgprot_t prot, - pgoff_t num_prefault, - pgoff_t fault_page_size); + pgoff_t num_prefault);
vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf);
From: Huang Guobin huangguobin4@huawei.com
[ Upstream commit b93c6a911a3fe926b00add28f3b932007827c4ca ]
When I do fuzz test for bonding device interface, I got the following use-after-free Calltrace:
================================================================== BUG: KASAN: use-after-free in bond_enslave+0x1521/0x24f0 Read of size 8 at addr ffff88825bc11c00 by task ifenslave/7365
CPU: 5 PID: 7365 Comm: ifenslave Tainted: G E 5.15.0-rc1+ #13 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1 04/01/2014 Call Trace: dump_stack_lvl+0x6c/0x8b print_address_description.constprop.0+0x48/0x70 kasan_report.cold+0x82/0xdb __asan_load8+0x69/0x90 bond_enslave+0x1521/0x24f0 bond_do_ioctl+0x3e0/0x450 dev_ifsioc+0x2ba/0x970 dev_ioctl+0x112/0x710 sock_do_ioctl+0x118/0x1b0 sock_ioctl+0x2e0/0x490 __x64_sys_ioctl+0x118/0x150 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f19159cf577 Code: b3 66 90 48 8b 05 11 89 2c 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 78 RSP: 002b:00007ffeb3083c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007ffeb3084bca RCX: 00007f19159cf577 RDX: 00007ffeb3083ce0 RSI: 0000000000008990 RDI: 0000000000000003 RBP: 00007ffeb3084bc4 R08: 0000000000000040 R09: 0000000000000000 R10: 00007ffeb3084bc0 R11: 0000000000000246 R12: 00007ffeb3083ce0 R13: 0000000000000000 R14: 0000000000000000 R15: 00007ffeb3083cb0
Allocated by task 7365: kasan_save_stack+0x23/0x50 __kasan_kmalloc+0x83/0xa0 kmem_cache_alloc_trace+0x22e/0x470 bond_enslave+0x2e1/0x24f0 bond_do_ioctl+0x3e0/0x450 dev_ifsioc+0x2ba/0x970 dev_ioctl+0x112/0x710 sock_do_ioctl+0x118/0x1b0 sock_ioctl+0x2e0/0x490 __x64_sys_ioctl+0x118/0x150 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
Freed by task 7365: kasan_save_stack+0x23/0x50 kasan_set_track+0x20/0x30 kasan_set_free_info+0x24/0x40 __kasan_slab_free+0xf2/0x130 kfree+0xd1/0x5c0 slave_kobj_release+0x61/0x90 kobject_put+0x102/0x180 bond_sysfs_slave_add+0x7a/0xa0 bond_enslave+0x11b6/0x24f0 bond_do_ioctl+0x3e0/0x450 dev_ifsioc+0x2ba/0x970 dev_ioctl+0x112/0x710 sock_do_ioctl+0x118/0x1b0 sock_ioctl+0x2e0/0x490 __x64_sys_ioctl+0x118/0x150 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
Last potentially related work creation: kasan_save_stack+0x23/0x50 kasan_record_aux_stack+0xb7/0xd0 insert_work+0x43/0x190 __queue_work+0x2e3/0x970 delayed_work_timer_fn+0x3e/0x50 call_timer_fn+0x148/0x470 run_timer_softirq+0x8a8/0xc50 __do_softirq+0x107/0x55f
Second to last potentially related work creation: kasan_save_stack+0x23/0x50 kasan_record_aux_stack+0xb7/0xd0 insert_work+0x43/0x190 __queue_work+0x2e3/0x970 __queue_delayed_work+0x130/0x180 queue_delayed_work_on+0xa7/0xb0 bond_enslave+0xe25/0x24f0 bond_do_ioctl+0x3e0/0x450 dev_ifsioc+0x2ba/0x970 dev_ioctl+0x112/0x710 sock_do_ioctl+0x118/0x1b0 sock_ioctl+0x2e0/0x490 __x64_sys_ioctl+0x118/0x150 do_syscall_64+0x35/0xb0 entry_SYSCALL_64_after_hwframe+0x44/0xae
The buggy address belongs to the object at ffff88825bc11c00 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 0 bytes inside of 1024-byte region [ffff88825bc11c00, ffff88825bc12000) The buggy address belongs to the page: page:ffffea00096f0400 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x25bc10 head:ffffea00096f0400 order:3 compound_mapcount:0 compound_pincount:0 flags: 0x57ff00000010200(slab|head|node=1|zone=2|lastcpupid=0x7ff) raw: 057ff00000010200 ffffea0009a71c08 ffff888240001968 ffff88810004dbc0 raw: 0000000000000000 00000000000a000a 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff88825bc11b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88825bc11b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88825bc11c00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff88825bc11c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88825bc11d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ==================================================================
Put new_slave in bond_sysfs_slave_add() will cause use-after-free problems when new_slave is accessed in the subsequent error handling process. Since new_slave will be put in the subsequent error handling process, remove the unnecessary put to fix it. In addition, when sysfs_create_file() fails, if some files have been crea- ted successfully, we need to call sysfs_remove_file() to remove them. Since there are sysfs_create_files() & sysfs_remove_files() can be used, use these two functions instead.
Fixes: 7afcaec49696 (bonding: use kobject_put instead of _del after kobject_add) Signed-off-by: Huang Guobin huangguobin4@huawei.com Reviewed-by: Jakub Kicinski kuba@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/bonding/bond_sysfs_slave.c | 36 ++++++++------------------ 1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/net/bonding/bond_sysfs_slave.c b/drivers/net/bonding/bond_sysfs_slave.c index fd07561da0348..6a6cdd0bb2585 100644 --- a/drivers/net/bonding/bond_sysfs_slave.c +++ b/drivers/net/bonding/bond_sysfs_slave.c @@ -108,15 +108,15 @@ static ssize_t ad_partner_oper_port_state_show(struct slave *slave, char *buf) } static SLAVE_ATTR_RO(ad_partner_oper_port_state);
-static const struct slave_attribute *slave_attrs[] = { - &slave_attr_state, - &slave_attr_mii_status, - &slave_attr_link_failure_count, - &slave_attr_perm_hwaddr, - &slave_attr_queue_id, - &slave_attr_ad_aggregator_id, - &slave_attr_ad_actor_oper_port_state, - &slave_attr_ad_partner_oper_port_state, +static const struct attribute *slave_attrs[] = { + &slave_attr_state.attr, + &slave_attr_mii_status.attr, + &slave_attr_link_failure_count.attr, + &slave_attr_perm_hwaddr.attr, + &slave_attr_queue_id.attr, + &slave_attr_ad_aggregator_id.attr, + &slave_attr_ad_actor_oper_port_state.attr, + &slave_attr_ad_partner_oper_port_state.attr, NULL };
@@ -137,24 +137,10 @@ const struct sysfs_ops slave_sysfs_ops = {
int bond_sysfs_slave_add(struct slave *slave) { - const struct slave_attribute **a; - int err; - - for (a = slave_attrs; *a; ++a) { - err = sysfs_create_file(&slave->kobj, &((*a)->attr)); - if (err) { - kobject_put(&slave->kobj); - return err; - } - } - - return 0; + return sysfs_create_files(&slave->kobj, slave_attrs); }
void bond_sysfs_slave_del(struct slave *slave) { - const struct slave_attribute **a; - - for (a = slave_attrs; *a; ++a) - sysfs_remove_file(&slave->kobj, &((*a)->attr)); + sysfs_remove_files(&slave->kobj, slave_attrs); }
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9cbc3367968de69017a87a1118b62490ac1bdd0a ]
The octeontx2 pf nic driver failsz to link when the devlink support is not reachable:
aarch64-linux-ld: drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.o: in function `otx2_dl_mcam_count_get': otx2_devlink.c:(.text+0x10): undefined reference to `devlink_priv' aarch64-linux-ld: drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.o: in function `otx2_dl_mcam_count_validate': otx2_devlink.c:(.text+0x50): undefined reference to `devlink_priv' aarch64-linux-ld: drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.o: in function `otx2_dl_mcam_count_set': otx2_devlink.c:(.text+0xd0): undefined reference to `devlink_priv' aarch64-linux-ld: drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.o: in function `otx2_devlink_info_get': otx2_devlink.c:(.text+0x150): undefined reference to `devlink_priv'
This is already selected by the admin function driver, but not the actual nic, which might be built-in when the af driver is not.
Fixes: 2da489432747 ("octeontx2-pf: devlink params support to set mcam entry count") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/marvell/octeontx2/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/marvell/octeontx2/Kconfig b/drivers/net/ethernet/marvell/octeontx2/Kconfig index 3f982ccf2c85f..639893d870550 100644 --- a/drivers/net/ethernet/marvell/octeontx2/Kconfig +++ b/drivers/net/ethernet/marvell/octeontx2/Kconfig @@ -31,6 +31,7 @@ config NDC_DIS_DYNAMIC_CACHING config OCTEONTX2_PF tristate "Marvell OcteonTX2 NIC Physical Function driver" select OCTEONTX2_MBOX + select NET_DEVLINK depends on (64BIT && COMPILE_TEST) || ARM64 depends on PCI depends on PTP_1588_CLOCK_OPTIONAL
From: Takashi Iwai tiwai@suse.de
[ Upstream commit dce9446192439eaac81c21f517325fb473735e53 ]
Although we've covered all calls with NULL dma buffer pointer, so far, there may be still some else in the wild. For catching such a case more easily, add a WARN_ON_ONCE() in snd_dma_get_ops().
Fixes: 37af81c5998f ("ALSA: core: Abstract memory alloc helpers") Link: https://lore.kernel.org/r/20211105102103.28148-1-tiwai@suse.de Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/core/memalloc.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 0b8a1c3eae1b4..2d842982576bb 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -494,6 +494,8 @@ static const struct snd_malloc_ops *dma_ops[] = {
static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab) { + if (WARN_ON_ONCE(!dmab)) + return NULL; if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN || dmab->dev.type >= ARRAY_SIZE(dma_ops))) return NULL;
From: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com
[ Upstream commit 002be81140075e17a1ebd5c3c55e356fbab0ddad ]
Early exits from for_each_child_of_node() should decrement the node reference counter. Reported by Coccinelle:
drivers/mfd/mfd-core.c:197:2-24: WARNING: Function "for_each_child_of_node" should have of_node_put() before goto around lines 209.
Fixes: c94bb233a9fe ("mfd: Make MFD core code Device Tree and IRQ domain aware") Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20210528115126.18370-1-krzysztof.kozlowski@canonic... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/mfd-core.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 79f5c6a18815a..684a011a63968 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -198,6 +198,7 @@ static int mfd_add_device(struct device *parent, int id, if (of_device_is_compatible(np, cell->of_compatible)) { /* Ignore 'disabled' devices error free */ if (!of_device_is_available(np)) { + of_node_put(np); ret = 0; goto fail_alias; } @@ -205,6 +206,7 @@ static int mfd_add_device(struct device *parent, int id, ret = mfd_match_of_node_to_dev(pdev, np, cell); if (ret == -EAGAIN) continue; + of_node_put(np); if (ret) goto fail_alias;
From: Mark Brown broonie@kernel.org
[ Upstream commit d5fa8592b773f4da2b04e7333cd37efec5e4ca43 ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding a SPI device ID table.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20210924143347.14721-3-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/motorola-cpcap.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index 6fb206da27298..265464b5d7cc5 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -202,6 +202,13 @@ static const struct of_device_id cpcap_of_match[] = { }; MODULE_DEVICE_TABLE(of, cpcap_of_match);
+static const struct spi_device_id cpcap_spi_ids[] = { + { .name = "cpcap", }, + { .name = "6556002", }, + {}, +}; +MODULE_DEVICE_TABLE(spi, cpcap_spi_ids); + static const struct regmap_config cpcap_regmap_config = { .reg_bits = 16, .reg_stride = 4, @@ -342,6 +349,7 @@ static struct spi_driver cpcap_driver = { .pm = &cpcap_pm, }, .probe = cpcap_probe, + .id_table = cpcap_spi_ids, }; module_spi_driver(cpcap_driver);
From: Mark Brown broonie@kernel.org
[ Upstream commit c5c7f0677107052060037583b9c8c15d818afb04 ]
Currently autoloading for SPI devices does not use the DT ID table, it uses SPI modalises. Supporting OF modalises is going to be difficult if not impractical, an attempt was made but has been reverted, so ensure that module autoloading works for this driver by adding a SPI device ID table.
Fixes: 96c8395e2166 ("spi: Revert modalias changes") Signed-off-by: Mark Brown broonie@kernel.org Reviewed-by: Baolin Wang baolin.wang7@gmail.com Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20210924143347.14721-4-broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/sprd-sc27xx-spi.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/mfd/sprd-sc27xx-spi.c b/drivers/mfd/sprd-sc27xx-spi.c index 6b7956604a0f0..9890882db1ed3 100644 --- a/drivers/mfd/sprd-sc27xx-spi.c +++ b/drivers/mfd/sprd-sc27xx-spi.c @@ -236,6 +236,12 @@ static const struct of_device_id sprd_pmic_match[] = { }; MODULE_DEVICE_TABLE(of, sprd_pmic_match);
+static const struct spi_device_id sprd_pmic_spi_ids[] = { + { .name = "sc2731", .driver_data = (unsigned long)&sc2731_data }, + {}, +}; +MODULE_DEVICE_TABLE(spi, sprd_pmic_spi_ids); + static struct spi_driver sprd_pmic_driver = { .driver = { .name = "sc27xx-pmic", @@ -243,6 +249,7 @@ static struct spi_driver sprd_pmic_driver = { .pm = &sprd_pmic_pm_ops, }, .probe = sprd_pmic_probe, + .id_table = sprd_pmic_spi_ids, };
static int __init sprd_pmic_init(void)
From: Kai Song songkai01@inspur.com
[ Upstream commit fae2570d629cdd72f0611d015fc4ba705ae5422b ]
The resource_size defines that: res->end - res->start + 1; The origin original code is: sysmgr_config.max_register = res->end - res->start - 3;
So, the correct fix is that: sysmgr_config.max_register = resource_size(res) - 4;
Fixes: d12edf9661a4 ("mfd: altera-sysmgr: Use resource_size function on resource object") Signed-off-by: Kai Song songkai01@inspur.com Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20211006141926.6120-1-songkai01@inspur.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/altera-sysmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c index 20cb294c75122..5d3715a28b28e 100644 --- a/drivers/mfd/altera-sysmgr.c +++ b/drivers/mfd/altera-sysmgr.c @@ -153,7 +153,7 @@ static int sysmgr_probe(struct platform_device *pdev) if (!base) return -ENOMEM;
- sysmgr_config.max_register = resource_size(res) - 3; + sysmgr_config.max_register = resource_size(res) - 4; regmap = devm_regmap_init_mmio(dev, base, &sysmgr_config); }
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit 452a3e723f75880757acf87b053935c43aa89f89 ]
Fix a device wakeup power reference counting error introduced by commit a2d7b2e004af ("ACPI: PM: Fix sharing of wakeup power resources") because of a coding mistake.
Fixes: a2d7b2e004af ("ACPI: PM: Fix sharing of wakeup power resources") Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/power.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 4b42debeed455..c95eedd58f5bf 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -755,13 +755,11 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
mutex_lock(&acpi_device_lock);
- if (dev->wakeup.prepare_count > 1) { - dev->wakeup.prepare_count--; + /* Do nothing if wakeup power has not been enabled for this device. */ + if (dev->wakeup.prepare_count <= 0) goto out; - }
- /* Do nothing if wakeup power has not been enabled for this device. */ - if (!dev->wakeup.prepare_count) + if (--dev->wakeup.prepare_count > 0) goto out;
err = acpi_device_sleep_wake(dev, 0, 0, 0);
From: Mehrdad Arshad Rad arshad.rad@gmail.com
[ Upstream commit 64165ddf8ea184631c65e3bbc8d59f6d940590ca ]
Fix bpf_map_lookup_and_delete_elem_flags() to pass the return code through libbpf_err_errno() as we do similarly in bpf_map_lookup_and_delete_elem().
Fixes: f12b65432728 ("libbpf: Streamline error reporting for low-level APIs") Signed-off-by: Mehrdad Arshad Rad arshad.rad@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Yonghong Song yhs@fb.com Link: https://lore.kernel.org/bpf/20211104171354.11072-1-arshad.rad@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/bpf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 2401fad090c52..bfd1ce9fe2110 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -480,6 +480,7 @@ int bpf_map_lookup_and_delete_elem(int fd, const void *key, void *value) int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, __u64 flags) { union bpf_attr attr; + int ret;
memset(&attr, 0, sizeof(attr)); attr.map_fd = fd; @@ -487,7 +488,8 @@ int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, _ attr.value = ptr_to_u64(value); attr.flags = flags;
- return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); + ret = sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); + return libbpf_err_errno(ret); }
int bpf_map_delete_elem(int fd, const void *key)
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 8b4ac13abe7d82da0e0d22a9ba2e27301559a93e ]
The xdp_redirect_multi test logs are created in selftest folder and not cleaned after test. Let's creat a tmp dir and remove the logs after testing.
Fixes: d23292476297 ("selftests/bpf: Add xdp_redirect_multi test") Suggested-by: Jiri Benc jbenc@redhat.com Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20211027033553.962413-2-liuhangbin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/bpf/test_xdp_redirect_multi.sh | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh index 1538373157e3c..b20b96ba72ef0 100755 --- a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh +++ b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh @@ -31,6 +31,7 @@ IFACES="" DRV_MODE="xdpgeneric xdpdrv xdpegress" PASS=0 FAIL=0 +LOG_DIR=$(mktemp -d)
test_pass() { @@ -100,17 +101,17 @@ do_egress_tests() local mode=$1
# mac test - ip netns exec ns2 tcpdump -e -i veth0 -nn -l -e &> mac_ns1-2_${mode}.log & - ip netns exec ns3 tcpdump -e -i veth0 -nn -l -e &> mac_ns1-3_${mode}.log & + ip netns exec ns2 tcpdump -e -i veth0 -nn -l -e &> ${LOG_DIR}/mac_ns1-2_${mode}.log & + ip netns exec ns3 tcpdump -e -i veth0 -nn -l -e &> ${LOG_DIR}/mac_ns1-3_${mode}.log & sleep 0.5 ip netns exec ns1 ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null sleep 0.5 pkill -9 tcpdump
# mac check - grep -q "${veth_mac[2]} > ff:ff:ff:ff:ff:ff" mac_ns1-2_${mode}.log && \ + grep -q "${veth_mac[2]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-2_${mode}.log && \ test_pass "$mode mac ns1-2" || test_fail "$mode mac ns1-2" - grep -q "${veth_mac[3]} > ff:ff:ff:ff:ff:ff" mac_ns1-3_${mode}.log && \ + grep -q "${veth_mac[3]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-3_${mode}.log && \ test_pass "$mode mac ns1-3" || test_fail "$mode mac ns1-3" }
@@ -121,9 +122,9 @@ do_ping_tests() # ping6 test: echo request should be redirect back to itself, not others ip netns exec ns1 ip neigh add 2001:db8::2 dev veth0 lladdr 00:00:00:00:00:02
- ip netns exec ns1 tcpdump -i veth0 -nn -l -e &> ns1-1_${mode}.log & - ip netns exec ns2 tcpdump -i veth0 -nn -l -e &> ns1-2_${mode}.log & - ip netns exec ns3 tcpdump -i veth0 -nn -l -e &> ns1-3_${mode}.log & + ip netns exec ns1 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-1_${mode}.log & + ip netns exec ns2 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-2_${mode}.log & + ip netns exec ns3 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-3_${mode}.log & sleep 0.5 # ARP test ip netns exec ns1 ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null @@ -135,32 +136,32 @@ do_ping_tests() pkill -9 tcpdump
# All netns should receive the redirect arp requests - [ $(grep -c "who-has 192.0.2.254" ns1-1_${mode}.log) -gt 4 ] && \ + [ $(grep -c "who-has 192.0.2.254" ${LOG_DIR}/ns1-1_${mode}.log) -gt 4 ] && \ test_pass "$mode arp(F_BROADCAST) ns1-1" || \ test_fail "$mode arp(F_BROADCAST) ns1-1" - [ $(grep -c "who-has 192.0.2.254" ns1-2_${mode}.log) -le 4 ] && \ + [ $(grep -c "who-has 192.0.2.254" ${LOG_DIR}/ns1-2_${mode}.log) -le 4 ] && \ test_pass "$mode arp(F_BROADCAST) ns1-2" || \ test_fail "$mode arp(F_BROADCAST) ns1-2" - [ $(grep -c "who-has 192.0.2.254" ns1-3_${mode}.log) -le 4 ] && \ + [ $(grep -c "who-has 192.0.2.254" ${LOG_DIR}/ns1-3_${mode}.log) -le 4 ] && \ test_pass "$mode arp(F_BROADCAST) ns1-3" || \ test_fail "$mode arp(F_BROADCAST) ns1-3"
# ns1 should not receive the redirect echo request, others should - [ $(grep -c "ICMP echo request" ns1-1_${mode}.log) -eq 4 ] && \ + [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-1" || \ test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-1" - [ $(grep -c "ICMP echo request" ns1-2_${mode}.log) -eq 4 ] && \ + [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-2_${mode}.log) -eq 4 ] && \ test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-2" || \ test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-2" - [ $(grep -c "ICMP echo request" ns1-3_${mode}.log) -eq 4 ] && \ + [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-3_${mode}.log) -eq 4 ] && \ test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-3" || \ test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-3"
# ns1 should receive the echo request, ns2 should not - [ $(grep -c "ICMP6, echo request" ns1-1_${mode}.log) -eq 4 ] && \ + [ $(grep -c "ICMP6, echo request" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ test_pass "$mode IPv6 (no flags) ns1-1" || \ test_fail "$mode IPv6 (no flags) ns1-1" - [ $(grep -c "ICMP6, echo request" ns1-2_${mode}.log) -eq 0 ] && \ + [ $(grep -c "ICMP6, echo request" ${LOG_DIR}/ns1-2_${mode}.log) -eq 0 ] && \ test_pass "$mode IPv6 (no flags) ns1-2" || \ test_fail "$mode IPv6 (no flags) ns1-2" } @@ -176,7 +177,7 @@ do_tests() xdpgeneric) drv_p="-S";; esac
- ./xdp_redirect_multi $drv_p $IFACES &> xdp_redirect_${mode}.log & + ./xdp_redirect_multi $drv_p $IFACES &> ${LOG_DIR}/xdp_redirect_${mode}.log & xdp_pid=$! sleep 1
@@ -192,13 +193,13 @@ do_tests() trap clean_up 0 2 3 6 9
check_env -rm -f xdp_redirect_*.log ns*.log mac_ns*.log
for mode in ${DRV_MODE}; do setup_ns $mode do_tests $mode clean_up done +rm -rf ${LOG_DIR}
echo "Summary: PASS $PASS, FAIL $FAIL" [ $FAIL -eq 0 ] && exit 0 || exit 1
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit f53ea9dbf78d42a10e2392b5c59362ccc224fd1d ]
The arp request number triggered by ping none exist address is not accurate, which may lead the test false negative/positive. Change to use arping to accurate the arp number. Also do not use grep pattern match for dot.
Fixes: d23292476297 ("selftests/bpf: Add xdp_redirect_multi test") Suggested-by: Jiri Benc jbenc@redhat.com Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20211027033553.962413-3-liuhangbin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_xdp_redirect_multi.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh index b20b96ba72ef0..c2a933caa32d4 100755 --- a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh +++ b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh @@ -127,7 +127,7 @@ do_ping_tests() ip netns exec ns3 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-3_${mode}.log & sleep 0.5 # ARP test - ip netns exec ns1 ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null + ip netns exec ns1 arping -q -c 2 -I veth0 192.0.2.254 # IPv4 test ip netns exec ns1 ping 192.0.2.253 -i 0.1 -c 4 &> /dev/null # IPv6 test @@ -136,13 +136,13 @@ do_ping_tests() pkill -9 tcpdump
# All netns should receive the redirect arp requests - [ $(grep -c "who-has 192.0.2.254" ${LOG_DIR}/ns1-1_${mode}.log) -gt 4 ] && \ + [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ test_pass "$mode arp(F_BROADCAST) ns1-1" || \ test_fail "$mode arp(F_BROADCAST) ns1-1" - [ $(grep -c "who-has 192.0.2.254" ${LOG_DIR}/ns1-2_${mode}.log) -le 4 ] && \ + [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-2_${mode}.log) -eq 2 ] && \ test_pass "$mode arp(F_BROADCAST) ns1-2" || \ test_fail "$mode arp(F_BROADCAST) ns1-2" - [ $(grep -c "who-has 192.0.2.254" ${LOG_DIR}/ns1-3_${mode}.log) -le 4 ] && \ + [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-3_${mode}.log) -eq 2 ] && \ test_pass "$mode arp(F_BROADCAST) ns1-3" || \ test_fail "$mode arp(F_BROADCAST) ns1-3"
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 648c3677062fbd14d754b853daebb295426771e8 ]
No need to kill tcpdump with -9.
Fixes: d23292476297 ("selftests/bpf: Add xdp_redirect_multi test") Suggested-by: Jiri Benc jbenc@redhat.com Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20211027033553.962413-4-liuhangbin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/test_xdp_redirect_multi.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh index c2a933caa32d4..37e347159ab44 100755 --- a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh +++ b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh @@ -106,7 +106,7 @@ do_egress_tests() sleep 0.5 ip netns exec ns1 ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null sleep 0.5 - pkill -9 tcpdump + pkill tcpdump
# mac check grep -q "${veth_mac[2]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-2_${mode}.log && \ @@ -133,7 +133,7 @@ do_ping_tests() # IPv6 test ip netns exec ns1 ping6 2001:db8::2 -i 0.1 -c 2 &> /dev/null sleep 0.5 - pkill -9 tcpdump + pkill tcpdump
# All netns should receive the redirect arp requests [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \
From: Hangbin Liu liuhangbin@gmail.com
[ Upstream commit 8955c1a329873385775081e029d9a7c6aa9037e1 ]
As I want to test both DEVMAP and DEVMAP_HASH in XDP multicast redirect, I limited DEVMAP max entries to a small value for performace. When the test runs after amount of interface creating/deleting tests. The interface index will exceed the map max entries and xdp_redirect_multi will error out with "Get interfacesInterface index to large".
Fix this issue by limit the tests in netns and specify the ifindex when creating interfaces.
Fixes: d23292476297 ("selftests/bpf: Add xdp_redirect_multi test") Reported-by: Jiri Benc jbenc@redhat.com Signed-off-by: Hangbin Liu liuhangbin@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Link: https://lore.kernel.org/bpf/20211027033553.962413-5-liuhangbin@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../selftests/bpf/test_xdp_redirect_multi.sh | 23 ++++++++++++------- .../selftests/bpf/xdp_redirect_multi.c | 4 ++-- 2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh index 37e347159ab44..bedff7aa7023f 100755 --- a/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh +++ b/tools/testing/selftests/bpf/test_xdp_redirect_multi.sh @@ -2,11 +2,11 @@ # SPDX-License-Identifier: GPL-2.0 # # Test topology: -# - - - - - - - - - - - - - - - - - - - - - - - - - -# | veth1 veth2 veth3 | ... init net +# - - - - - - - - - - - - - - - - - - - +# | veth1 veth2 veth3 | ns0 # - -| - - - - - - | - - - - - - | - - # --------- --------- --------- -# | veth0 | | veth0 | | veth0 | ... +# | veth0 | | veth0 | | veth0 | # --------- --------- --------- # ns1 ns2 ns3 # @@ -51,6 +51,7 @@ clean_up() ip link del veth$i 2> /dev/null ip netns del ns$i 2> /dev/null done + ip netns del ns0 2> /dev/null }
# Kselftest framework requirement - SKIP code is 4. @@ -78,10 +79,12 @@ setup_ns() mode="xdpdrv" fi
+ ip netns add ns0 for i in $(seq $NUM); do ip netns add ns$i - ip link add veth$i type veth peer name veth0 netns ns$i - ip link set veth$i up + ip -n ns$i link add veth0 index 2 type veth \ + peer name veth$i netns ns0 index $((1 + $i)) + ip -n ns0 link set veth$i up ip -n ns$i link set veth0 up
ip -n ns$i addr add 192.0.2.$i/24 dev veth0 @@ -92,7 +95,7 @@ setup_ns() xdp_dummy.o sec xdp_dummy &> /dev/null || \ { test_fail "Unable to load dummy xdp" && exit 1; } IFACES="$IFACES veth$i" - veth_mac[$i]=$(ip link show veth$i | awk '/link/ether/ {print $2}') + veth_mac[$i]=$(ip -n ns0 link show veth$i | awk '/link/ether/ {print $2}') done }
@@ -177,9 +180,13 @@ do_tests() xdpgeneric) drv_p="-S";; esac
- ./xdp_redirect_multi $drv_p $IFACES &> ${LOG_DIR}/xdp_redirect_${mode}.log & + ip netns exec ns0 ./xdp_redirect_multi $drv_p $IFACES &> ${LOG_DIR}/xdp_redirect_${mode}.log & xdp_pid=$! sleep 1 + if ! ps -p $xdp_pid > /dev/null; then + test_fail "$mode xdp_redirect_multi start failed" + return 1 + fi
if [ "$mode" = "xdpegress" ]; then do_egress_tests $mode @@ -190,7 +197,7 @@ do_tests() kill $xdp_pid }
-trap clean_up 0 2 3 6 9 +trap clean_up EXIT
check_env
diff --git a/tools/testing/selftests/bpf/xdp_redirect_multi.c b/tools/testing/selftests/bpf/xdp_redirect_multi.c index 3696a8f32c235..f5ffba341c174 100644 --- a/tools/testing/selftests/bpf/xdp_redirect_multi.c +++ b/tools/testing/selftests/bpf/xdp_redirect_multi.c @@ -129,7 +129,7 @@ int main(int argc, char **argv) goto err_out; }
- printf("Get interfaces"); + printf("Get interfaces:"); for (i = 0; i < MAX_IFACE_NUM && argv[optind + i]; i++) { ifaces[i] = if_nametoindex(argv[optind + i]); if (!ifaces[i]) @@ -139,7 +139,7 @@ int main(int argc, char **argv) goto err_out; } if (ifaces[i] > MAX_INDEX_NUM) { - printf("Interface index to large\n"); + printf(" interface index too large\n"); goto err_out; } printf(" %d", ifaces[i]);
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9d6366e743f37d36ef69347924ead7bcc596076e ]
My previous patch correctly addressed the possible link failure, but as Jani points out, the dependency is now stricter than it needs to be.
Change it again, to allow DRM_FBDEV_EMULATION to be used when DRM_KMS_HELPER and FB are both loadable modules and DRM is linked into the kernel.
As a side-effect, the option is now only visible when at least one DRM driver makes use of DRM_KMS_HELPER. This is better, because the option has no effect otherwise.
Fixes: 606b102876e3 ("drm: fb_helper: fix CONFIG_FB dependency") Suggested-by: Acked-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20211029120307.1407047-1-arnd@... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 9199f53861cac..6ae4269118af3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -102,9 +102,8 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS
config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" - depends on DRM - depends on FB=y || FB=DRM - select DRM_KMS_HELPER + depends on DRM_KMS_HELPER + depends on FB=y || FB=DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT
On 15. 11. 21, 18:05, Greg Kroah-Hartman wrote:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9d6366e743f37d36ef69347924ead7bcc596076e ]
Hi,
this breaks build on openSUSE's armv7hl config: $ wget -O .config https://raw.githubusercontent.com/openSUSE/kernel-source/stable/config/armv7... $ make -j168 CROSS_COMPILE=arm-suse-linux-gnueabi- ARCH=arm vmlinux ... LD .tmp_vmlinux.btf arm-suse-linux-gnueabi-ld: drivers/gpu/drm/panel/panel-simple.o: in function `panel_simple_probe': drivers/gpu/drm/panel/panel-simple.c:803: undefined reference to `drm_panel_dp_aux_backlight' $ grep -E 'CONFIG_(DRM|FB|DRM_KMS_HELPER|DRM_FBDEV_EMULATION)>' .config CONFIG_DRM=y CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_FBDEV_EMULATION=y CONFIG_FB=y
5.16-rc1 builds just fine -- investigating why…
My previous patch correctly addressed the possible link failure, but as Jani points out, the dependency is now stricter than it needs to be.
Change it again, to allow DRM_FBDEV_EMULATION to be used when DRM_KMS_HELPER and FB are both loadable modules and DRM is linked into the kernel.
As a side-effect, the option is now only visible when at least one DRM driver makes use of DRM_KMS_HELPER. This is better, because the option has no effect otherwise.
Fixes: 606b102876e3 ("drm: fb_helper: fix CONFIG_FB dependency") Suggested-by: Acked-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20211029120307.1407047-1-arnd@... Signed-off-by: Sasha Levin sashal@kernel.org
drivers/gpu/drm/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 9199f53861cac..6ae4269118af3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -102,9 +102,8 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver"
- depends on DRM
- depends on FB=y || FB=DRM
- select DRM_KMS_HELPER
- depends on DRM_KMS_HELPER
- depends on FB=y || FB=DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT
On 19. 11. 21, 8:50, Jiri Slaby wrote:
On 15. 11. 21, 18:05, Greg Kroah-Hartman wrote:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9d6366e743f37d36ef69347924ead7bcc596076e ]
Hi,
this breaks build on openSUSE's armv7hl config: $ wget -O .config https://raw.githubusercontent.com/openSUSE/kernel-source/stable/config/armv7...
$ make -j168 CROSS_COMPILE=arm-suse-linux-gnueabi- ARCH=arm vmlinux ... LD .tmp_vmlinux.btf arm-suse-linux-gnueabi-ld: drivers/gpu/drm/panel/panel-simple.o: in function `panel_simple_probe': drivers/gpu/drm/panel/panel-simple.c:803: undefined reference to `drm_panel_dp_aux_backlight' $ grep -E 'CONFIG_(DRM|FB|DRM_KMS_HELPER|DRM_FBDEV_EMULATION)>' .config CONFIG_DRM=y CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_FBDEV_EMULATION=y CONFIG_FB=y
5.16-rc1 builds just fine -- investigating why…
CLearly because the code moved to panel-edp.c. So doing: -CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_EDP=y leads to the same error in that file: arm-suse-linux-gnueabi-ld: drivers/gpu/drm/panel/panel-edp.o: in function `panel_edp_probe': drivers/gpu/drm/panel/panel-edp.c:843: undefined reference to `drm_panel_dp_aux_backlight'
My previous patch correctly addressed the possible link failure, but as Jani points out, the dependency is now stricter than it needs to be.
Change it again, to allow DRM_FBDEV_EMULATION to be used when DRM_KMS_HELPER and FB are both loadable modules and DRM is linked into the kernel.
As a side-effect, the option is now only visible when at least one DRM driver makes use of DRM_KMS_HELPER. This is better, because the option has no effect otherwise.
Fixes: 606b102876e3 ("drm: fb_helper: fix CONFIG_FB dependency") Suggested-by: Acked-by: Jani Nikula jani.nikula@intel.com Reviewed-by: Javier Martinez Canillas javierm@redhat.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20211029120307.1407047-1-arnd@...
Signed-off-by: Sasha Levin sashal@kernel.org
drivers/gpu/drm/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 9199f53861cac..6ae4269118af3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -102,9 +102,8 @@ config DRM_DEBUG_DP_MST_TOPOLOGY_REFS config DRM_FBDEV_EMULATION bool "Enable legacy fbdev support for your modesetting driver" - depends on DRM - depends on FB=y || FB=DRM - select DRM_KMS_HELPER + depends on DRM_KMS_HELPER + depends on FB=y || FB=DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT
On Fri, Nov 19, 2021 at 8:56 AM Jiri Slaby jirislaby@kernel.org wrote:
On 19. 11. 21, 8:50, Jiri Slaby wrote:
On 15. 11. 21, 18:05, Greg Kroah-Hartman wrote:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9d6366e743f37d36ef69347924ead7bcc596076e ]
Hi,
this breaks build on openSUSE's armv7hl config: $ wget -O .config https://raw.githubusercontent.com/openSUSE/kernel-source/stable/config/armv7...
$ make -j168 CROSS_COMPILE=arm-suse-linux-gnueabi- ARCH=arm vmlinux ... LD .tmp_vmlinux.btf arm-suse-linux-gnueabi-ld: drivers/gpu/drm/panel/panel-simple.o: in function `panel_simple_probe': drivers/gpu/drm/panel/panel-simple.c:803: undefined reference to `drm_panel_dp_aux_backlight' $ grep -E 'CONFIG_(DRM|FB|DRM_KMS_HELPER|DRM_FBDEV_EMULATION)>' .config CONFIG_DRM=y CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_FBDEV_EMULATION=y CONFIG_FB=y
5.16-rc1 builds just fine -- investigating why…
CLearly because the code moved to panel-edp.c. So doing: -CONFIG_DRM_PANEL_EDP=m +CONFIG_DRM_PANEL_EDP=y leads to the same error in that file: arm-suse-linux-gnueabi-ld: drivers/gpu/drm/panel/panel-edp.o: in function `panel_edp_probe': drivers/gpu/drm/panel/panel-edp.c:843: undefined reference to `drm_panel_dp_aux_backlight'
Ah right, I ran into a similar thing on my randconfig builds, this is what I have applied locally but wasn't completely sure about yet, it may need additional 'select DRM_KMS_CMA_HELPER' to cover all instances:
commit 8dd05af5243f3ab968b317ef82b3c0d04079b805 Author: Arnd Bergmann arnd@arndb.de Date: Mon Nov 15 16:54:04 2021 +0100
drm/mipi-dbi: select CONFIG_DRM_KMS_HELPER
The driver fails to build when the KMS helpers are disabled:
ld.lld: error: undefined symbol: drm_gem_fb_get_obj >>> referenced by drm_mipi_dbi.c >>> gpu/drm/drm_mipi_dbi.o:(mipi_dbi_buf_copy) in archive drivers/built-in.a >>> referenced by drm_mipi_dbi.c >>> gpu/drm/drm_mipi_dbi.o:(mipi_dbi_fb_dirty) in archive drivers/built-in.a
ld.lld: error: undefined symbol: drm_gem_fb_begin_cpu_access >>> referenced by drm_mipi_dbi.c >>> gpu/drm/drm_mipi_dbi.o:(mipi_dbi_buf_copy) in archive drivers/built-in.a
ld.lld: error: undefined symbol: drm_fb_swab >>> referenced by drm_mipi_dbi.c >>> gpu/drm/drm_mipi_dbi.o:(mipi_dbi_buf_copy) in archive drivers/built-in.a
ld.lld: error: undefined symbol: drm_fb_xrgb8888_to_rgb565 >>> referenced by drm_mipi_dbi.c >>> gpu/drm/drm_mipi_dbi.o:(mipi_dbi_buf_copy) in archive drivers/built-in.a
ld.lld: error: undefined symbol: drm_fb_memcpy >>> referenced by drm_mipi_dbi.c >>> gpu/drm/drm_mipi_dbi.o:(mipi_dbi_buf_copy) in archive drivers/built-in.a
This is fairly hard to hit in randconfig drivers, but it eventually did trigger for me in a configuration where all other DRM drivers are loadable modules, but DRM_PANEL_WIDECHIPS_WS2401 was built-in.
Signed-off-by: Arnd Bergmann arnd@arndb.de
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 0039df26854b..a03c2761c5f9 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -29,6 +29,7 @@ menuconfig DRM
config DRM_MIPI_DBI tristate + select DRM_KMS_HELPER depends on DRM
config DRM_MIPI_DSI diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 431b6e12a81f..17a8d603e7d8 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -8,7 +8,6 @@ config DRM_BRIDGE config DRM_PANEL_BRIDGE def_bool y depends on DRM_BRIDGE - depends on DRM_KMS_HELPER select DRM_PANEL help DRM bridge wrapper of DRM panels diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index cfc8d644cedf..40ec20f3552d 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -140,9 +140,8 @@ config DRM_PANEL_ILITEK_IL9322 config DRM_PANEL_ILITEK_ILI9341 tristate "Ilitek ILI9341 240x320 QVGA panels" depends on OF && SPI - depends on DRM_KMS_HELPER - depends on DRM_KMS_CMA_HELPER depends on BACKLIGHT_CLASS_DEVICE + select DRM_KMS_CMA_HELPER select DRM_MIPI_DBI help Say Y here if you want to enable support for Ilitek IL9341
Arnd Bergmann arnd@arndb.de writes:
Ah right, I ran into a similar thing on my randconfig builds, this is what I have applied locally but wasn't completely sure about yet, it may need additional 'select DRM_KMS_CMA_HELPER' to cover all instances:
With 5.15.3, I had these errors on *one* of my boxes with Nvidia drivers when building the nvidia drivers
Gentoo, nvidia-drivers-470.86
ERROR: modpost: "drm_atomic_helper_update_plane" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_connector_reset" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_page_flip" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_swap_state" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_helper_probe_single_connector_modes" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_kms_helper_hotplug_event" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "__drm_atomic_helper_crtc_destroy_state" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_crtc_reset" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "__drm_atomic_helper_plane_duplicate_state" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_connector_duplicate_state" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! WARNING: modpost: suppressed 12 unresolved symbol warnings because there were too many)
After "make oldconfig", many DRM settings have been lost. Enabling "CONFIG_DRM_CIRRUS_QEMU" gets them back, though a better way should be found.
$ uname -a Linux bilbo 5.15.2 #3 SMP PREEMPT Fri Nov 12 14:41:08 GMT 2021 x86_64 AMD FX(tm)-4300 Quad-Core Processor AuthenticAMD GNU/Linux
$ zcat /proc/config.gz > .config
$ grep CONFIG_DRM .config | grep -v "is not set$" CONFIG_DRM=m CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_I2C_CH7006=m CONFIG_DRM_I2C_SIL164=m CONFIG_DRM_PANEL=y CONFIG_DRM_BRIDGE=y CONFIG_DRM_PANEL_BRIDGE=y CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=m
$ make oldconfig # # configuration written to .config #
$ grep CONFIG_DRM .config | grep -v "is not set$" CONFIG_DRM=m CONFIG_DRM_BRIDGE=y CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=m
Comparing with the working system, that has VMM installed, and hence
CONFIG_DRM_CIRRUS_QEMU=m
Setting this and things are working again.
$ zcat /proc/config.gz > .config
$ ./scripts/config --enable CONFIG_DRM_CIRRUS_QEMU
$ make oldconfig # # configuration written to .config #
$ grep CONFIG_DRM .config | grep -v "is not set$" CONFIG_DRM=m CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_GEM_SHMEM_HELPER=y CONFIG_DRM_I2C_CH7006=m CONFIG_DRM_I2C_SIL164=m CONFIG_DRM_PANEL=y CONFIG_DRM_BRIDGE=y CONFIG_DRM_PANEL_BRIDGE=y CONFIG_DRM_CIRRUS_QEMU=m CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=m $
On Fri, Nov 19, 2021 at 9:57 AM Alan J. Wylie alan@wylie.me.uk wrote:
Arnd Bergmann arnd@arndb.de writes:
Ah right, I ran into a similar thing on my randconfig builds, this is what I have applied locally but wasn't completely sure about yet, it may need additional 'select DRM_KMS_CMA_HELPER' to cover all instances:
With 5.15.3, I had these errors on *one* of my boxes with Nvidia drivers when building the nvidia drivers
Gentoo, nvidia-drivers-470.86
ERROR: modpost: "drm_atomic_helper_update_plane" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_connector_reset" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko] undefined! ERROR: modpost: "drm_atomic_helper_page_flip" [/work/tmp/portage/x11-drivers/nvidia-drivers-470.86/work/kernel/nvidia-drm.ko]
To be honest, I'm not overly stressed out about breaking external modules. It is true that this driver only builds when CONFIG_DRM_KMS_HELPER is set, so you end up having to enable some other driver that selects it because the kernel doesn't know what symbols would be used. If you enable CONFIG_TRIM_UNUSED_KSYMS, you'd likely get additional problems here.
Before my patch, the kms helpers were selected by CONFIG_DRM_FBDEV_EMULATION in your .config, but this made no sense unless you also have a third-party module that uses it.
Arnd
On Fri, Nov 19, 2021 at 08:50:05AM +0100, Jiri Slaby wrote:
On 15. 11. 21, 18:05, Greg Kroah-Hartman wrote:
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 9d6366e743f37d36ef69347924ead7bcc596076e ]
Hi,
this breaks build on openSUSE's armv7hl config: $ wget -O .config https://raw.githubusercontent.com/openSUSE/kernel-source/stable/config/armv7... $ make -j168 CROSS_COMPILE=arm-suse-linux-gnueabi- ARCH=arm vmlinux ... LD .tmp_vmlinux.btf arm-suse-linux-gnueabi-ld: drivers/gpu/drm/panel/panel-simple.o: in function `panel_simple_probe': drivers/gpu/drm/panel/panel-simple.c:803: undefined reference to `drm_panel_dp_aux_backlight' $ grep -E 'CONFIG_(DRM|FB|DRM_KMS_HELPER|DRM_FBDEV_EMULATION)>' .config CONFIG_DRM=y CONFIG_DRM_KMS_HELPER=m CONFIG_DRM_FBDEV_EMULATION=y CONFIG_FB=y
5.16-rc1 builds just fine -- investigating why…
Ok, will go revert that, thanks.
greg k-h
From: Fabio Estevam festevam@gmail.com
[ Upstream commit 14d9a37c952588930d7226953359fea3ab956d39 ]
This reverts commit f4b34faa08428d813fc3629f882c503487f94a12.
Since commit f4b34faa0842 ("drm/imx: Annotate dma-fence critical section in commit path") the following possible circular dependency is detected:
[ 5.001811] ====================================================== [ 5.001817] WARNING: possible circular locking dependency detected [ 5.001824] 5.14.9-01225-g45da36cc6fcc-dirty #1 Tainted: G W [ 5.001833] ------------------------------------------------------ [ 5.001838] kworker/u8:0/7 is trying to acquire lock: [ 5.001848] c1752080 (regulator_list_mutex){+.+.}-{3:3}, at: regulator_lock_dependent+0x40/0x294 [ 5.001903] [ 5.001903] but task is already holding lock: [ 5.001909] c176df78 (dma_fence_map){++++}-{0:0}, at: imx_drm_atomic_commit_tail+0x10/0x160 [ 5.001957] [ 5.001957] which lock already depends on the new lock. ...
Revert it for now.
Tested on a imx6q-sabresd.
Fixes: f4b34faa0842 ("drm/imx: Annotate dma-fence critical section in commit path") Signed-off-by: Fabio Estevam festevam@gmail.com Signed-off-by: Daniel Vetter daniel.vetter@ffwll.ch Link: https://patchwork.freedesktop.org/patch/msgid/20211104001112.4035691-1-feste... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/imx/imx-drm-core.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 9558e9e1b431b..cb685fe2039b4 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -81,7 +81,6 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) struct drm_plane_state *old_plane_state, *new_plane_state; bool plane_disabling = false; int i; - bool fence_cookie = dma_fence_begin_signalling();
drm_atomic_helper_commit_modeset_disables(dev, state);
@@ -112,7 +111,6 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) }
drm_atomic_helper_commit_hw_done(state); - dma_fence_end_signalling(fence_cookie); }
static const struct drm_mode_config_helper_funcs imx_drm_mode_config_helpers = {
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit e9c76719c1e99caf95e70de74170291b9457bbc1 ]
sysfs_emit and sysfs_emit_at requrie a page boundary aligned buf address. Make them happy!
v2: fix sysfs_emit -> sysfs_emit_at missed conversions
Cc: Lang Yu lang.yu@amd.com Cc: Darren Powell darren.powell@amd.com Fixes: 6db0c87a0a8e ("amdgpu/pm: Replace hwmgr smu usage of sprintf with sysfs_emit") Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1774 Reviewed-by: Lang Yu lang.yu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 8 ++++++-- .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c | 10 +++++++--- .../gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c | 2 ++ .../gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h | 13 +++++++++++++ .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 12 +++++++++--- .../gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 4 ++++ .../gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 14 ++++++++++---- 7 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 1de3ae77e03ed..258c573acc979 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -1024,6 +1024,8 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, uint32_t min_freq, max_freq = 0; uint32_t ret = 0;
+ phm_get_sysfs_buf(&buf, &size); + switch (type) { case PP_SCLK: smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency, &now); @@ -1065,7 +1067,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, if (ret) return ret;
- size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); size += sysfs_emit_at(buf, size, "0: %10uMhz\n", (data->gfx_actual_soft_min_freq > 0) ? data->gfx_actual_soft_min_freq : min_freq); size += sysfs_emit_at(buf, size, "1: %10uMhz\n", @@ -1081,7 +1083,7 @@ static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr, if (ret) return ret;
- size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", min_freq, max_freq); } @@ -1456,6 +1458,8 @@ static int smu10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) if (!buf) return -EINVAL;
+ phm_get_sysfs_buf(&buf, &size); + size += sysfs_emit_at(buf, size, "%s %16s %s %s %s %s\n",title[0], title[1], title[2], title[3], title[4], title[5]);
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index e7803ce8f67aa..aceebf5842253 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -4914,6 +4914,8 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, int size = 0; uint32_t i, now, clock, pcie_speed;
+ phm_get_sysfs_buf(&buf, &size); + switch (type) { case PP_SCLK: smum_send_msg_to_smc(hwmgr, PPSMC_MSG_API_GetSclkFrequency, &clock); @@ -4963,7 +4965,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, break; case OD_SCLK: if (hwmgr->od_enabled) { - size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); for (i = 0; i < odn_sclk_table->num_of_pl; i++) size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n", i, odn_sclk_table->entries[i].clock/100, @@ -4972,7 +4974,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, break; case OD_MCLK: if (hwmgr->od_enabled) { - size = sysfs_emit(buf, "%s:\n", "OD_MCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); for (i = 0; i < odn_mclk_table->num_of_pl; i++) size += sysfs_emit_at(buf, size, "%d: %10uMHz %10umV\n", i, odn_mclk_table->entries[i].clock/100, @@ -4981,7 +4983,7 @@ static int smu7_print_clock_levels(struct pp_hwmgr *hwmgr, break; case OD_RANGE: if (hwmgr->od_enabled) { - size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", data->golden_dpm_table.sclk_table.dpm_levels[0].value/100, hwmgr->platform_descriptor.overdriveLimit.engineClock/100); @@ -5518,6 +5520,8 @@ static int smu7_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) if (!buf) return -EINVAL;
+ phm_get_sysfs_buf(&buf, &size); + size += sysfs_emit_at(buf, size, "%s %16s %16s %16s %16s %16s %16s %16s\n", title[0], title[1], title[2], title[3], title[4], title[5], title[6], title[7]); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c index b94a77e4e7147..8e28a8eecefc6 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c @@ -1550,6 +1550,8 @@ static int smu8_print_clock_levels(struct pp_hwmgr *hwmgr, uint32_t i, now; int size = 0;
+ phm_get_sysfs_buf(&buf, &size); + switch (type) { case PP_SCLK: now = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h index ad33983a8064e..2a75da1e9f035 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.h @@ -109,6 +109,19 @@ int phm_irq_process(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry);
+/* + * Helper function to make sysfs_emit_at() happy. Align buf to + * the current page boundary and record the offset. + */ +static inline void phm_get_sysfs_buf(char **buf, int *offset) +{ + if (!*buf || !offset) + return; + + *offset = offset_in_page(*buf); + *buf -= *offset; +} + int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr);
void *smu_atom_get_data_table(void *dev, uint32_t table, uint16_t *size, diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index c152a61ddd2c9..c981fc2882f01 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -4548,6 +4548,8 @@ static int vega10_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) int ret = 0; int size = 0;
+ phm_get_sysfs_buf(&buf, &size); + ret = vega10_get_enabled_smc_features(hwmgr, &features_enabled); PP_ASSERT_WITH_CODE(!ret, "[EnableAllSmuFeatures] Failed to get enabled smc features!", @@ -4637,6 +4639,8 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
int i, now, size = 0, count = 0;
+ phm_get_sysfs_buf(&buf, &size); + switch (type) { case PP_SCLK: if (data->registry_data.sclk_dpm_key_disabled) @@ -4717,7 +4721,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
case OD_SCLK: if (hwmgr->od_enabled) { - size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk; for (i = 0; i < podn_vdd_dep->count; i++) size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n", @@ -4727,7 +4731,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, break; case OD_MCLK: if (hwmgr->od_enabled) { - size = sysfs_emit(buf, "%s:\n", "OD_MCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk; for (i = 0; i < podn_vdd_dep->count; i++) size += sysfs_emit_at(buf, size, "%d: %10uMhz %10umV\n", @@ -4737,7 +4741,7 @@ static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr, break; case OD_RANGE: if (hwmgr->od_enabled) { - size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE"); size += sysfs_emit_at(buf, size, "SCLK: %7uMHz %10uMHz\n", data->golden_dpm_table.gfx_table.dpm_levels[0].value/100, hwmgr->platform_descriptor.overdriveLimit.engineClock/100); @@ -5112,6 +5116,8 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) if (!buf) return -EINVAL;
+ phm_get_sysfs_buf(&buf, &size); + size += sysfs_emit_at(buf, size, "%s %16s %s %s %s %s\n",title[0], title[1], title[2], title[3], title[4], title[5]);
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c index 8558718e15a8f..f7e783e1c888f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c @@ -2141,6 +2141,8 @@ static int vega12_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) int ret = 0; int size = 0;
+ phm_get_sysfs_buf(&buf, &size); + ret = vega12_get_enabled_smc_features(hwmgr, &features_enabled); PP_ASSERT_WITH_CODE(!ret, "[EnableAllSmuFeatures] Failed to get enabled smc features!", @@ -2244,6 +2246,8 @@ static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr, int i, now, size = 0; struct pp_clock_levels_with_latency clocks;
+ phm_get_sysfs_buf(&buf, &size); + switch (type) { case PP_SCLK: PP_ASSERT_WITH_CODE( diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index 0cf39c1244b1c..03e63be4ee275 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -3238,6 +3238,8 @@ static int vega20_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf) int ret = 0; int size = 0;
+ phm_get_sysfs_buf(&buf, &size); + ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled); PP_ASSERT_WITH_CODE(!ret, "[EnableAllSmuFeatures] Failed to get enabled smc features!", @@ -3364,6 +3366,8 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, int ret = 0; uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
+ phm_get_sysfs_buf(&buf, &size); + switch (type) { case PP_SCLK: ret = vega20_get_current_clk_freq(hwmgr, PPCLK_GFXCLK, &now); @@ -3479,7 +3483,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, case OD_SCLK: if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id && od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) { - size = sysfs_emit(buf, "%s:\n", "OD_SCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK"); size += sysfs_emit_at(buf, size, "0: %10uMhz\n", od_table->GfxclkFmin); size += sysfs_emit_at(buf, size, "1: %10uMhz\n", @@ -3489,7 +3493,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr,
case OD_MCLK: if (od8_settings[OD8_SETTING_UCLK_FMAX].feature_id) { - size = sysfs_emit(buf, "%s:\n", "OD_MCLK"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK"); size += sysfs_emit_at(buf, size, "1: %10uMhz\n", od_table->UclkFmax); } @@ -3503,7 +3507,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, od8_settings[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id && od8_settings[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id && od8_settings[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id) { - size = sysfs_emit(buf, "%s:\n", "OD_VDDC_CURVE"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_VDDC_CURVE"); size += sysfs_emit_at(buf, size, "0: %10uMhz %10dmV\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1 / VOLTAGE_SCALE); @@ -3518,7 +3522,7 @@ static int vega20_print_clock_levels(struct pp_hwmgr *hwmgr, break;
case OD_RANGE: - size = sysfs_emit(buf, "%s:\n", "OD_RANGE"); + size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
if (od8_settings[OD8_SETTING_GFXCLK_FMIN].feature_id && od8_settings[OD8_SETTING_GFXCLK_FMAX].feature_id) { @@ -4003,6 +4007,8 @@ static int vega20_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) if (!buf) return -EINVAL;
+ phm_get_sysfs_buf(&buf, &size); + size += sysfs_emit_at(buf, size, "%16s %s %s %s %s %s %s %s %s %s %s\n", title[0], title[1], title[2], title[3], title[4], title[5], title[6], title[7], title[8], title[9], title[10]);
From: Vincent Mailhol mailhol.vincent@wanadoo.fr
[ Upstream commit d9447f768bc8c60623e4bb3ce65b8f4654d33a50 ]
In es58x_rx_err_msg(), if can->do_set_mode() fails, the function directly returns without calling netif_rx(skb). This means that the skb previously allocated by alloc_can_err_skb() is not freed. In other terms, this is a memory leak.
This patch simply removes the return statement in the error branch and let the function continue.
Issue was found with GCC -fanalyzer, please follow the link below for details.
Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces") Link: https://lore.kernel.org/all/20211026180740.1953265-1-mailhol.vincent@wanadoo... Signed-off-by: Vincent Mailhol mailhol.vincent@wanadoo.fr Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/usb/etas_es58x/es58x_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 96a13c770e4a1..24627ab146261 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -664,7 +664,7 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error, struct can_device_stats *can_stats = &can->can_stats; struct can_frame *cf = NULL; struct sk_buff *skb; - int ret; + int ret = 0;
if (!netif_running(netdev)) { if (net_ratelimit()) @@ -823,8 +823,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error, can->state = CAN_STATE_BUS_OFF; can_bus_off(netdev); ret = can->do_set_mode(netdev, CAN_MODE_STOP); - if (ret) - return ret; } break;
@@ -881,7 +879,7 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error, ES58X_EVENT_BUSOFF, timestamp); }
- return 0; + return ret; }
/**
From: Marc Kleine-Budde mkl@pengutronix.de
[ Upstream commit 69c55f6e7669d46bb40e41f6e2b218428178368a ]
This patch fixes the error handling for mcp251xfd_chip_rx_int_enable(). Instead just returning the error, properly shut down the chip.
Link: https://lore.kernel.org/all/20211106201526.44292-2-mkl@pengutronix.de Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 212fcd1554e4f..e16dc482f3270 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1092,7 +1092,7 @@ static int mcp251xfd_chip_start(struct mcp251xfd_priv *priv)
err = mcp251xfd_chip_rx_int_enable(priv); if (err) - return err; + goto out_chip_stop;
err = mcp251xfd_chip_ecc_init(priv); if (err)
From: Miaohe Lin linmiaohe@huawei.com
[ Upstream commit afe8605ca45424629fdddfd85984b442c763dc47 ]
There is one possible race window between zs_pool_dec_isolated() and zs_unregister_migration() because wait_for_isolated_drain() checks the isolated count without holding class->lock and there is no order inside zs_pool_dec_isolated(). Thus the below race window could be possible:
zs_pool_dec_isolated zs_unregister_migration check pool->destroying != 0 pool->destroying = true; smp_mb(); wait_for_isolated_drain() wait for pool->isolated_pages == 0 atomic_long_dec(&pool->isolated_pages); atomic_long_read(&pool->isolated_pages) == 0
Since we observe the pool->destroying (false) before atomic_long_dec() for pool->isolated_pages, waking pool->migration_wait up is missed.
Fix this by ensure checking pool->destroying happens after the atomic_long_dec(&pool->isolated_pages).
Link: https://lkml.kernel.org/r/20210708115027.7557-1-linmiaohe@huawei.com Fixes: 701d678599d0 ("mm/zsmalloc.c: fix race condition in zs_destroy_pool") Signed-off-by: Miaohe Lin linmiaohe@huawei.com Cc: Minchan Kim minchan@kernel.org Cc: Sergey Senozhatsky senozhatsky@chromium.org Cc: Henry Burns henryburns@google.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/zsmalloc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 68e8831068f4b..b897ce3b399a1 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -1830,10 +1830,11 @@ static inline void zs_pool_dec_isolated(struct zs_pool *pool) VM_BUG_ON(atomic_long_read(&pool->isolated_pages) <= 0); atomic_long_dec(&pool->isolated_pages); /* - * There's no possibility of racing, since wait_for_isolated_drain() - * checks the isolated count under &class->lock after enqueuing - * on migration_wait. + * Checking pool->destroying must happen after atomic_long_dec() + * for pool->isolated_pages above. Paired with the smp_mb() in + * zs_unregister_migration(). */ + smp_mb__after_atomic(); if (atomic_long_read(&pool->isolated_pages) == 0 && pool->destroying) wake_up_all(&pool->migration_wait); }
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit a88e03cf3d190cf46bc4063a9b7efe87590de5f4 ]
snprintf() returns the number of bytes it would have printed if there were space. But it does not count the NUL terminator. So that means that if "count == copied" then this has already overflowed by one character.
This bug likely isn't super harmful in real life.
Link: https://lkml.kernel.org/r/20210916130404.GA25094@kili Fixes: c0265342bff4 ("zram: introduce zram memory tracking") Signed-off-by: Dan Carpenter dan.carpenter@oracle.com Cc: Minchan Kim minchan@kernel.org Cc: Sergey Senozhatsky senozhatsky@chromium.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/zram/zram_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index fcaf2750f68f7..6383c81ac5b37 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -910,7 +910,7 @@ static ssize_t read_block_state(struct file *file, char __user *buf, zram_test_flag(zram, index, ZRAM_HUGE) ? 'h' : '.', zram_test_flag(zram, index, ZRAM_IDLE) ? 'i' : '.');
- if (count < copied) { + if (count <= copied) { zram_slot_unlock(zram, index); break; }
From: Ian Rogers irogers@google.com
[ Upstream commit 88c42f4d6cb249eb68524282f8d4cc32f9059984 ]
If btf__new() is called then there needs to be a corresponding btf__free().
Fixes: f8dfeae009effc0b ("perf bpf: Show more BPF program info in print_bpf_prog_info()") 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/20211106053733.3580931-2-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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 1a7112a87736a..a410b3968b3af 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -576,7 +576,7 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, synthesize_bpf_prog_name(name, KSYM_NAME_LEN, info, btf, 0); fprintf(fp, "# bpf_prog_info %u: %s addr 0x%llx size %u\n", info->id, name, prog_addrs[0], prog_lens[0]); - return; + goto out; }
fprintf(fp, "# bpf_prog_info %u:\n", info->id); @@ -586,4 +586,6 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info, fprintf(fp, "# \tsub_prog %u: %s addr 0x%llx size %u\n", i, name, prog_addrs[i], prog_lens[i]); } +out: + btf__free(btf); }
From: Eric Dumazet edumazet@google.com
[ Upstream commit 8ac9dfd58b138f7e82098a4e0a0d46858b12215b ]
Both ifindex and LLC_SK_DEV_HASH_ENTRIES are signed.
This means that (ifindex % LLC_SK_DEV_HASH_ENTRIES) is negative if @ifindex is negative.
We could simply make LLC_SK_DEV_HASH_ENTRIES unsigned.
In this patch I chose to use hash_32() to get more entropy from @ifindex, like llc_sk_laddr_hashfn().
UBSAN: array-index-out-of-bounds in ./include/net/llc.h:75:26 index -43 is out of range for type 'hlist_head [64]' CPU: 1 PID: 20999 Comm: syz-executor.3 Not tainted 5.15.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 ubsan_epilogue+0xb/0x5a lib/ubsan.c:151 __ubsan_handle_out_of_bounds.cold+0x62/0x6c lib/ubsan.c:291 llc_sk_dev_hash include/net/llc.h:75 [inline] llc_sap_add_socket+0x49c/0x520 net/llc/llc_conn.c:697 llc_ui_bind+0x680/0xd70 net/llc/af_llc.c:404 __sys_bind+0x1e9/0x250 net/socket.c:1693 __do_sys_bind net/socket.c:1704 [inline] __se_sys_bind net/socket.c:1702 [inline] __x64_sys_bind+0x6f/0xb0 net/socket.c:1702 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7fa503407ae9
Fixes: 6d2e3ea28446 ("llc: use a device based hash table to speed up multicast delivery") Signed-off-by: Eric Dumazet edumazet@google.com Reported-by: syzbot syzkaller@googlegroups.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/llc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/net/llc.h b/include/net/llc.h index df282d9b40170..9c10b121b49b0 100644 --- a/include/net/llc.h +++ b/include/net/llc.h @@ -72,7 +72,9 @@ struct llc_sap { static inline struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex) { - return &sap->sk_dev_hash[ifindex % LLC_SK_DEV_HASH_ENTRIES]; + u32 bucket = hash_32(ifindex, LLC_SK_DEV_HASH_BITS); + + return &sap->sk_dev_hash[bucket]; }
static inline
From: Chengfeng Ye cyeaa@connect.ust.hk
[ Upstream commit 9fec40f850658e00a14a7dd9e06f7fbc7e59cc4a ]
skb is already freed by dev_kfree_skb in pn533_fill_fragment_skbs, but follow error handler branch when pn533_fill_fragment_skbs() fails, skb is freed again, results in double free issue. Fix this by not free skb in error path of pn533_fill_fragment_skbs.
Fixes: 963a82e07d4e ("NFC: pn533: Split large Tx frames in chunks") Fixes: 93ad42020c2d ("NFC: pn533: Target mode Tx fragmentation support") Signed-off-by: Chengfeng Ye cyeaa@connect.ust.hk Reviewed-by: Dan Carpenter dan.carpenter@oracle.com Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@canonical.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nfc/pn533/pn533.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 2f3f3fe9a0baa..d32aec0c334fe 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -2218,7 +2218,7 @@ static int pn533_fill_fragment_skbs(struct pn533 *dev, struct sk_buff *skb) frag = pn533_alloc_skb(dev, frag_size); if (!frag) { skb_queue_purge(&dev->fragment_skb); - break; + return -ENOMEM; }
if (!dev->tgt_mode) { @@ -2287,7 +2287,7 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, /* jumbo frame ? */ if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { rc = pn533_fill_fragment_skbs(dev, skb); - if (rc <= 0) + if (rc < 0) goto error;
skb = skb_dequeue(&dev->fragment_skb); @@ -2355,7 +2355,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) /* let's split in multiple chunks if size's too big */ if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { rc = pn533_fill_fragment_skbs(dev, skb); - if (rc <= 0) + if (rc < 0) goto error;
/* get the first skb */
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit c45231a7668d6b632534f692b10592ea375b55b0 ]
'netdev' is a managed resource allocated in the probe using 'devm_alloc_etherdev()'. It must not be freed explicitly in the remove function.
Fixes: ee7da21ac4c3 ("net: Add driver for LiteX's LiteETH network interface") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/litex/litex_liteeth.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/net/ethernet/litex/litex_liteeth.c b/drivers/net/ethernet/litex/litex_liteeth.c index a9bdbf0dcfe1e..5bb1cc8a2ce13 100644 --- a/drivers/net/ethernet/litex/litex_liteeth.c +++ b/drivers/net/ethernet/litex/litex_liteeth.c @@ -289,7 +289,6 @@ static int liteeth_remove(struct platform_device *pdev) struct net_device *netdev = platform_get_drvdata(pdev);
unregister_netdev(netdev); - free_netdev(netdev);
return 0; }
From: Reiji Watanabe reijiw@google.com
[ Upstream commit 9dc232a8ab18bb20f1dcb03c8e049e3607f3ed15 ]
The id argument of ARM64_FTR_REG_OVERRIDE() is used for two purposes: one as the system register encoding (used for the sys_id field of __ftr_reg_entry), and the other as the register name (stringified and used for the name field of arm64_ftr_reg), which is debug information. The id argument is supposed to be a macro that indicates an encoding of the register (eg. SYS_ID_AA64PFR0_EL1, etc).
ARM64_FTR_REG(), which also has the same id argument, uses ARM64_FTR_REG_OVERRIDE() and passes the id to the macro. Since the id argument is completely macro-expanded before it is substituted into a macro body of ARM64_FTR_REG_OVERRIDE(), the stringified id in the body of ARM64_FTR_REG_OVERRIDE is not a human-readable register name, but a string of numeric bitwise operations.
Fix this so that human-readable register names are available as debug information.
Fixes: 8f266a5d878a ("arm64: cpufeature: Add global feature override facility") Signed-off-by: Reiji Watanabe reijiw@google.com Reviewed-by: Oliver Upton oupton@google.com Acked-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211101045421.2215822-1-reijiw@google.com Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/kernel/cpufeature.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 6ec7036ef7e18..7553c98f379fc 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -573,15 +573,19 @@ static const struct arm64_ftr_bits ftr_raz[] = { ARM64_FTR_END, };
-#define ARM64_FTR_REG_OVERRIDE(id, table, ovr) { \ +#define __ARM64_FTR_REG_OVERRIDE(id_str, id, table, ovr) { \ .sys_id = id, \ .reg = &(struct arm64_ftr_reg){ \ - .name = #id, \ + .name = id_str, \ .override = (ovr), \ .ftr_bits = &((table)[0]), \ }}
-#define ARM64_FTR_REG(id, table) ARM64_FTR_REG_OVERRIDE(id, table, &no_override) +#define ARM64_FTR_REG_OVERRIDE(id, table, ovr) \ + __ARM64_FTR_REG_OVERRIDE(#id, id, table, ovr) + +#define ARM64_FTR_REG(id, table) \ + __ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override; struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit c7c386fbc20262c1d911c615c65db6a58667d92c ]
gcc warns about undefined behavior the vmalloc code when building with CONFIG_ARM64_PA_BITS_52, when the 'idx++' in the argument to __phys_to_pte_val() is evaluated twice:
mm/vmalloc.c: In function 'vmap_pfn_apply': mm/vmalloc.c:2800:58: error: operation on 'data->idx' may be undefined [-Werror=sequence-point] 2800 | *pte = pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot)); | ~~~~~~~~~^~ arch/arm64/include/asm/pgtable-types.h:25:37: note: in definition of macro '__pte' 25 | #define __pte(x) ((pte_t) { (x) } ) | ^ arch/arm64/include/asm/pgtable.h:80:15: note: in expansion of macro '__phys_to_pte_val' 80 | __pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) | ^~~~~~~~~~~~~~~~~ mm/vmalloc.c:2800:30: note: in expansion of macro 'pfn_pte' 2800 | *pte = pte_mkspecial(pfn_pte(data->pfns[data->idx++], data->prot)); | ^~~~~~~
I have no idea why this never showed up earlier, but the safest workaround appears to be changing those macros into inline functions so the arguments get evaluated only once.
Cc: Matthew Wilcox willy@infradead.org Fixes: 75387b92635e ("arm64: handle 52-bit physical addresses in page table entries") Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20211105075414.2553155-1-arnd@kernel.org Signed-off-by: Will Deacon will@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/include/asm/pgtable.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index dfa76afa0ccff..72f95c6a70519 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -67,9 +67,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; * page table entry, taking care of 52-bit addresses. */ #ifdef CONFIG_ARM64_PA_BITS_52 -#define __pte_to_phys(pte) \ - ((pte_val(pte) & PTE_ADDR_LOW) | ((pte_val(pte) & PTE_ADDR_HIGH) << 36)) -#define __phys_to_pte_val(phys) (((phys) | ((phys) >> 36)) & PTE_ADDR_MASK) +static inline phys_addr_t __pte_to_phys(pte_t pte) +{ + return (pte_val(pte) & PTE_ADDR_LOW) | + ((pte_val(pte) & PTE_ADDR_HIGH) << 36); +} +static inline pteval_t __phys_to_pte_val(phys_addr_t phys) +{ + return (phys | (phys >> 36)) & PTE_ADDR_MASK; +} #else #define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK) #define __phys_to_pte_val(phys) (phys)
From: John Fastabend john.fastabend@gmail.com
[ Upstream commit b8b8315e39ffaca82e79d86dde26e9144addf66b ]
We do not need to handle unhash from BPF side we can simply wait for the close to happen. The original concern was a socket could transition from ESTABLISHED state to a new state while the BPF hook was still attached. But, we convinced ourself this is no longer possible and we also improved BPF sockmap to handle listen sockets so this is no longer a problem.
More importantly though there are cases where unhash is called when data is in the receive queue. The BPF unhash logic will flush this data which is wrong. To be correct it should keep the data in the receive queue and allow a receiving application to continue reading the data. This may happen when tcp_abort() is received for example. Instead of complicating the logic in unhash simply moving all this to tcp_close() hook solves this.
Fixes: 51199405f9672 ("bpf: skb_verdict, support SK_PASS on RX BPF path") Signed-off-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Tested-by: Jussi Maki joamaki@gmail.com Reviewed-by: Jakub Sitnicki jakub@cloudflare.com Link: https://lore.kernel.org/bpf/20211103204736.248403-3-john.fastabend@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_bpf.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index 5f4d6f45d87f7..246f725b78c9b 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -475,7 +475,6 @@ static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS], struct proto *base) { prot[TCP_BPF_BASE] = *base; - prot[TCP_BPF_BASE].unhash = sock_map_unhash; prot[TCP_BPF_BASE].close = sock_map_close; prot[TCP_BPF_BASE].recvmsg = tcp_bpf_recvmsg; prot[TCP_BPF_BASE].sock_is_readable = sk_msg_is_readable;
From: John Fastabend john.fastabend@gmail.com
[ Upstream commit c5d2177a72a1659554922728fc407f59950aa929 ]
A socket in a sockmap may have different combinations of programs attached depending on configuration. There can be no programs in which case the socket acts as a sink only. There can be a TX program in this case a BPF program is attached to sending side, but no RX program is attached. There can be an RX program only where sends have no BPF program attached, but receives are hooked with BPF. And finally, both TX and RX programs may be attached. Giving us the permutations:
None, Tx, Rx, and TxRx
To date most of our use cases have been TX case being used as a fast datapath to directly copy between local application and a userspace proxy. Or Rx cases and TxRX applications that are operating an in kernel based proxy. The traffic in the first case where we hook applications into a userspace application looks like this:
AppA redirect AppB Tx <-----------> Rx | | + + TCP <--> lo <--> TCP
In this case all traffic from AppA (after 3whs) is copied into the AppB ingress queue and no traffic is ever on the TCP recieive_queue.
In the second case the application never receives, except in some rare error cases, traffic on the actual user space socket. Instead the send happens in the kernel.
AppProxy socket pool sk0 ------------->{sk1,sk2, skn} ^ | | | | v ingress lb egress TCP TCP
Here because traffic is never read off the socket with userspace recv() APIs there is only ever one reader on the sk receive_queue. Namely the BPF programs.
However, we've started to introduce a third configuration where the BPF program on receive should process the data, but then the normal case is to push the data into the receive queue of AppB.
AppB recv() (userspace) ----------------------- tcp_bpf_recvmsg() (kernel) | | | | | | ingress_msgQ | | | RX_BPF | | | v v sk->receive_queue
This is different from the App{A,B} redirect because traffic is first received on the sk->receive_queue.
Now for the issue. The tcp_bpf_recvmsg() handler first checks the ingress_msg queue for any data handled by the BPF rx program and returned with PASS code so that it was enqueued on the ingress msg queue. Then if no data exists on that queue it checks the socket receive queue. Unfortunately, this is the same receive_queue the BPF program is reading data off of. So we get a race. Its possible for the recvmsg() hook to pull data off the receive_queue before the BPF hook has a chance to read it. It typically happens when an application is banging on recv() and getting EAGAINs. Until they manage to race with the RX BPF program.
To fix this we note that before this patch at attach time when the socket is loaded into the map we check if it needs a TX program or just the base set of proto bpf hooks. Then it uses the above general RX hook regardless of if we have a BPF program attached at rx or not. This patch now extends this check to handle all cases enumerated above, TX, RX, TXRX, and none. And to fix above race when an RX program is attached we use a new hook that is nearly identical to the old one except now we do not let the recv() call skip the RX BPF program. Now only the BPF program pulls data from sk->receive_queue and recv() only pulls data from the ingress msgQ post BPF program handling.
With this resolved our AppB from above has been up and running for many hours without detecting any errors. We do this by correlating counters in RX BPF events and the AppB to ensure data is never skipping the BPF program. Selftests, was not able to detect this because we only run them for a short period of time on well ordered send/recvs so we don't get any of the noise we see in real application environments.
Fixes: 51199405f9672 ("bpf: skb_verdict, support SK_PASS on RX BPF path") Signed-off-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Tested-by: Jussi Maki joamaki@gmail.com Reviewed-by: Jakub Sitnicki jakub@cloudflare.com Link: https://lore.kernel.org/bpf/20211103204736.248403-4-john.fastabend@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/ipv4/tcp_bpf.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index 246f725b78c9b..f70aa0932bd6c 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -172,6 +172,41 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock, return ret; }
+static int tcp_bpf_recvmsg_parser(struct sock *sk, + struct msghdr *msg, + size_t len, + int nonblock, + int flags, + int *addr_len) +{ + struct sk_psock *psock; + int copied; + + if (unlikely(flags & MSG_ERRQUEUE)) + return inet_recv_error(sk, msg, len, addr_len); + + psock = sk_psock_get(sk); + if (unlikely(!psock)) + return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len); + + lock_sock(sk); +msg_bytes_ready: + copied = sk_msg_recvmsg(sk, psock, msg, len, flags); + if (!copied) { + long timeo; + int data; + + timeo = sock_rcvtimeo(sk, nonblock); + data = tcp_msg_wait_data(sk, psock, timeo); + if (data && !sk_psock_queue_empty(psock)) + goto msg_bytes_ready; + copied = -EAGAIN; + } + release_sock(sk); + sk_psock_put(sk, psock); + return copied; +} + static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, int flags, int *addr_len) { @@ -464,6 +499,8 @@ enum { enum { TCP_BPF_BASE, TCP_BPF_TX, + TCP_BPF_RX, + TCP_BPF_TXRX, TCP_BPF_NUM_CFGS, };
@@ -482,6 +519,12 @@ static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS], prot[TCP_BPF_TX] = prot[TCP_BPF_BASE]; prot[TCP_BPF_TX].sendmsg = tcp_bpf_sendmsg; prot[TCP_BPF_TX].sendpage = tcp_bpf_sendpage; + + prot[TCP_BPF_RX] = prot[TCP_BPF_BASE]; + prot[TCP_BPF_RX].recvmsg = tcp_bpf_recvmsg_parser; + + prot[TCP_BPF_TXRX] = prot[TCP_BPF_TX]; + prot[TCP_BPF_TXRX].recvmsg = tcp_bpf_recvmsg_parser; }
static void tcp_bpf_check_v6_needs_rebuild(struct proto *ops) @@ -519,6 +562,10 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) int family = sk->sk_family == AF_INET6 ? TCP_BPF_IPV6 : TCP_BPF_IPV4; int config = psock->progs.msg_parser ? TCP_BPF_TX : TCP_BPF_BASE;
+ if (psock->progs.stream_verdict || psock->progs.skb_verdict) { + config = (config == TCP_BPF_TX) ? TCP_BPF_TXRX : TCP_BPF_RX; + } + if (restore) { if (inet_csk_has_ulp(sk)) { /* TLS does not have an unhash proto in SW cases,
From: John Fastabend john.fastabend@gmail.com
[ Upstream commit e0dc3b93bd7bcff8c3813d1df43e0908499c7cf0 ]
Strparser is reusing the qdisc_skb_cb struct to stash the skb message handling progress, e.g. offset and length of the skb. First this is poorly named and inherits a struct from qdisc that doesn't reflect the actual usage of cb[] at this layer.
But, more importantly strparser is using the following to access its metadata.
(struct _strp_msg *)((void *)skb->cb + offsetof(struct qdisc_skb_cb, data))
Where _strp_msg is defined as:
struct _strp_msg { struct strp_msg strp; /* 0 8 */ int accum_len; /* 8 4 */
/* size: 12, cachelines: 1, members: 2 */ /* last cacheline: 12 bytes */ };
So we use 12 bytes of ->data[] in struct. However in BPF code running parser and verdict the user has read capabilities into the data[] array as well. Its not too problematic, but we should not be exposing internal state to BPF program. If its really needed then we can use the probe_read() APIs which allow reading kernel memory. And I don't believe cb[] layer poses any API breakage by moving this around because programs can't depend on cb[] across layers.
In order to fix another issue with a ctx rewrite we need to stash a temp variable somewhere. To make this work cleanly this patch builds a cb struct for sk_skb types called sk_skb_cb struct. Then we can use this consistently in the strparser, sockmap space. Additionally we can start allowing ->cb[] write access after this.
Fixes: 604326b41a6fb ("bpf, sockmap: convert to generic sk_msg interface") Signed-off-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Tested-by: Jussi Maki joamaki@gmail.com Reviewed-by: Jakub Sitnicki jakub@cloudflare.com Link: https://lore.kernel.org/bpf/20211103204736.248403-5-john.fastabend@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/strparser.h | 16 +++++++++++++++- net/core/filter.c | 22 ++++++++++++++++++++++ net/strparser/strparser.c | 10 +--------- 3 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/include/net/strparser.h b/include/net/strparser.h index 1d20b98493a10..bec1439bd3be6 100644 --- a/include/net/strparser.h +++ b/include/net/strparser.h @@ -54,10 +54,24 @@ struct strp_msg { int offset; };
+struct _strp_msg { + /* Internal cb structure. struct strp_msg must be first for passing + * to upper layer. + */ + struct strp_msg strp; + int accum_len; +}; + +struct sk_skb_cb { +#define SK_SKB_CB_PRIV_LEN 20 + unsigned char data[SK_SKB_CB_PRIV_LEN]; + struct _strp_msg strp; +}; + static inline struct strp_msg *strp_msg(struct sk_buff *skb) { return (struct strp_msg *)((void *)skb->cb + - offsetof(struct qdisc_skb_cb, data)); + offsetof(struct sk_skb_cb, strp)); }
/* Structure for an attached lower socket */ diff --git a/net/core/filter.c b/net/core/filter.c index 2e32cee2c4690..23a9bf92b5bb9 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9761,11 +9761,33 @@ static u32 sk_skb_convert_ctx_access(enum bpf_access_type type, struct bpf_prog *prog, u32 *target_size) { struct bpf_insn *insn = insn_buf; + int off;
switch (si->off) { case offsetof(struct __sk_buff, data_end): insn = bpf_convert_data_end_access(si, insn); break; + case offsetof(struct __sk_buff, cb[0]) ... + offsetofend(struct __sk_buff, cb[4]) - 1: + BUILD_BUG_ON(sizeof_field(struct sk_skb_cb, data) < 20); + BUILD_BUG_ON((offsetof(struct sk_buff, cb) + + offsetof(struct sk_skb_cb, data)) % + sizeof(__u64)); + + prog->cb_access = 1; + off = si->off; + off -= offsetof(struct __sk_buff, cb[0]); + off += offsetof(struct sk_buff, cb); + off += offsetof(struct sk_skb_cb, data); + if (type == BPF_WRITE) + *insn++ = BPF_STX_MEM(BPF_SIZE(si->code), si->dst_reg, + si->src_reg, off); + else + *insn++ = BPF_LDX_MEM(BPF_SIZE(si->code), si->dst_reg, + si->src_reg, off); + break; + + default: return bpf_convert_ctx_access(type, si, insn_buf, prog, target_size); diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index 9c0343568d2a0..1a72c67afed5e 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c @@ -27,18 +27,10 @@
static struct workqueue_struct *strp_wq;
-struct _strp_msg { - /* Internal cb structure. struct strp_msg must be first for passing - * to upper layer. - */ - struct strp_msg strp; - int accum_len; -}; - static inline struct _strp_msg *_strp_msg(struct sk_buff *skb) { return (struct _strp_msg *)((void *)skb->cb + - offsetof(struct qdisc_skb_cb, data)); + offsetof(struct sk_skb_cb, strp)); }
/* Lower lock held */
From: Jussi Maki joamaki@gmail.com
[ Upstream commit b2c4618162ec615a15883a804cce7e27afecfa58 ]
The current conversion of skb->data_end reads like this:
; data_end = (void*)(long)skb->data_end; 559: (79) r1 = *(u64 *)(r2 +200) ; r1 = skb->data 560: (61) r11 = *(u32 *)(r2 +112) ; r11 = skb->len 561: (0f) r1 += r11 562: (61) r11 = *(u32 *)(r2 +116) 563: (1f) r1 -= r11
But similar to the case in 84f44df664e9 ("bpf: sock_ops sk access may stomp registers when dst_reg = src_reg"), the code will read an incorrect skb->len when src == dst. In this case we end up generating this xlated code:
; data_end = (void*)(long)skb->data_end; 559: (79) r1 = *(u64 *)(r1 +200) ; r1 = skb->data 560: (61) r11 = *(u32 *)(r1 +112) ; r11 = (skb->data)->len 561: (0f) r1 += r11 562: (61) r11 = *(u32 *)(r1 +116) 563: (1f) r1 -= r11
... where line 560 is the reading 4B of (skb->data + 112) instead of the intended skb->len Here the skb pointer in r1 gets set to skb->data and the later deref for skb->len ends up following skb->data instead of skb.
This fixes the issue similarly to the patch mentioned above by creating an additional temporary variable and using to store the register when dst_reg = src_reg. We name the variable bpf_temp_reg and place it in the cb context for sk_skb. Then we restore from the temp to ensure nothing is lost.
Fixes: 16137b09a66f2 ("bpf: Compute data_end dynamically with JIT code") Signed-off-by: Jussi Maki joamaki@gmail.com Signed-off-by: John Fastabend john.fastabend@gmail.com Signed-off-by: Daniel Borkmann daniel@iogearbox.net Reviewed-by: Jakub Sitnicki jakub@cloudflare.com Link: https://lore.kernel.org/bpf/20211103204736.248403-6-john.fastabend@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/strparser.h | 4 ++++ net/core/filter.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/include/net/strparser.h b/include/net/strparser.h index bec1439bd3be6..732b7097d78e4 100644 --- a/include/net/strparser.h +++ b/include/net/strparser.h @@ -66,6 +66,10 @@ struct sk_skb_cb { #define SK_SKB_CB_PRIV_LEN 20 unsigned char data[SK_SKB_CB_PRIV_LEN]; struct _strp_msg strp; + /* temp_reg is a temporary register used for bpf_convert_data_end_access + * when dst_reg == src_reg. + */ + u64 temp_reg; };
static inline struct strp_msg *strp_msg(struct sk_buff *skb) diff --git a/net/core/filter.c b/net/core/filter.c index 23a9bf92b5bb9..f4a63af45f008 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9735,22 +9735,46 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, static struct bpf_insn *bpf_convert_data_end_access(const struct bpf_insn *si, struct bpf_insn *insn) { - /* si->dst_reg = skb->data */ + int reg; + int temp_reg_off = offsetof(struct sk_buff, cb) + + offsetof(struct sk_skb_cb, temp_reg); + + if (si->src_reg == si->dst_reg) { + /* We need an extra register, choose and save a register. */ + reg = BPF_REG_9; + if (si->src_reg == reg || si->dst_reg == reg) + reg--; + if (si->src_reg == reg || si->dst_reg == reg) + reg--; + *insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg, temp_reg_off); + } else { + reg = si->dst_reg; + } + + /* reg = skb->data */ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data), - si->dst_reg, si->src_reg, + reg, si->src_reg, offsetof(struct sk_buff, data)); /* AX = skb->len */ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, len), BPF_REG_AX, si->src_reg, offsetof(struct sk_buff, len)); - /* si->dst_reg = skb->data + skb->len */ - *insn++ = BPF_ALU64_REG(BPF_ADD, si->dst_reg, BPF_REG_AX); + /* reg = skb->data + skb->len */ + *insn++ = BPF_ALU64_REG(BPF_ADD, reg, BPF_REG_AX); /* AX = skb->data_len */ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_buff, data_len), BPF_REG_AX, si->src_reg, offsetof(struct sk_buff, data_len)); - /* si->dst_reg = skb->data + skb->len - skb->data_len */ - *insn++ = BPF_ALU64_REG(BPF_SUB, si->dst_reg, BPF_REG_AX); + + /* reg = skb->data + skb->len - skb->data_len */ + *insn++ = BPF_ALU64_REG(BPF_SUB, reg, BPF_REG_AX); + + if (si->src_reg == si->dst_reg) { + /* Restore the saved register */ + *insn++ = BPF_MOV64_REG(BPF_REG_AX, si->src_reg); + *insn++ = BPF_MOV64_REG(si->dst_reg, reg); + *insn++ = BPF_LDX_MEM(BPF_DW, reg, BPF_REG_AX, temp_reg_off); + }
return insn; }
From: Amelie Delaunay amelie.delaunay@foss.st.com
[ Upstream commit af229d2c2557b5cf2a3b1eb39847ec1de7446873 ]
Theorically, address pointers used by STM32 DMA must be chosen so as to ensure that all transfers within a burst block are aligned on the address boundary equal to the size of the transfer. If this is always the case for peripheral addresses on STM32, it is not for memory addresses if the user doesn't respect this alignment constraint. To avoid a weird behavior of the DMA controller in this case (no error triggered but data are not transferred as expected), force no burst.
Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20211011094259.315023-4-amelie.delaunay@foss.st.co... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/stm32-dma.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index fdda916555ec5..c276a39aa7930 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -752,8 +752,14 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, if (src_bus_width < 0) return src_bus_width;
- /* Set memory burst size */ - src_maxburst = STM32_DMA_MAX_BURST; + /* + * Set memory burst size - burst not possible if address is not aligned on + * the address boundary equal to the size of the transfer + */ + if (buf_addr % buf_len) + src_maxburst = 1; + else + src_maxburst = STM32_DMA_MAX_BURST; src_best_burst = stm32_dma_get_best_burst(buf_len, src_maxburst, fifoth, @@ -802,8 +808,14 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, if (dst_bus_width < 0) return dst_bus_width;
- /* Set memory burst size */ - dst_maxburst = STM32_DMA_MAX_BURST; + /* + * Set memory burst size - burst not possible if address is not aligned on + * the address boundary equal to the size of the transfer + */ + if (buf_addr % buf_len) + dst_maxburst = 1; + else + dst_maxburst = STM32_DMA_MAX_BURST; dst_best_burst = stm32_dma_get_best_burst(buf_len, dst_maxburst, fifoth,
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit 2498363310e9b5e5de0e104709adc35c9f3ff7d9 ]
Using the % operator on a 64-bit variable is expensive and can cause a link failure:
arm-linux-gnueabi-ld: drivers/dma/stm32-dma.o: in function `stm32_dma_get_max_width': stm32-dma.c:(.text+0x170): undefined reference to `__aeabi_uldivmod' arm-linux-gnueabi-ld: drivers/dma/stm32-dma.o: in function `stm32_dma_set_xfer_param': stm32-dma.c:(.text+0x1cd4): undefined reference to `__aeabi_uldivmod'
As we know that we just want to check the alignment in stm32_dma_get_max_width(), there is no need for a full division, and using a simple mask is a faster replacement.
Same in stm32_dma_set_xfer_param(), change this to only allow burst transfers if the address is a multiple of the length. stm32_dma_get_best_burst just after will take buf_len into account to fix burst in case of misalignment.
Fixes: b20fd5fa310c ("dmaengine: stm32-dma: fix stm32_dma_get_max_width") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Amelie Delaunay amelie.delaunay@foss.st.com Link: https://lore.kernel.org/r/20211103153312.41483-1-amelie.delaunay@foss.st.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/stm32-dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index c276a39aa7930..7dfc743ac4338 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -280,7 +280,7 @@ static enum dma_slave_buswidth stm32_dma_get_max_width(u32 buf_len, max_width > DMA_SLAVE_BUSWIDTH_1_BYTE) max_width = max_width >> 1;
- if (buf_addr % max_width) + if (buf_addr & (max_width - 1)) max_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
return max_width; @@ -756,7 +756,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, * Set memory burst size - burst not possible if address is not aligned on * the address boundary equal to the size of the transfer */ - if (buf_addr % buf_len) + if (buf_addr & (buf_len - 1)) src_maxburst = 1; else src_maxburst = STM32_DMA_MAX_BURST; @@ -812,7 +812,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, * Set memory burst size - burst not possible if address is not aligned on * the address boundary equal to the size of the transfer */ - if (buf_addr % buf_len) + if (buf_addr & (buf_len - 1)) dst_maxburst = 1; else dst_maxburst = STM32_DMA_MAX_BURST;
From: Dan Carpenter dan.carpenter@oracle.com
[ Upstream commit 1c360cc1cc883fbdf0a258b4df376571fbeac5ee ]
The priv->ntfy_blocks[] has "priv->num_ntfy_blks" elements so this > needs to be >= to prevent an off by one bug. The priv->ntfy_blocks[] array is allocated in gve_alloc_notify_blocks().
Fixes: 87a7f321bb6a ("gve: Recover from queue stall due to missed IRQ") 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/net/ethernet/google/gve/gve_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 8c996e72748d2..959352fceead7 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -1132,7 +1132,7 @@ static void gve_tx_timeout(struct net_device *dev, unsigned int txqueue) goto reset;
ntfy_idx = gve_tx_idx_to_ntfy(priv, txqueue); - if (ntfy_idx > priv->num_ntfy_blks) + if (ntfy_idx >= priv->num_ntfy_blks) goto reset;
block = &priv->ntfy_blocks[ntfy_idx];
From: Imre Deak imre.deak@intel.com
[ Upstream commit 90ab96f3872eae816f4e07deaa77322a91237960 ]
For NV12 FBs with odd main surface tile-row height the CCS surface height was incorrectly calculated 1 less than the actual value. Fix this by rounding up the result of divison. For consistency do the same for the CCS surface width calculation.
Fixes: b3e57bccd68a ("drm/i915/tgl: Gen-12 render decompression") Signed-off-by: Imre Deak imre.deak@intel.com Reviewed-by: Juha-Pekka Heikkila juhapekka.heikkila@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20211026225105.2783797-2-imre.... (cherry picked from commit 2ee5ef9c934ad26376c9282171e731e6c0339815) Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/display/intel_fb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index c60a81a81c09c..c6413c5409420 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -172,8 +172,9 @@ static void intel_fb_plane_dims(const struct intel_framebuffer *fb, int color_pl
intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, &fb->base, main_plane); intel_fb_plane_get_subsampling(&hsub, &vsub, &fb->base, color_plane); - *w = fb->base.width / main_hsub / hsub; - *h = fb->base.height / main_vsub / vsub; + + *w = DIV_ROUND_UP(fb->base.width, main_hsub * hsub); + *h = DIV_ROUND_UP(fb->base.height, main_vsub * vsub); }
static u32 intel_adjust_tile_offset(int *x, int *y,
From: Andrew Halaney ahalaney@redhat.com
[ Upstream commit 8bc2b3dca7292347d8e715fb723c587134abe013 ]
The prior message is confusing users, which is the exact opposite of the goal. If the message is being seen, one of the following situations is happening:
1. the param is misspelled 2. the param is not valid due to the kernel configuration 3. the param is intended for init but isn't after the '--' delineator on the command line
To make that more clear to the user, explicitly mention "kernel command line" and also note that the params are still passed to user space to avoid causing any alarm over params intended for init.
Link: https://lkml.kernel.org/r/20211013223502.96756-1-ahalaney@redhat.com Fixes: 86d1919a4fb0 ("init: print out unknown kernel parameters") Signed-off-by: Andrew Halaney ahalaney@redhat.com Suggested-by: Steven Rostedt (VMware) rostedt@goodmis.org Acked-by: Randy Dunlap rdunlap@infradead.org Cc: Borislav Petkov bp@suse.de Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- init/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/init/main.c b/init/main.c index 3c4054a955458..bcd132d4e7bdd 100644 --- a/init/main.c +++ b/init/main.c @@ -924,7 +924,9 @@ static void __init print_unknown_bootoptions(void) for (p = &envp_init[2]; *p; p++) end += sprintf(end, " %s", *p);
- pr_notice("Unknown command line parameters:%s\n", unknown_options); + /* Start at unknown_options[1] to skip the initial space */ + pr_notice("Unknown kernel command line parameters "%s", will be passed to user space.\n", + &unknown_options[1]); memblock_free_ptr(unknown_options, len); }
From: Muchun Song songmuchun@bytedance.com
[ Upstream commit 10a6de19cad6efb9b49883513afb810dc265fca2 ]
DEFINE_PROC_SHOW_ATTRIBUTE() is supposed to be used to define a series of functions and variables to register proc file easily. And the users can use proc_create_data() to pass their own private data and get it via seq->private in the callback. Unfortunately, the proc file system use PDE_DATA() to get private data instead of inode->i_private. So fix it. Fortunately, there only one user of it which does not pass any private data, so this bug does not break any in-tree codes.
Link: https://lkml.kernel.org/r/20211029032638.84884-1-songmuchun@bytedance.com Fixes: 97a32539b956 ("proc: convert everything to "struct proc_ops"") Signed-off-by: Muchun Song songmuchun@bytedance.com Cc: Andy Shevchenko andriy.shevchenko@linux.intel.com Cc: Stephen Rothwell sfr@canb.auug.org.au Cc: Florent Revest revest@chromium.org Cc: Alexey Dobriyan adobriyan@gmail.com Cc: Christian Brauner christian.brauner@ubuntu.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/seq_file.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index dd99569595fd3..5733890df64f5 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -194,7 +194,7 @@ static const struct file_operations __name ## _fops = { \ #define DEFINE_PROC_SHOW_ATTRIBUTE(__name) \ static int __name ## _open(struct inode *inode, struct file *file) \ { \ - return single_open(file, __name ## _show, inode->i_private); \ + return single_open(file, __name ## _show, PDE_DATA(inode)); \ } \ \ static const struct proc_ops __name ## _proc_ops = { \
From: Evan Quan evan.quan@amd.com
[ Upstream commit 4fc30ea780e0a5c1c019bc2e44f8523e1eed9051 ]
There was a change(below) target for such issue: d82e2c249c8f ("drm/amdgpu: Fix crash on device remove/driver unload") But the fix for VI ASICs was missing there. This is a supplement for that.
Fixes: d82e2c249c8f ("drm/amdgpu: Fix crash on device remove/driver unload")
Signed-off-by: Evan Quan evan.quan@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index bc571833632ea..72f8762907681 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -543,6 +543,19 @@ static int uvd_v6_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ cancel_delayed_work_sync(&adev->uvd.idle_work); + + if (RREG32(mmUVD_STATUS) != 0) + uvd_v6_0_stop(adev); + + return 0; +} + +static int uvd_v6_0_suspend(void *handle) +{ + int r; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + /* * Proper cleanups before halting the HW engine: * - cancel the delayed idle work @@ -567,17 +580,6 @@ static int uvd_v6_0_hw_fini(void *handle) AMD_CG_STATE_GATE); }
- if (RREG32(mmUVD_STATUS) != 0) - uvd_v6_0_stop(adev); - - return 0; -} - -static int uvd_v6_0_suspend(void *handle) -{ - int r; - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v6_0_hw_fini(adev); if (r) return r;
From: Marek Behún kabel@kernel.org
[ Upstream commit dc2fc9f03c5c410d8f01c2206b3d529f80b13733 ]
Model 88E6191X only supports >1G speeds on port 10. Port 0 and 9 are only 1G.
Fixes: de776d0d316f ("net: dsa: mv88e6xxx: add support for mv88e6393x family") Signed-off-by: Marek Behún kabel@kernel.org Cc: Russell King (Oracle) rmk+kernel@armlinux.org.uk Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://lore.kernel.org/r/20211104171747.10509-1-kabel@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mv88e6xxx/chip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 8dadcae93c9b5..be8589fa86a15 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -640,7 +640,10 @@ static void mv88e6393x_phylink_validate(struct mv88e6xxx_chip *chip, int port, unsigned long *mask, struct phylink_link_state *state) { - if (port == 0 || port == 9 || port == 10) { + bool is_6191x = + chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X; + + if (((port == 0 || port == 9) && !is_6191x) || port == 10) { phylink_set(mask, 10000baseT_Full); phylink_set(mask, 10000baseKR_Full); phylink_set(mask, 10000baseCR_Full);
From: Eric Dumazet edumazet@google.com
[ Upstream commit 6dc25401cba4d428328eade8ceae717633fdd702 ]
1) if q->tk_offset == TK_OFFS_MAX, then get_tcp_tstamp() calls ktime_mono_to_any() with out-of-bound value.
2) if q->tk_offset is changed in taprio_parse_clockid(), taprio_get_time() might also call ktime_mono_to_any() with out-of-bound value as sysbot found:
UBSAN: array-index-out-of-bounds in kernel/time/timekeeping.c:908:27 index 3 is out of range for type 'ktime_t *[3]' CPU: 1 PID: 25668 Comm: kworker/u4:0 Not tainted 5.15.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: bat_events batadv_iv_send_outstanding_bat_ogm_packet Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 ubsan_epilogue+0xb/0x5a lib/ubsan.c:151 __ubsan_handle_out_of_bounds.cold+0x62/0x6c lib/ubsan.c:291 ktime_mono_to_any+0x1d4/0x1e0 kernel/time/timekeeping.c:908 get_tcp_tstamp net/sched/sch_taprio.c:322 [inline] get_packet_txtime net/sched/sch_taprio.c:353 [inline] taprio_enqueue_one+0x5b0/0x1460 net/sched/sch_taprio.c:420 taprio_enqueue+0x3b1/0x730 net/sched/sch_taprio.c:485 dev_qdisc_enqueue+0x40/0x300 net/core/dev.c:3785 __dev_xmit_skb net/core/dev.c:3869 [inline] __dev_queue_xmit+0x1f6e/0x3630 net/core/dev.c:4194 batadv_send_skb_packet+0x4a9/0x5f0 net/batman-adv/send.c:108 batadv_iv_ogm_send_to_if net/batman-adv/bat_iv_ogm.c:393 [inline] batadv_iv_ogm_emit net/batman-adv/bat_iv_ogm.c:421 [inline] batadv_iv_send_outstanding_bat_ogm_packet+0x6d7/0x8e0 net/batman-adv/bat_iv_ogm.c:1701 process_one_work+0x9b2/0x1690 kernel/workqueue.c:2298 worker_thread+0x658/0x11f0 kernel/workqueue.c:2445 kthread+0x405/0x4f0 kernel/kthread.c:327 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
Fixes: 7ede7b03484b ("taprio: make clock reference conversions easier") Fixes: 54002066100b ("taprio: Adjust timestamps for TCP packets") Signed-off-by: Eric Dumazet edumazet@google.com Cc: Vedang Patel vedang.patel@intel.com Reported-by: syzbot syzkaller@googlegroups.com Reviewed-by: Vinicius Costa Gomes vinicius.gomes@intel.com Link: https://lore.kernel.org/r/20211108180815.1822479-1-eric.dumazet@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_taprio.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index b9fd18d986464..a66398fb2d6d0 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -95,18 +95,22 @@ static ktime_t sched_base_time(const struct sched_gate_list *sched) return ns_to_ktime(sched->base_time); }
-static ktime_t taprio_get_time(struct taprio_sched *q) +static ktime_t taprio_mono_to_any(const struct taprio_sched *q, ktime_t mono) { - ktime_t mono = ktime_get(); + /* This pairs with WRITE_ONCE() in taprio_parse_clockid() */ + enum tk_offsets tk_offset = READ_ONCE(q->tk_offset);
- switch (q->tk_offset) { + switch (tk_offset) { case TK_OFFS_MAX: return mono; default: - return ktime_mono_to_any(mono, q->tk_offset); + return ktime_mono_to_any(mono, tk_offset); } +}
- return KTIME_MAX; +static ktime_t taprio_get_time(const struct taprio_sched *q) +{ + return taprio_mono_to_any(q, ktime_get()); }
static void taprio_free_sched_cb(struct rcu_head *head) @@ -319,7 +323,7 @@ static ktime_t get_tcp_tstamp(struct taprio_sched *q, struct sk_buff *skb) return 0; }
- return ktime_mono_to_any(skb->skb_mstamp_ns, q->tk_offset); + return taprio_mono_to_any(q, skb->skb_mstamp_ns); }
/* There are a few scenarios where we will have to modify the txtime from @@ -1352,6 +1356,7 @@ static int taprio_parse_clockid(struct Qdisc *sch, struct nlattr **tb, } } else if (tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID]) { int clockid = nla_get_s32(tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID]); + enum tk_offsets tk_offset;
/* We only support static clockids and we don't allow * for it to be modified after the first init. @@ -1366,22 +1371,24 @@ static int taprio_parse_clockid(struct Qdisc *sch, struct nlattr **tb,
switch (clockid) { case CLOCK_REALTIME: - q->tk_offset = TK_OFFS_REAL; + tk_offset = TK_OFFS_REAL; break; case CLOCK_MONOTONIC: - q->tk_offset = TK_OFFS_MAX; + tk_offset = TK_OFFS_MAX; break; case CLOCK_BOOTTIME: - q->tk_offset = TK_OFFS_BOOT; + tk_offset = TK_OFFS_BOOT; break; case CLOCK_TAI: - q->tk_offset = TK_OFFS_TAI; + tk_offset = TK_OFFS_TAI; break; default: NL_SET_ERR_MSG(extack, "Invalid 'clockid'"); err = -EINVAL; goto out; } + /* This pairs with READ_ONCE() in taprio_mono_to_any */ + WRITE_ONCE(q->tk_offset, tk_offset);
q->clockid = clockid; } else {
From: Jie Wang wangjie125@huawei.com
[ Upstream commit beb27ca451a57a1c0e52b5268703f3c3173c1f8c ]
Currently, NIC init ROCE interrupt vector with MSIX interrupt. But ROCE use pci_irq_vector() to get interrupt vector, which adds the relative interrupt vector again and gets wrong interrupt vector.
So fixes it by assign relative interrupt vector to ROCE instead of MSIX interrupt vector and delete the unused struct member base_msi_vector declaration of hclgevf_dev.
Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") Signed-off-by: Jie Wang wangjie125@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 6 +----- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 -- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 +---- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 2 -- 4 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index d891390d492f6..ffd85cd297ef3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2498,7 +2498,7 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport) if (hdev->num_msi < hdev->num_nic_msi + hdev->num_roce_msi) return -EINVAL;
- roce->rinfo.base_vector = hdev->roce_base_vector; + roce->rinfo.base_vector = hdev->num_nic_msi;
roce->rinfo.netdev = nic->kinfo.netdev; roce->rinfo.roce_io_base = hdev->hw.io_base; @@ -2534,10 +2534,6 @@ static int hclge_init_msi(struct hclge_dev *hdev) hdev->num_msi = vectors; hdev->num_msi_left = vectors;
- hdev->base_msi_vector = pdev->irq; - hdev->roce_base_vector = hdev->base_msi_vector + - hdev->num_nic_msi; - hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, sizeof(u16), GFP_KERNEL); if (!hdev->vector_status) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 69cd8f87b4c86..9111b8c84d786 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -876,12 +876,10 @@ struct hclge_dev { u16 num_msi; u16 num_msi_left; u16 num_msi_used; - u32 base_msi_vector; u16 *vector_status; int *vector_irq; u16 num_nic_msi; /* Num of nic vectors for this PF */ u16 num_roce_msi; /* Num of roce vectors for this PF */ - int roce_base_vector;
unsigned long service_timer_period; unsigned long service_timer_previous; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index cf00ad7bb881f..4cf34f1693544 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2557,7 +2557,7 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev) hdev->num_msi_left == 0) return -EINVAL;
- roce->rinfo.base_vector = hdev->roce_base_vector; + roce->rinfo.base_vector = hdev->roce_base_msix_offset;
roce->rinfo.netdev = nic->kinfo.netdev; roce->rinfo.roce_io_base = hdev->hw.io_base; @@ -2823,9 +2823,6 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) hdev->num_msi = vectors; hdev->num_msi_left = vectors;
- hdev->base_msi_vector = pdev->irq; - hdev->roce_base_vector = pdev->irq + hdev->roce_base_msix_offset; - hdev->vector_status = devm_kcalloc(&pdev->dev, hdev->num_msi, sizeof(u16), GFP_KERNEL); if (!hdev->vector_status) { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 28288d7e33032..4bd922b475012 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -308,8 +308,6 @@ struct hclgevf_dev { u16 num_nic_msix; /* Num of nic vectors for this VF */ u16 num_roce_msix; /* Num of roce vectors for this VF */ u16 roce_base_msix_offset; - int roce_base_vector; - u32 base_msi_vector; u16 *vector_status; int *vector_irq;
From: Jie Wang wangjie125@huawei.com
[ Upstream commit 0b653a81a26d66ffe526a54c2177e24fb1400301 ]
Currently, driver will send command to firmware to query pfc packet number when user uses dcb tool to get pfc parameters. However, the periodic service task will also periodically query and record MAC statistics, including pfc packet number.
As the hardware registers of statistics is cleared after reading, it will cause pfc packet number of MAC statistics are not correct after using dcb tool to get pfc parameters.
To fix this problem, when user uses dcb tool to get pfc parameters, driver updates MAC statistics firstly and then get pfc packet number from MAC statistics.
Fixes: 64fd2300fcc1 ("net: hns3: add support for querying pfc puase packets statistic") Signed-off-by: Jie Wang wangjie125@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../hisilicon/hns3/hns3pf/hclge_dcb.c | 18 ++--- .../hisilicon/hns3/hns3pf/hclge_main.c | 4 +- .../hisilicon/hns3/hns3pf/hclge_main.h | 4 ++ .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 68 +++++++++---------- .../ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 4 +- 5 files changed, 48 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index 91cb578f56b80..90013c131e949 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -286,28 +286,24 @@ err_out:
static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) { - u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC]; struct hclge_vport *vport = hclge_get_vport(h); struct hclge_dev *hdev = vport->back; int ret; - u8 i;
memset(pfc, 0, sizeof(*pfc)); pfc->pfc_cap = hdev->pfc_max; pfc->pfc_en = hdev->tm_info.pfc_en;
- ret = hclge_pfc_tx_stats_get(hdev, requests); - if (ret) + ret = hclge_mac_update_stats(hdev); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to update MAC stats, ret = %d.\n", ret); return ret; + }
- ret = hclge_pfc_rx_stats_get(hdev, indications); - if (ret) - return ret; + hclge_pfc_tx_stats_get(hdev, pfc->requests); + hclge_pfc_rx_stats_get(hdev, pfc->indications);
- for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { - pfc->requests[i] = requests[i]; - pfc->indications[i] = indications[i]; - } return 0; }
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index ffd85cd297ef3..66c407d0d507e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -26,8 +26,6 @@ #include "hclge_devlink.h"
#define HCLGE_NAME "hclge" -#define HCLGE_STATS_READ(p, offset) (*(u64 *)((u8 *)(p) + (offset))) -#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f))
#define HCLGE_BUF_SIZE_UNIT 256U #define HCLGE_BUF_MUL_BY 2 @@ -548,7 +546,7 @@ static int hclge_mac_query_reg_num(struct hclge_dev *hdev, u32 *desc_num) return 0; }
-static int hclge_mac_update_stats(struct hclge_dev *hdev) +int hclge_mac_update_stats(struct hclge_dev *hdev) { u32 desc_num; int ret; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 9111b8c84d786..2fa6e14c96e5b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -824,6 +824,9 @@ struct hclge_vf_vlan_cfg { (y) = (_k_ ^ ~_v_) & (_k_); \ } while (0)
+#define HCLGE_MAC_STATS_FIELD_OFF(f) (offsetof(struct hclge_mac_stats, f)) +#define HCLGE_STATS_READ(p, offset) (*(u64 *)((u8 *)(p) + (offset))) + #define HCLGE_MAC_TNL_LOG_SIZE 8 #define HCLGE_VPORT_NUM 256 struct hclge_dev { @@ -1136,4 +1139,5 @@ void hclge_inform_vf_promisc_info(struct hclge_vport *vport); int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len); int hclge_push_vf_link_status(struct hclge_vport *vport); int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en); +int hclge_mac_update_stats(struct hclge_dev *hdev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index 95074e91a8466..a50e2edbf4a0f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -113,50 +113,50 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, return 0; }
-static int hclge_pfc_stats_get(struct hclge_dev *hdev, - enum hclge_opcode_type opcode, u64 *stats) -{ - struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM]; - int ret, i, j; - - if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT || - opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT)) - return -EINVAL; - - for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1; i++) { - hclge_cmd_setup_basic_desc(&desc[i], opcode, true); - desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); - } - - hclge_cmd_setup_basic_desc(&desc[i], opcode, true); +static const u16 hclge_pfc_tx_stats_offset[] = { + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri0_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri1_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri2_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri3_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri4_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri5_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri6_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri7_pkt_num) +};
- ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM); - if (ret) - return ret; +static const u16 hclge_pfc_rx_stats_offset[] = { + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri0_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri1_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri2_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri3_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri4_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri5_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri6_pkt_num), + HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri7_pkt_num) +};
- for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) { - struct hclge_pfc_stats_cmd *pfc_stats = - (struct hclge_pfc_stats_cmd *)desc[i].data; +static void hclge_pfc_stats_get(struct hclge_dev *hdev, bool tx, u64 *stats) +{ + const u16 *offset; + int i;
- for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) { - u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j; + if (tx) + offset = hclge_pfc_tx_stats_offset; + else + offset = hclge_pfc_rx_stats_offset;
- if (index < HCLGE_MAX_TC_NUM) - stats[index] = - le64_to_cpu(pfc_stats->pkt_num[j]); - } - } - return 0; + for (i = 0; i < HCLGE_MAX_TC_NUM; i++) + stats[i] = HCLGE_STATS_READ(&hdev->mac_stats, offset[i]); }
-int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats) +void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats) { - return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats); + hclge_pfc_stats_get(hdev, false, stats); }
-int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats) +void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats) { - return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats); + hclge_pfc_stats_get(hdev, true, stats); }
int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h index 2ee9b795f71dc..1db7f40b45255 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -228,8 +228,8 @@ int hclge_tm_dwrr_cfg(struct hclge_dev *hdev); int hclge_tm_init_hw(struct hclge_dev *hdev, bool init); int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); -int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); -int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); +void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); +void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num); int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num);
From: Yufeng Mo moyufeng@huawei.com
[ Upstream commit e140c7983e3054be0652bf914f4454f16c5520b0 ]
When fully configure VLANs for a VF, then unload the VF while triggering a reset to PF, will cause a kernel crash because the irq is already uninit.
[ 293.177579] ------------[ cut here ]------------ [ 293.183502] kernel BUG at drivers/pci/msi.c:352! [ 293.189547] Internal error: Oops - BUG: 0 [#1] SMP ...... [ 293.390124] Workqueue: hclgevf hclgevf_service_task [hclgevf] [ 293.402627] pstate: 80c00009 (Nzcv daif +PAN +UAO) [ 293.414324] pc : free_msi_irqs+0x19c/0x1b8 [ 293.425429] lr : free_msi_irqs+0x18c/0x1b8 [ 293.436545] sp : ffff00002716fbb0 [ 293.446950] x29: ffff00002716fbb0 x28: 0000000000000000 [ 293.459519] x27: 0000000000000000 x26: ffff45b91ea16b00 [ 293.472183] x25: 0000000000000000 x24: ffffa587b08f4700 [ 293.484717] x23: ffffc591ac30e000 x22: ffffa587b08f8428 [ 293.497190] x21: ffffc591ac30e300 x20: 0000000000000000 [ 293.509594] x19: ffffa58a062a8300 x18: 0000000000000000 [ 293.521949] x17: 0000000000000000 x16: ffff45b91dcc3f48 [ 293.534013] x15: 0000000000000000 x14: 0000000000000000 [ 293.545883] x13: 0000000000000040 x12: 0000000000000228 [ 293.557508] x11: 0000000000000020 x10: 0000000000000040 [ 293.568889] x9 : ffff45b91ea1e190 x8 : ffffc591802d0000 [ 293.580123] x7 : ffffc591802d0148 x6 : 0000000000000120 [ 293.591190] x5 : ffffc591802d0000 x4 : 0000000000000000 [ 293.602015] x3 : 0000000000000000 x2 : 0000000000000000 [ 293.612624] x1 : 00000000000004a4 x0 : ffffa58a1e0c6b80 [ 293.623028] Call trace: [ 293.630340] free_msi_irqs+0x19c/0x1b8 [ 293.638849] pci_disable_msix+0x118/0x140 [ 293.647452] pci_free_irq_vectors+0x20/0x38 [ 293.656081] hclgevf_uninit_msi+0x44/0x58 [hclgevf] [ 293.665309] hclgevf_reset_rebuild+0x1ac/0x2e0 [hclgevf] [ 293.674866] hclgevf_reset+0x358/0x400 [hclgevf] [ 293.683545] hclgevf_reset_service_task+0xd0/0x1b0 [hclgevf] [ 293.693325] hclgevf_service_task+0x4c/0x2e8 [hclgevf] [ 293.702307] process_one_work+0x1b0/0x448 [ 293.710034] worker_thread+0x54/0x468 [ 293.717331] kthread+0x134/0x138 [ 293.724114] ret_from_fork+0x10/0x18 [ 293.731324] Code: f940b000 b4ffff00 a903e7b8 f90017b6 (d4210000)
This patch fixes the problem by waiting for the VF reset done while unloading the VF.
Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support") Signed-off-by: Yufeng Mo moyufeng@huawei.com Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 +++++ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h | 2 ++ 2 files changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 4cf34f1693544..3b8bde58613a8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -3010,7 +3010,10 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client,
/* un-init roce, if it exists */ if (hdev->roce_client) { + while (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) + msleep(HCLGEVF_WAIT_RESET_DONE); clear_bit(HCLGEVF_STATE_ROCE_REGISTERED, &hdev->state); + hdev->roce_client->ops->uninit_instance(&hdev->roce, 0); hdev->roce_client = NULL; hdev->roce.client = NULL; @@ -3019,6 +3022,8 @@ static void hclgevf_uninit_client_instance(struct hnae3_client *client, /* un-init nic/unic, if this was not called by roce client */ if (client->ops->uninit_instance && hdev->nic_client && client->type != HNAE3_CLIENT_ROCE) { + while (test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) + msleep(HCLGEVF_WAIT_RESET_DONE); clear_bit(HCLGEVF_STATE_NIC_REGISTERED, &hdev->state);
client->ops->uninit_instance(&hdev->nic, 0); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h index 4bd922b475012..f6f736c0091c0 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -109,6 +109,8 @@ #define HCLGEVF_VF_RST_ING 0x07008 #define HCLGEVF_VF_RST_ING_BIT BIT(16)
+#define HCLGEVF_WAIT_RESET_DONE 100 + #define HCLGEVF_RSS_IND_TBL_SIZE 512 #define HCLGEVF_RSS_SET_BITMAP_MSK 0xffff #define HCLGEVF_RSS_KEY_SIZE 40
From: Guangbin Huang huangguangbin2@huawei.com
[ Upstream commit 688db0c7a4a69ddc8b8143a1cac01eb20082a3aa ]
Currently, driver only allow configuring ETS bandwidth of TCs according to the max TC number queried from firmware. However, the hardware actually supports 8 TCs and users may need to configure ETS bandwidth of all TCs, so remove the restriction.
Fixes: 330baff5423b ("net: hns3: add ETS TC weight setting in SSU module") Signed-off-by: Guangbin Huang huangguangbin2@huawei.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 2 +- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index 90013c131e949..375ebf105a9aa 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -129,7 +129,7 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, u32 total_ets_bw = 0; u8 i;
- for (i = 0; i < hdev->tc_max; i++) { + for (i = 0; i < HNAE3_MAX_TC; i++) { switch (ets->tc_tsa[i]) { case IEEE_8021QAZ_TSA_STRICT: if (hdev->tm_info.tc_info[i].tc_sch_mode != diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index a50e2edbf4a0f..429652a8cde16 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -1123,7 +1123,6 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev) { -#define DEFAULT_TC_WEIGHT 1 #define DEFAULT_TC_OFFSET 14
struct hclge_ets_tc_weight_cmd *ets_weight; @@ -1136,13 +1135,7 @@ static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev) for (i = 0; i < HNAE3_MAX_TC; i++) { struct hclge_pg_info *pg_info;
- ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT; - - if (!(hdev->hw_tc_map & BIT(i))) - continue; - - pg_info = - &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; + pg_info = &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; ets_weight->tc_weight[i] = pg_info->tc_dwrr[i]; }
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit f64ab8e4f368f48afb08ae91928e103d17b235e9 ]
Commit fe28c53ed71d ("net: stmmac: fix taprio configuration when base_time is in the past") allowed some base time values in the past, but apparently not all, the base-time value of 0 (Jan 1st 1970) is still explicitly denied by the driver.
Remove the bogus check.
Fixes: b60189e0392f ("net: stmmac: Integrate EST with TAPRIO scheduler API") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Kurt Kanzenbach kurt@linutronix.de Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index 8160087ee92f2..1c4ea0b1b845b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -786,8 +786,6 @@ static int tc_setup_taprio(struct stmmac_priv *priv, goto disable; if (qopt->num_entries >= dep) return -EINVAL; - if (!qopt->base_time) - return -ERANGE; if (!qopt->cycle_time) return -ERANGE;
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
[ Upstream commit 7a166854b4e24c57d56b3eba9fe1594985ee0a2c ]
It is spurious to allocate a bitmap without initializing it. So, better safe than sorry, initialize it to 0 at least to have some known values.
While at it, switch to the devm_bitmap_ API which is less verbose.
Fixes: 4b41d3436796 ("net: ethernet: ti: cpsw: allow untagged traffic on host port") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/ti/cpsw_ale.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 0c75e0576ee1f..1ef0aaef5c61c 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -1299,10 +1299,8 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params) if (!ale) return ERR_PTR(-ENOMEM);
- ale->p0_untag_vid_mask = - devm_kmalloc_array(params->dev, BITS_TO_LONGS(VLAN_N_VID), - sizeof(unsigned long), - GFP_KERNEL); + ale->p0_untag_vid_mask = devm_bitmap_zalloc(params->dev, VLAN_N_VID, + GFP_KERNEL); if (!ale->p0_untag_vid_mask) return ERR_PTR(-ENOMEM);
From: Marek Behún kabel@kernel.org
[ Upstream commit bb7bbb6e36474933540c24ae1f1ad651b843981f ]
Commit bfe301ebbc94 ("net: mvpp2: convert to use mac_prepare()/mac_finish()") introduced a bug wherein it leaves the MAC RESET register asserted after mac_finish(), due to wrong order of function calls.
Before it was: .mac_config() mvpp22_mode_reconfigure() assert reset mvpp2_xlg_config() deassert reset
Now it is: .mac_prepare() .mac_config() mvpp2_xlg_config() deassert reset .mac_finish() mvpp2_xlg_config() assert reset
Obviously this is wrong.
This bug is triggered when phylink tries to change the PHY interface mode from a GMAC mode (sgmii, 1000base-x, 2500base-x) to XLG mode (10gbase-r, xaui). The XLG mode does not work since reset is left asserted. Only after ifconfig down && ifconfig up is called will the XLG mode work.
Move the call to mvpp22_mode_reconfigure() to .mac_prepare() implementation. Since some of the subsequent functions need to know whether the interface is being changed, we unfortunately also need to pass around the new interface mode before setting port->phy_interface.
Fixes: bfe301ebbc94 ("net: mvpp2: convert to use mac_prepare()/mac_finish()") Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index d5c92e43f89e6..d74d4966b13fc 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1605,7 +1605,7 @@ static void mvpp22_gop_fca_set_periodic_timer(struct mvpp2_port *port) mvpp22_gop_fca_enable_periodic(port, true); }
-static int mvpp22_gop_init(struct mvpp2_port *port) +static int mvpp22_gop_init(struct mvpp2_port *port, phy_interface_t interface) { struct mvpp2 *priv = port->priv; u32 val; @@ -1613,7 +1613,7 @@ static int mvpp22_gop_init(struct mvpp2_port *port) if (!priv->sysctrl_base) return 0;
- switch (port->phy_interface) { + switch (interface) { case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: @@ -1743,15 +1743,15 @@ static void mvpp22_gop_setup_irq(struct mvpp2_port *port) * lanes by the physical layer. This is why configurations like * "PPv2 (2500BaseX) - COMPHY (2500SGMII)" are valid. */ -static int mvpp22_comphy_init(struct mvpp2_port *port) +static int mvpp22_comphy_init(struct mvpp2_port *port, + phy_interface_t interface) { int ret;
if (!port->comphy) return 0;
- ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET, - port->phy_interface); + ret = phy_set_mode_ext(port->comphy, PHY_MODE_ETHERNET, interface); if (ret) return ret;
@@ -2172,7 +2172,8 @@ static void mvpp22_pcs_reset_assert(struct mvpp2_port *port) writel(val & ~MVPP22_XPCS_CFG0_RESET_DIS, xpcs + MVPP22_XPCS_CFG0); }
-static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port) +static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port, + phy_interface_t interface) { struct mvpp2 *priv = port->priv; void __iomem *mpcs, *xpcs; @@ -2184,7 +2185,7 @@ static void mvpp22_pcs_reset_deassert(struct mvpp2_port *port) mpcs = priv->iface_base + MVPP22_MPCS_BASE(port->gop_id); xpcs = priv->iface_base + MVPP22_XPCS_BASE(port->gop_id);
- switch (port->phy_interface) { + switch (interface) { case PHY_INTERFACE_MODE_10GBASER: val = readl(mpcs + MVPP22_MPCS_CLK_RESET); val |= MAC_CLK_RESET_MAC | MAC_CLK_RESET_SD_RX | @@ -4529,7 +4530,8 @@ static int mvpp2_poll(struct napi_struct *napi, int budget) return rx_done; }
-static void mvpp22_mode_reconfigure(struct mvpp2_port *port) +static void mvpp22_mode_reconfigure(struct mvpp2_port *port, + phy_interface_t interface) { u32 ctrl3;
@@ -4540,18 +4542,18 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port) mvpp22_pcs_reset_assert(port);
/* comphy reconfiguration */ - mvpp22_comphy_init(port); + mvpp22_comphy_init(port, interface);
/* gop reconfiguration */ - mvpp22_gop_init(port); + mvpp22_gop_init(port, interface);
- mvpp22_pcs_reset_deassert(port); + mvpp22_pcs_reset_deassert(port, interface);
if (mvpp2_port_supports_xlg(port)) { ctrl3 = readl(port->base + MVPP22_XLG_CTRL3_REG); ctrl3 &= ~MVPP22_XLG_CTRL3_MACMODESELECT_MASK;
- if (mvpp2_is_xlg(port->phy_interface)) + if (mvpp2_is_xlg(interface)) ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_10G; else ctrl3 |= MVPP22_XLG_CTRL3_MACMODESELECT_GMAC; @@ -4559,7 +4561,7 @@ static void mvpp22_mode_reconfigure(struct mvpp2_port *port) writel(ctrl3, port->base + MVPP22_XLG_CTRL3_REG); }
- if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(port->phy_interface)) + if (mvpp2_port_supports_xlg(port) && mvpp2_is_xlg(interface)) mvpp2_xlg_max_rx_size_set(port); else mvpp2_gmac_max_rx_size_set(port); @@ -4579,7 +4581,7 @@ static void mvpp2_start_dev(struct mvpp2_port *port) mvpp2_interrupts_enable(port);
if (port->priv->hw_version >= MVPP22) - mvpp22_mode_reconfigure(port); + mvpp22_mode_reconfigure(port, port->phy_interface);
if (port->phylink) { phylink_start(port->phylink); @@ -6477,6 +6479,9 @@ static int mvpp2__mac_prepare(struct phylink_config *config, unsigned int mode, mvpp22_gop_mask_irq(port);
phy_power_off(port->comphy); + + /* Reconfigure the serdes lanes */ + mvpp22_mode_reconfigure(port, interface); } }
@@ -6531,9 +6536,6 @@ static int mvpp2_mac_finish(struct phylink_config *config, unsigned int mode, port->phy_interface != interface) { port->phy_interface = interface;
- /* Reconfigure the serdes lanes */ - mvpp22_mode_reconfigure(port); - /* Unmask interrupts */ mvpp22_gop_unmask_irq(port); } @@ -6960,7 +6962,7 @@ static int mvpp2_port_probe(struct platform_device *pdev, * driver does this, we can remove this code. */ if (port->comphy) { - err = mvpp22_comphy_init(port); + err = mvpp22_comphy_init(port, port->phy_interface); if (err == 0) phy_power_off(port->comphy); }
From: Eiichi Tsukata eiichi.tsukata@nutanix.com
[ Upstream commit c7cd82b90599fa10915f41e3dd9098a77d0aa7b6 ]
Currently vosck_connect() increments sock refcount for nonblocking socket each time it's called, which can lead to memory leak if it's called multiple times because connect timeout function decrements sock refcount only once.
Fixes it by making vsock_connect() return -EALREADY immediately when sock state is already SS_CONNECTING.
Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Reviewed-by: Stefano Garzarella sgarzare@redhat.com Signed-off-by: Eiichi Tsukata eiichi.tsukata@nutanix.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/vmw_vsock/af_vsock.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index e2c0cfb334d20..fa8c1b623fa21 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -1322,6 +1322,8 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr, * non-blocking call. */ err = -EALREADY; + if (flags & O_NONBLOCK) + goto out; break; default: if ((sk->sk_state == TCP_LISTEN) ||
From: Dust Li dust.li@linux.alibaba.com
[ Upstream commit e5d5aadcf3cd59949316df49c27cb21788d7efe4 ]
We got the following WARNING when running ab/nginx test with RDMA link flapping (up-down-up). The reason is when smc_sock fallback and at linkdown happens simultaneously, we may got the following situation:
__smc_lgr_terminate() --> smc_conn_kill() --> smc_close_active_abort() smc_sock->sk_state = SMC_CLOSED sock_put(smc_sock)
smc_sock was set to SMC_CLOSED and sock_put() been called when terminate the link group. But later application call close() on the socket, then we got:
__smc_release(): if (smc_sock->fallback) smc_sock->sk_state = SMC_CLOSED sock_put(smc_sock)
Again we set the smc_sock to CLOSED through it's already in CLOSED state, and double put the refcnt, so the following warning happens:
refcount_t: underflow; use-after-free. WARNING: CPU: 5 PID: 860 at lib/refcount.c:28 refcount_warn_saturate+0x8d/0xf0 Modules linked in: CPU: 5 PID: 860 Comm: nginx Not tainted 5.10.46+ #403 Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 8c24b4c 04/01/2014 RIP: 0010:refcount_warn_saturate+0x8d/0xf0 Code: 05 5c 1e b5 01 01 e8 52 25 bc ff 0f 0b c3 80 3d 4f 1e b5 01 00 75 ad 48
RSP: 0018:ffffc90000527e50 EFLAGS: 00010286 RAX: 0000000000000026 RBX: ffff8881300df2c0 RCX: 0000000000000027 RDX: 0000000000000000 RSI: ffff88813bd58040 RDI: ffff88813bd58048 RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000001 R10: ffff8881300df2c0 R11: ffffc90000527c78 R12: ffff8881300df340 R13: ffff8881300df930 R14: ffff88810b3dad80 R15: ffff8881300df4f8 FS: 00007f739de8fb80(0000) GS:ffff88813bd40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000000000a01b008 CR3: 0000000111b64003 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: smc_release+0x353/0x3f0 __sock_release+0x3d/0xb0 sock_close+0x11/0x20 __fput+0x93/0x230 task_work_run+0x65/0xa0 exit_to_user_mode_prepare+0xf9/0x100 syscall_exit_to_user_mode+0x27/0x190 entry_SYSCALL_64_after_hwframe+0x44/0xa9
This patch adds check in __smc_release() to make sure we won't do an extra sock_put() and set the socket to CLOSED when its already in CLOSED state.
Fixes: 51f1de79ad8e (net/smc: replace sock_put worker by socket refcounting) Signed-off-by: Dust Li dust.li@linux.alibaba.com Reviewed-by: Tony Lu tonylu@linux.alibaba.com Signed-off-by: Dust Li dust.li@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/af_smc.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index 78b663dbfa1f9..32c1c7ce856d3 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -148,14 +148,18 @@ static int __smc_release(struct smc_sock *smc) sock_set_flag(sk, SOCK_DEAD); sk->sk_shutdown |= SHUTDOWN_MASK; } else { - if (sk->sk_state != SMC_LISTEN && sk->sk_state != SMC_INIT) - sock_put(sk); /* passive closing */ - if (sk->sk_state == SMC_LISTEN) { - /* wake up clcsock accept */ - rc = kernel_sock_shutdown(smc->clcsock, SHUT_RDWR); + if (sk->sk_state != SMC_CLOSED) { + if (sk->sk_state != SMC_LISTEN && + sk->sk_state != SMC_INIT) + sock_put(sk); /* passive closing */ + if (sk->sk_state == SMC_LISTEN) { + /* wake up clcsock accept */ + rc = kernel_sock_shutdown(smc->clcsock, + SHUT_RDWR); + } + sk->sk_state = SMC_CLOSED; + sk->sk_state_change(sk); } - sk->sk_state = SMC_CLOSED; - sk->sk_state_change(sk); smc_restore_fallback_changes(smc); }
From: Rahul Lakkireddy rahul.lakkireddy@chelsio.com
[ Upstream commit 4ca110bf8d9b31a60f8f8ff6706ea147d38ad97c ]
Ensure diagnostics monitoring support is implemented for the SFF 8472 compliant port module and set the correct length for ethtool port module eeprom read.
Fixes: f56ec6766dcf ("cxgb4: Add support for ethtool i2c dump") Signed-off-by: Manoj Malviya manojmalviya@chelsio.com Signed-off-by: Rahul Lakkireddy rahul.lakkireddy@chelsio.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c | 7 +++++-- drivers/net/ethernet/chelsio/cxgb4/t4_hw.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c index 5903bdb78916f..129352bbe1143 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c @@ -2015,12 +2015,15 @@ static int cxgb4_get_module_info(struct net_device *dev, if (ret) return ret;
- if (!sff8472_comp || (sff_diag_type & 4)) { + if (!sff8472_comp || (sff_diag_type & SFP_DIAG_ADDRMODE)) { modinfo->type = ETH_MODULE_SFF_8079; modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; } else { modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + if (sff_diag_type & SFP_DIAG_IMPLEMENTED) + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + else + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2; } break;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h index 002fc62ea7262..63bc956d20376 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h @@ -293,6 +293,8 @@ enum { #define I2C_PAGE_SIZE 0x100 #define SFP_DIAG_TYPE_ADDR 0x5c #define SFP_DIAG_TYPE_LEN 0x1 +#define SFP_DIAG_ADDRMODE BIT(2) +#define SFP_DIAG_IMPLEMENTED BIT(6) #define SFF_8472_COMP_ADDR 0x5e #define SFF_8472_COMP_LEN 0x1 #define SFF_REV_ADDR 0x1
From: Willem de Bruijn willemb@google.com
[ Upstream commit d336509cb9d03970911878bb77f0497f64fda061 ]
The below commit added optional support for passing a bind address. It configures the sockaddr bind arguments before parsing options and reconfigures on options -b and -4.
This broke support for passing port (-p) on its own.
Configure sockaddr after parsing all arguments.
Fixes: 3327a9c46352 ("selftests: add functionals test for UDP GRO") Reported-by: Eric Dumazet edumazet@google.com Signed-off-by: Willem de Bruijn willemb@google.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/net/udpgso_bench_rx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c index 76a24052f4b47..6a193425c367f 100644 --- a/tools/testing/selftests/net/udpgso_bench_rx.c +++ b/tools/testing/selftests/net/udpgso_bench_rx.c @@ -293,19 +293,17 @@ static void usage(const char *filepath)
static void parse_opts(int argc, char **argv) { + const char *bind_addr = NULL; int c;
- /* bind to any by default */ - setup_sockaddr(PF_INET6, "::", &cfg_bind_addr); while ((c = getopt(argc, argv, "4b:C:Gl:n:p:rR:S:tv")) != -1) { switch (c) { case '4': cfg_family = PF_INET; cfg_alen = sizeof(struct sockaddr_in); - setup_sockaddr(PF_INET, "0.0.0.0", &cfg_bind_addr); break; case 'b': - setup_sockaddr(cfg_family, optarg, &cfg_bind_addr); + bind_addr = optarg; break; case 'C': cfg_connect_timeout_ms = strtoul(optarg, NULL, 0); @@ -341,6 +339,11 @@ static void parse_opts(int argc, char **argv) } }
+ if (!bind_addr) + bind_addr = cfg_family == PF_INET6 ? "::" : "0.0.0.0"; + + setup_sockaddr(cfg_family, bind_addr, &cfg_bind_addr); + if (optind != argc) usage(argv[0]);
From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit d9c8e52ff9e84ff1a406330f9ea4de7c5eb40282 ]
Commit aeb58c860dc5 ("thermal/drivers/int340x: processor_thermal: Suppot 64 bit RFIM responses") started using 'readq()' to read 64-bit status responses from the int340x hardware.
That's all fine and good, but on 32-bit targets a 64-bit 'readq()' is ambiguous, since it's no longer an atomic access. Some hardware might require 64-bit accesses, and other hardware might want low word first or high word first.
It's quite likely that the driver isn't relevant in a 32-bit environment any more, and there's a patch floating around to just make it depend on X86_64, but let's make it buildable on x86-32 anyway.
The driver previously just read the low 32 bits, so the hardware certainly is ok with 32-bit reads, and in a little-endian environment the low word first model is the natural one.
So just add the include for the 'io-64-nonatomic-lo-hi.h' version.
Fixes: aeb58c860dc5 ("thermal/drivers/int340x: processor_thermal: Suppot 64 bit RFIM responses") Reported-by: Jakub Kicinski kuba@kernel.org Cc: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Cc: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c index 59e93b04f0a9e..66cd0190bc035 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_mbox.c @@ -7,6 +7,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/io-64-nonatomic-lo-hi.h> #include "processor_thermal_device.h"
#define MBOX_CMD_WORKLOAD_TYPE_READ 0x0E
From: Steve French stfrench@microsoft.com
commit 71e6864eacbef0b2645ca043cdfbac272cb6cea3 upstream.
Linux allows doing a flush/fsync on a file open for read-only, but the protocol does not allow that. If the file passed in on the flush is read-only try to find a writeable handle for the same inode, if that is not possible skip sending the fsync call to the server to avoid breaking the apps.
Reported-by: Julian Sikorski belegdol@gmail.com Tested-by: Julian Sikorski belegdol@gmail.com Suggested-by: Jeremy Allison jra@samba.org Reviewed-by: Paulo Alcantara (SUSE) pc@cjr.nz Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/cifs/file.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-)
--- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2692,12 +2692,23 @@ int cifs_strict_fsync(struct file *file, tcon = tlink_tcon(smbfile->tlink); if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { server = tcon->ses->server; - if (server->ops->flush) - rc = server->ops->flush(xid, tcon, &smbfile->fid); - else + if (server->ops->flush == NULL) { rc = -ENOSYS; + goto strict_fsync_exit; + } + + if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) { + smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY); + if (smbfile) { + rc = server->ops->flush(xid, tcon, &smbfile->fid); + cifsFileInfo_put(smbfile); + } else + cifs_dbg(FYI, "ignore fsync for file not open for write\n"); + } else + rc = server->ops->flush(xid, tcon, &smbfile->fid); }
+strict_fsync_exit: free_xid(xid); return rc; } @@ -2709,6 +2720,7 @@ int cifs_fsync(struct file *file, loff_t struct cifs_tcon *tcon; struct TCP_Server_Info *server; struct cifsFileInfo *smbfile = file->private_data; + struct inode *inode = file_inode(file); struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
rc = file_write_and_wait_range(file, start, end); @@ -2725,12 +2737,23 @@ int cifs_fsync(struct file *file, loff_t tcon = tlink_tcon(smbfile->tlink); if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { server = tcon->ses->server; - if (server->ops->flush) - rc = server->ops->flush(xid, tcon, &smbfile->fid); - else + if (server->ops->flush == NULL) { rc = -ENOSYS; + goto fsync_exit; + } + + if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) { + smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY); + if (smbfile) { + rc = server->ops->flush(xid, tcon, &smbfile->fid); + cifsFileInfo_put(smbfile); + } else + cifs_dbg(FYI, "ignore fsync for file not open for write\n"); + } else + rc = server->ops->flush(xid, tcon, &smbfile->fid); }
+fsync_exit: free_xid(xid); return rc; }
From: Michał Mirosław mirq-linux@rere.qmqm.pl
commit 0d08e7bf0d0d1a29aff7b16ef516f7415eb1aa05 upstream.
Currently __set_fixmap() bails out with a warning when called in early boot from early_iounmap(). Fix it, and while at it, make the comment a bit easier to understand.
Cc: stable@vger.kernel.org Fixes: b089c31c519c ("ARM: 8667/3: Fix memory attribute inconsistencies when using fixmap") Acked-by: Ard Biesheuvel ardb@kernel.org Signed-off-by: Michał Mirosław mirq-linux@rere.qmqm.pl Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/mm/mmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -390,9 +390,9 @@ void __set_fixmap(enum fixed_addresses i BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) < FIXADDR_START); BUG_ON(idx >= __end_of_fixed_addresses);
- /* we only support device mappings until pgprot_kernel has been set */ + /* We support only device mappings before pgprot_kernel is set. */ if (WARN_ON(pgprot_val(prot) != pgprot_val(FIXMAP_PAGE_IO) && - pgprot_val(pgprot_kernel) == 0)) + pgprot_val(prot) && pgprot_val(pgprot_kernel) == 0)) return;
if (pgprot_val(prot))
From: Arnd Bergmann arnd@arndb.de
commit 418ace9992a7647c446ed3186df40cf165b67298 upstream.
Naresh and Antonio ran into a build failure with latest Debian armhf compilers, with lots of output like
tmp/ccY3nOAs.s:2215: Error: selected processor does not support `cpsid i' in ARM mode
As it turns out, $(cc-option) fails early here when the FPU is not selected before CPU architecture is selected, as the compiler option check runs before enabling -msoft-float, which causes a problem when testing a target architecture level without an FPU:
cc1: error: '-mfloat-abi=hard': selected architecture lacks an FPU
Passing e.g. -march=armv6k+fp in place of -march=armv6k would avoid this issue, but the fallback logic is already broken because all supported compilers (gcc-5 and higher) are much more recent than these options, and building with -march=armv5t as a fallback no longer works.
The best way forward that I see is to just remove all the checks, which also has the nice side-effect of slightly improving the startup time for 'make'.
The -mtune=marvell-f option was apparently never supported by any mainline compiler, and the custom Codesourcery gcc build that did support is now too old to build kernels, so just use -mtune=xscale unconditionally for those.
This should be safe to apply on all stable kernels, and will be required in order to keep building them with gcc-11 and higher.
Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=996419
Reported-by: Antonio Terceiro antonio.terceiro@linaro.org Reported-by: Naresh Kamboju naresh.kamboju@linaro.org Reported-by: Sebastian Andrzej Siewior sebastian@breakpoint.cc Tested-by: Sebastian Reichel sebastian.reichel@collabora.com Tested-by: Klaus Kudielka klaus.kudielka@gmail.com Cc: Matthias Klose doko@debian.org Cc: stable@vger.kernel.org Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/Makefile | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-)
--- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -60,15 +60,15 @@ KBUILD_CFLAGS += $(call cc-option,-fno-i # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes # testing for a specific architecture or later rather impossible. -arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m -arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) -arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) +arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m +arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -march=armv7-a +arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 -march=armv6 # Only override the compiler option if ARMv6. The ARMv6K extensions are # always available in ARMv7 ifeq ($(CONFIG_CPU_32v6),y) -arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) +arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 -march=armv6k endif -arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) +arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 -march=armv5te arch-$(CONFIG_CPU_32v4T) =-D__LINUX_ARM_ARCH__=4 -march=armv4t arch-$(CONFIG_CPU_32v4) =-D__LINUX_ARM_ARCH__=4 -march=armv4 arch-$(CONFIG_CPU_32v3) =-D__LINUX_ARM_ARCH__=3 -march=armv3m @@ -82,7 +82,7 @@ tune-$(CONFIG_CPU_ARM720T) =-mtune=arm7t tune-$(CONFIG_CPU_ARM740T) =-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM9TDMI) =-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM940T) =-mtune=arm9tdmi -tune-$(CONFIG_CPU_ARM946E) =$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) +tune-$(CONFIG_CPU_ARM946E) =-mtune=arm9e tune-$(CONFIG_CPU_ARM920T) =-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) =-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) =-mtune=arm9tdmi @@ -90,11 +90,11 @@ tune-$(CONFIG_CPU_ARM926T) =-mtune=arm9t tune-$(CONFIG_CPU_FA526) =-mtune=arm9tdmi tune-$(CONFIG_CPU_SA110) =-mtune=strongarm110 tune-$(CONFIG_CPU_SA1100) =-mtune=strongarm1100 -tune-$(CONFIG_CPU_XSCALE) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale -tune-$(CONFIG_CPU_XSC3) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale -tune-$(CONFIG_CPU_FEROCEON) =$(call cc-option,-mtune=marvell-f,-mtune=xscale) -tune-$(CONFIG_CPU_V6) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) -tune-$(CONFIG_CPU_V6K) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) +tune-$(CONFIG_CPU_XSCALE) =-mtune=xscale +tune-$(CONFIG_CPU_XSC3) =-mtune=xscale +tune-$(CONFIG_CPU_FEROCEON) =-mtune=xscale +tune-$(CONFIG_CPU_V6) =-mtune=arm1136j-s +tune-$(CONFIG_CPU_V6K) =-mtune=arm1136j-s
# Evaluate tune cc-option calls now tune-y := $(tune-y)
From: Helge Deller deller@gmx.de
commit 279917e27edc293eb645a25428c6ab3f3bca3f86 upstream.
I noticed that sometimes at kernel startup the backtraces did not included the function names of init functions. Their address were not resolved to function names and instead only the address was printed.
Debugging shows that the culprit is is_ksym_addr() which is called by the backtrace functions to check if an address belongs to a function in the kernel. The problem occurs only for CONFIG_KALLSYMS_ALL=y.
When looking at is_ksym_addr() one can see that for CONFIG_KALLSYMS_ALL=y the function only tries to resolve the address via is_kernel() function, which checks like this: if (addr >= _stext && addr <= _end) return 1; On parisc the init functions are located before _stext, so this check fails. Other platforms seem to have all functions (including init functions) behind _stext.
The following patch moves the _stext symbol at the beginning of the kernel and thus includes the init section. This fixes the check and does not seem to have any negative side effects on where the kernel mapping happens in the map_pages() function in arch/parisc/mm/init.c.
Signed-off-by: Helge Deller deller@gmx.de Cc: stable@kernel.org # 5.4+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/kernel/vmlinux.lds.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -57,6 +57,8 @@ SECTIONS { . = KERNEL_BINARY_TEXT_START;
+ _stext = .; /* start of kernel text, includes init code & data */ + __init_begin = .; HEAD_TEXT_SECTION MLONGCALL_DISCARD(INIT_TEXT_SECTION(8)) @@ -80,7 +82,6 @@ SECTIONS /* freed after init ends here */
_text = .; /* Text and read-only data */ - _stext = .; MLONGCALL_KEEP(INIT_TEXT_SECTION(8)) .text ALIGN(PAGE_SIZE) : { TEXT_TEXT
From: John David Anglin dave.anglin@bell.net
commit 38860b2c8bb1b92f61396eb06a63adff916fc31d upstream.
For years, there have been random segmentation faults in userspace on SMP PA-RISC machines. It occurred to me that this might be a problem in set_pte_at(). MIPS and some other architectures do cache flushes when installing PTEs with the present bit set.
Here I have adapted the code in update_mmu_cache() to flush the kernel mapping when the kernel flush is deferred, or when the kernel mapping may alias with the user mapping. This simplifies calls to update_mmu_cache().
I also changed the barrier in set_pte() from a compiler barrier to a full memory barrier. I know this change is not sufficient to fix the problem. It might not be needed.
I have had a few days of operation with 5.14.16 to 5.15.1 and haven't seen any random segmentation faults on rp3440 or c8000 so far.
Signed-off-by: John David Anglin dave.anglin@bell.net Signed-off-by: Helge Deller deller@gmx.de Cc: stable@kernel.org # 5.12+ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/parisc/include/asm/pgtable.h | 10 ++++++++-- arch/parisc/kernel/cache.c | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-)
--- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -76,6 +76,8 @@ static inline void purge_tlb_entries(str purge_tlb_end(flags); }
+extern void __update_cache(pte_t pte); + /* Certain architectures need to do special things when PTEs * within a page table are directly modified. Thus, the following * hook is made available. @@ -83,11 +85,14 @@ static inline void purge_tlb_entries(str #define set_pte(pteptr, pteval) \ do { \ *(pteptr) = (pteval); \ - barrier(); \ + mb(); \ } while(0)
#define set_pte_at(mm, addr, pteptr, pteval) \ do { \ + if (pte_present(pteval) && \ + pte_user(pteval)) \ + __update_cache(pteval); \ *(pteptr) = (pteval); \ purge_tlb_entries(mm, addr); \ } while (0) @@ -303,6 +308,7 @@ extern unsigned long *empty_zero_page;
#define pte_none(x) (pte_val(x) == 0) #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) +#define pte_user(x) (pte_val(x) & _PAGE_USER) #define pte_clear(mm, addr, xp) set_pte_at(mm, addr, xp, __pte(0))
#define pmd_flag(x) (pmd_val(x) & PxD_FLAG_MASK) @@ -410,7 +416,7 @@ extern void paging_init (void);
#define PG_dcache_dirty PG_arch_1
-extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); +#define update_mmu_cache(vms,addr,ptep) __update_cache(*ptep)
/* Encode and de-code a swap entry */
--- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -83,9 +83,9 @@ EXPORT_SYMBOL(flush_cache_all_local); #define pfn_va(pfn) __va(PFN_PHYS(pfn))
void -update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) +__update_cache(pte_t pte) { - unsigned long pfn = pte_pfn(*ptep); + unsigned long pfn = pte_pfn(pte); struct page *page;
/* We don't have pte special. As a result, we can be called with
From: Masahiro Yamada masahiroy@kernel.org
commit cca2aac8acf470b01066f559acd7146fc4c32ae8 upstream.
platform-y accumulates platform names with a slash appended. The current $(patsubst ...) ends up with doubling slashes.
GNU Make still include Platform files, but in case of an error, a clumsy file path is displayed:
arch/mips/loongson2ef//Platform:36: *** only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop. Stop.
Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Cc: Jason Self jason@bluehome.net Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/Kbuild.platforms | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -38,4 +38,4 @@ platform-$(CONFIG_MACH_TX49XX) += txx9/ platform-$(CONFIG_MACH_VR41XX) += vr41xx/
# include the platform specific files -include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platform-y)) +include $(patsubst %/, $(srctree)/arch/mips/%/Platform, $(platform-y))
From: Masahiro Yamada masahiroy@kernel.org
commit 0706f74f719e6e72c3a862ab2990796578fa73cc upstream.
Since commit 805b2e1d427a ("kbuild: include Makefile.compiler only when compiler is needed"), package builds for the loongson2f platform fail.
$ make ARCH=mips CROSS_COMPILE=mips64-linux- lemote2f_defconfig bindeb-pkg [ snip ] sh ./scripts/package/builddeb arch/mips/loongson2ef//Platform:36: *** only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop. Stop. cp: cannot stat '': No such file or directory make[5]: *** [scripts/Makefile.package:87: intdeb-pkg] Error 1 make[4]: *** [Makefile:1558: intdeb-pkg] Error 2 make[3]: *** [debian/rules:13: binary-arch] Error 2 dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2 make[2]: *** [scripts/Makefile.package:83: bindeb-pkg] Error 2 make[1]: *** [Makefile:1558: bindeb-pkg] Error 2 make: *** [Makefile:350: __build_one_by_one] Error 2
The reason is because "make image_name" fails.
$ make ARCH=mips CROSS_COMPILE=mips64-linux- image_name arch/mips/loongson2ef//Platform:36: *** only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop. Stop.
In general, adding $(error ...) in the parse stage is troublesome, and it is pointless to check toolchains even if we are not building anything. Do not include Kbuild.platform in such cases.
Fixes: 805b2e1d427a ("kbuild: include Makefile.compiler only when compiler is needed") Reported-by: Jason Self jason@bluehome.net Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/Makefile | 2 ++ 1 file changed, 2 insertions(+)
--- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -254,7 +254,9 @@ endif # # Board-dependent options and extra files # +ifdef need-compiler include $(srctree)/arch/mips/Kbuild.platforms +endif
ifdef CONFIG_PHYSICAL_START load-y = $(CONFIG_PHYSICAL_START)
From: Maciej W. Rozycki macro@orcam.me.uk
commit a923a2676e60683aee46aa4b93c30aff240ac20d upstream.
Fix assembly errors like:
{standard input}: Assembler messages: {standard input}:287: Error: opcode not supported on this processor: mips3 (mips3) `dins $10,$7,32,32' {standard input}:680: Error: opcode not supported on this processor: mips3 (mips3) `dins $10,$7,32,32' {standard input}:1274: Error: opcode not supported on this processor: mips3 (mips3) `dins $12,$9,32,32' {standard input}:2175: Error: opcode not supported on this processor: mips3 (mips3) `dins $10,$7,32,32' make[1]: *** [scripts/Makefile.build:277: mm/highmem.o] Error 1
with code produced from `__cmpxchg64' for MIPS64r2 CPU configurations using CONFIG_32BIT and CONFIG_PHYS_ADDR_T_64BIT.
This is due to MIPS_ISA_ARCH_LEVEL downgrading the assembly architecture to `r4000' i.e. MIPS III for MIPS64r2 configurations, while there is a block of code containing a DINS MIPS64r2 instruction conditionalized on MIPS_ISA_REV >= 2 within the scope of the downgrade.
The assembly architecture override code pattern has been put there for LL/SC instructions, so that code compiles for configurations that select a processor to build for that does not support these instructions while still providing run-time support for processors that do, dynamically switched by non-constant `cpu_has_llsc'. It went in with linux-mips.org commit aac8aa7717a2 ("Enable a suitable ISA for the assembler around ll/sc so that code builds even for processors that don't support the instructions. Plus minor formatting fixes.") back in 2005.
Fix the problem by wrapping these instructions along with the adjacent SYNC instructions only, following the practice established with commit cfd54de3b0e4 ("MIPS: Avoid move psuedo-instruction whilst using MIPS_ISA_LEVEL") and commit 378ed6f0e3c5 ("MIPS: Avoid using .set mips0 to restore ISA"). Strictly speaking the SYNC instructions do not have to be wrapped as they are only used as a Loongson3 erratum workaround, so they will be enabled in the assembler by default, but do this so as to keep code consistent with other places.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Maciej W. Rozycki macro@orcam.me.uk Fixes: c7e2d71dda7a ("MIPS: Fix set_pte() for Netlogic XLR using cmpxchg64()") Cc: stable@vger.kernel.org # v5.1+ Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/include/asm/cmpxchg.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h @@ -249,6 +249,7 @@ static inline unsigned long __cmpxchg64( /* Load 64 bits from ptr */ " " __SYNC(full, loongson3_war) " \n" "1: lld %L0, %3 # __cmpxchg64 \n" + " .set pop \n" /* * Split the 64 bit value we loaded into the 2 registers that hold the * ret variable. @@ -276,12 +277,14 @@ static inline unsigned long __cmpxchg64( " or %L1, %L1, $at \n" " .set at \n" # endif + " .set push \n" + " .set " MIPS_ISA_ARCH_LEVEL " \n" /* Attempt to store new at ptr */ " scd %L1, %2 \n" /* If we failed, loop! */ "\t" __SC_BEQZ "%L1, 1b \n" - " .set pop \n" "2: " __SYNC(full, loongson3_war) " \n" + " .set pop \n" : "=&r"(ret), "=&r"(tmp), "=" GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr)
From: Dave Jones davej@codemonkey.org.uk
commit e629fc1407a63dbb748f828f9814463ffc2a0af0 upstream.
Errata SKX37 is word-for-word identical to the other errata listed in this workaround. I happened to notice this after investigating a CMCI storm on a Skylake host. While I can't confirm this was the root cause, spurious corrected errors does sound like a likely suspect.
Fixes: 2976908e4198 ("x86/mce: Do not log spurious corrected mce errors") Signed-off-by: Dave Jones davej@codemonkey.org.uk Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: Tony Luck tony.luck@intel.com Cc: stable@vger.kernel.org Link: https://lkml.kernel.org/r/20211029205759.GA7385@codemonkey.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/cpu/mce/intel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/arch/x86/kernel/cpu/mce/intel.c +++ b/arch/x86/kernel/cpu/mce/intel.c @@ -547,12 +547,13 @@ bool intel_filter_mce(struct mce *m) { struct cpuinfo_x86 *c = &boot_cpu_data;
- /* MCE errata HSD131, HSM142, HSW131, BDM48, and HSM142 */ + /* MCE errata HSD131, HSM142, HSW131, BDM48, HSM142 and SKX37 */ if ((c->x86 == 6) && ((c->x86_model == INTEL_FAM6_HASWELL) || (c->x86_model == INTEL_FAM6_HASWELL_L) || (c->x86_model == INTEL_FAM6_BROADWELL) || - (c->x86_model == INTEL_FAM6_HASWELL_G)) && + (c->x86_model == INTEL_FAM6_HASWELL_G) || + (c->x86_model == INTEL_FAM6_SKYLAKE_X)) && (m->bank == 0) && ((m->status & 0xa0000000ffffffff) == 0x80000000000f0005)) return true;
From: Thomas Gleixner tglx@linutronix.de
commit 9c8e9c9681a0f3f1ae90a90230d059c7a1dece5a upstream.
The recent rework of PCI/MSI[X] masking moved the non-mask checks from the low level accessors into the higher level mask/unmask functions.
This missed the fact that these accessors can be invoked from other places as well. The missing checks break XEN-PV which sets pci_msi_ignore_mask and also violates the virtual MSIX and the msi_attrib.maskbit protections.
Instead of sprinkling checks all over the place, lift them back into the low level accessor functions. To avoid checking three different conditions combine them into one property of msi_desc::msi_attrib.
[ josef: Fixed the missed conversion in the core code ]
Fixes: fcacdfbef5a1 ("PCI/MSI: Provide a new set of mask and unmask functions") Reported-by: Josef Johansson josef@oderland.se Signed-off-by: Thomas Gleixner tglx@linutronix.de Tested-by: Josef Johansson josef@oderland.se Cc: Bjorn Helgaas helgaas@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/msi.c | 26 ++++++++++++++------------ include/linux/msi.h | 2 +- kernel/irq/msi.c | 4 ++-- 3 files changed, 17 insertions(+), 15 deletions(-)
--- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -148,6 +148,9 @@ static noinline void pci_msi_update_mask raw_spinlock_t *lock = &desc->dev->msi_lock; unsigned long flags;
+ if (!desc->msi_attrib.can_mask) + return; + raw_spin_lock_irqsave(lock, flags); desc->msi_mask &= ~clear; desc->msi_mask |= set; @@ -181,7 +184,8 @@ static void pci_msix_write_vector_ctrl(s { void __iomem *desc_addr = pci_msix_desc_addr(desc);
- writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); + if (desc->msi_attrib.can_mask) + writel(ctrl, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); }
static inline void pci_msix_mask(struct msi_desc *desc) @@ -200,23 +204,17 @@ static inline void pci_msix_unmask(struc
static void __pci_msi_mask_desc(struct msi_desc *desc, u32 mask) { - if (pci_msi_ignore_mask || desc->msi_attrib.is_virtual) - return; - if (desc->msi_attrib.is_msix) pci_msix_mask(desc); - else if (desc->msi_attrib.maskbit) + else pci_msi_mask(desc, mask); }
static void __pci_msi_unmask_desc(struct msi_desc *desc, u32 mask) { - if (pci_msi_ignore_mask || desc->msi_attrib.is_virtual) - return; - if (desc->msi_attrib.is_msix) pci_msix_unmask(desc); - else if (desc->msi_attrib.maskbit) + else pci_msi_unmask(desc, mask); }
@@ -484,7 +482,8 @@ msi_setup_entry(struct pci_dev *dev, int entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); entry->msi_attrib.is_virtual = 0; entry->msi_attrib.entry_nr = 0; - entry->msi_attrib.maskbit = !!(control & PCI_MSI_FLAGS_MASKBIT); + entry->msi_attrib.can_mask = !pci_msi_ignore_mask && + !!(control & PCI_MSI_FLAGS_MASKBIT); entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.multi_cap = (control & PCI_MSI_FLAGS_QMASK) >> 1; entry->msi_attrib.multiple = ilog2(__roundup_pow_of_two(nvec)); @@ -495,7 +494,7 @@ msi_setup_entry(struct pci_dev *dev, int entry->mask_pos = dev->msi_cap + PCI_MSI_MASK_32;
/* Save the initial mask status */ - if (entry->msi_attrib.maskbit) + if (entry->msi_attrib.can_mask) pci_read_config_dword(dev, entry->mask_pos, &entry->msi_mask);
out: @@ -638,10 +637,13 @@ static int msix_setup_entries(struct pci entry->msi_attrib.is_virtual = entry->msi_attrib.entry_nr >= vec_count;
+ entry->msi_attrib.can_mask = !pci_msi_ignore_mask && + !entry->msi_attrib.is_virtual; + entry->msi_attrib.default_irq = dev->irq; entry->mask_base = base;
- if (!entry->msi_attrib.is_virtual) { + if (entry->msi_attrib.can_mask) { addr = pci_msix_desc_addr(entry); entry->msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); } --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -148,7 +148,7 @@ struct msi_desc { u8 is_msix : 1; u8 multiple : 3; u8 multi_cap : 3; - u8 maskbit : 1; + u8 can_mask : 1; u8 is_64 : 1; u8 is_virtual : 1; u16 entry_nr; --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -529,10 +529,10 @@ static bool msi_check_reservation_mode(s
/* * Checking the first MSI descriptor is sufficient. MSIX supports - * masking and MSI does so when the maskbit is set. + * masking and MSI does so when the can_mask attribute is set. */ desc = first_msi_entry(dev); - return desc->msi_attrib.is_msix || desc->msi_attrib.maskbit; + return desc->msi_attrib.is_msix || desc->msi_attrib.can_mask; }
int __msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
From: Thomas Gleixner tglx@linutronix.de
commit 3735459037114d31e5acd9894fad9aed104231a0 upstream.
free_msi_irqs() frees the MSI entries before destroying the sysfs entries which are exposing them. Nothing prevents a concurrent free while a sysfs file is read and accesses the possibly freed entry.
Move the sysfs release ahead of freeing the entries.
Fixes: 1c51b50c2995 ("PCI/MSI: Export MSI mode using attributes, not kobjects") Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Bjorn Helgaas helgaas@kernel.org Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/87sfw5305m.ffs@tglx Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/msi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -368,6 +368,11 @@ static void free_msi_irqs(struct pci_dev for (i = 0; i < entry->nvec_used; i++) BUG_ON(irq_has_action(entry->irq + i));
+ if (dev->msi_irq_groups) { + msi_destroy_sysfs(&dev->dev, dev->msi_irq_groups); + dev->msi_irq_groups = NULL; + } + pci_msi_teardown_msi_irqs(dev);
list_for_each_entry_safe(entry, tmp, msi_list, list) { @@ -379,11 +384,6 @@ static void free_msi_irqs(struct pci_dev list_del(&entry->list); free_msi_entry(entry); } - - if (dev->msi_irq_groups) { - msi_destroy_sysfs(&dev->dev, dev->msi_irq_groups); - dev->msi_irq_groups = NULL; - } }
static void pci_intx_for_msi(struct pci_dev *dev, int enable)
From: Paolo Bonzini pbonzini@redhat.com
commit 3e067fd8503d6205aa0c1c8f48f6b209c592d19c upstream.
When UBSAN is enabled, the code emitted for the call to guest_pv_has includes a call to __ubsan_handle_load_invalid_value. objtool complains that this call happens with UACCESS enabled; to avoid the warning, pull the calls to user_access_begin into both arms of the "if" statement, after the check for guest_pv_has.
Reported-by: Stephen Rothwell sfr@canb.auug.org.au Cc: David Woodhouse dwmw2@infradead.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3227,9 +3227,6 @@ static void record_steal_time(struct kvm }
st = (struct kvm_steal_time __user *)ghc->hva; - if (!user_access_begin(st, sizeof(*st))) - return; - /* * Doing a TLB flush here, on the guest's behalf, can avoid * expensive IPIs. @@ -3238,6 +3235,9 @@ static void record_steal_time(struct kvm u8 st_preempted = 0; int err = -EFAULT;
+ if (!user_access_begin(st, sizeof(*st))) + return; + asm volatile("1: xchgb %0, %2\n" "xor %1, %1\n" "2:\n" @@ -3260,6 +3260,9 @@ static void record_steal_time(struct kvm if (!user_access_begin(st, sizeof(*st))) goto dirty; } else { + if (!user_access_begin(st, sizeof(*st))) + return; + unsafe_put_user(0, &st->preempted, out); vcpu->arch.st.preempted = 0; }
From: Michael Pratt mpratt@google.com
commit ca7752caeaa70bd31d1714af566c9809688544af upstream.
copy_process currently copies task_struct.posix_cputimers_work as-is. If a timer interrupt arrives while handling clone and before dup_task_struct completes then the child task will have:
1. posix_cputimers_work.scheduled = true 2. posix_cputimers_work.work queued.
copy_process clears task_struct.task_works, so (2) will have no effect and posix_cpu_timers_work will never run (not to mention it doesn't make sense for two tasks to share a common linked list).
Since posix_cpu_timers_work never runs, posix_cputimers_work.scheduled is never cleared. Since scheduled is set, future timer interrupts will skip scheduling work, with the ultimate result that the task will never receive timer expirations.
Together, the complete flow is:
1. Task 1 calls clone(), enters kernel. 2. Timer interrupt fires, schedules task work on Task 1. 2a. task_struct.posix_cputimers_work.scheduled = true 2b. task_struct.posix_cputimers_work.work added to task_struct.task_works. 3. dup_task_struct() copies Task 1 to Task 2. 4. copy_process() clears task_struct.task_works for Task 2. 5. Future timer interrupts on Task 2 see task_struct.posix_cputimers_work.scheduled = true and skip scheduling work.
Fix this by explicitly clearing contents of task_struct.posix_cputimers_work in copy_process(). This was never meant to be shared or inherited across tasks in the first place.
Fixes: 1fb497dd0030 ("posix-cpu-timers: Provide mechanisms to defer timer handling to task_work") Reported-by: Rhys Hiltner rhys@justin.tv Signed-off-by: Michael Pratt mpratt@google.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211101210615.716522-1-mpratt@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/linux/posix-timers.h | 2 ++ kernel/fork.c | 1 + kernel/time/posix-cpu-timers.c | 19 +++++++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-)
--- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -184,8 +184,10 @@ static inline void posix_cputimers_group #endif
#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK +void clear_posix_cputimers_work(struct task_struct *p); void posix_cputimers_init_work(void); #else +static inline void clear_posix_cputimers_work(struct task_struct *p) { } static inline void posix_cputimers_init_work(void) { } #endif
--- a/kernel/fork.c +++ b/kernel/fork.c @@ -2280,6 +2280,7 @@ static __latent_entropy struct task_stru p->pdeath_signal = 0; INIT_LIST_HEAD(&p->thread_group); p->task_works = NULL; + clear_posix_cputimers_work(p);
#ifdef CONFIG_KRETPROBES p->kretprobe_instances.first = NULL; --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -1159,13 +1159,28 @@ static void posix_cpu_timers_work(struct }
/* + * Clear existing posix CPU timers task work. + */ +void clear_posix_cputimers_work(struct task_struct *p) +{ + /* + * A copied work entry from the old task is not meaningful, clear it. + * N.B. init_task_work will not do this. + */ + memset(&p->posix_cputimers_work.work, 0, + sizeof(p->posix_cputimers_work.work)); + init_task_work(&p->posix_cputimers_work.work, + posix_cpu_timers_work); + p->posix_cputimers_work.scheduled = false; +} + +/* * Initialize posix CPU timers task work in init task. Out of line to * keep the callback static and to avoid header recursion hell. */ void __init posix_cputimers_init_work(void) { - init_task_work(¤t->posix_cputimers_work.work, - posix_cpu_timers_work); + clear_posix_cputimers_work(current); }
/*
From: Guo Ren guoren@linux.alibaba.com
commit 69ea463021be0d159ab30f96195fb0dd18ee2272 upstream.
When using "devm_request_threaded_irq(,,,,IRQF_ONESHOT,,)" in a driver, only the first interrupt is handled, and following interrupts are never delivered (initially reported in [1]).
That's because the RISC-V PLIC cannot EOI masked interrupts, as explained in the description of Interrupt Completion in the PLIC spec [2]:
<quote> The PLIC signals it has completed executing an interrupt handler by writing the interrupt ID it received from the claim to the claim/complete register. The PLIC does not check whether the completion ID is the same as the last claim ID for that target. If the completion ID does not match an interrupt source that *is currently enabled* for the target, the completion is silently ignored. </quote>
Re-enable the interrupt before completion if it has been masked during the handling, and remask it afterwards.
[1] http://lists.infradead.org/pipermail/linux-riscv/2021-July/007441.html [2] https://github.com/riscv/riscv-plic-spec/blob/8bc15a35d07c9edf7b5d23fec97283...
Fixes: bb0fed1c60cc ("irqchip/sifive-plic: Switch to fasteoi flow") Reported-by: Vincent Pelletier plr.vincent@gmail.com Tested-by: Nikita Shubin nikita.shubin@maquefel.me Signed-off-by: Guo Ren guoren@linux.alibaba.com Cc: stable@vger.kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Palmer Dabbelt palmer@dabbelt.com Cc: Atish Patra atish.patra@wdc.com Reviewed-by: Anup Patel anup@brainfault.org [maz: amended commit message] Signed-off-by: Marc Zyngier maz@kernel.org Link: https://lore.kernel.org/r/20211105094748.3894453-1-guoren@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/irqchip/irq-sifive-plic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -163,7 +163,13 @@ static void plic_irq_eoi(struct irq_data { struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
- writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); + if (irqd_irq_masked(d)) { + plic_irq_unmask(d); + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); + plic_irq_mask(d); + } else { + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); + } }
static struct irq_chip plic_chip = {
From: Jaegeuk Kim jaegeuk@kernel.org
commit 92d602bc7177325e7453189a22e0c8764ed3453e upstream.
We use inline_dentry which requires to allocate dentry page when adding a link. If we allow to reclaim memory from filesystem, we do down_read(&sbi->cp_rwsem) twice by f2fs_lock_op(). I think this should be okay, but how about stopping the lockdep complaint [1]?
f2fs_create() - f2fs_lock_op() - f2fs_do_add_link() - __f2fs_find_entry - f2fs_get_read_data_page() -> kswapd - shrink_node - f2fs_evict_inode - f2fs_lock_op()
[1]
fs_reclaim ){+.+.}-{0:0} : kswapd0: lock_acquire+0x114/0x394 kswapd0: __fs_reclaim_acquire+0x40/0x50 kswapd0: prepare_alloc_pages+0x94/0x1ec kswapd0: __alloc_pages_nodemask+0x78/0x1b0 kswapd0: pagecache_get_page+0x2e0/0x57c kswapd0: f2fs_get_read_data_page+0xc0/0x394 kswapd0: f2fs_find_data_page+0xa4/0x23c kswapd0: find_in_level+0x1a8/0x36c kswapd0: __f2fs_find_entry+0x70/0x100 kswapd0: f2fs_do_add_link+0x84/0x1ec kswapd0: f2fs_mkdir+0xe4/0x1e4 kswapd0: vfs_mkdir+0x110/0x1c0 kswapd0: do_mkdirat+0xa4/0x160 kswapd0: __arm64_sys_mkdirat+0x24/0x34 kswapd0: el0_svc_common.llvm.17258447499513131576+0xc4/0x1e8 kswapd0: do_el0_svc+0x28/0xa0 kswapd0: el0_svc+0x24/0x38 kswapd0: el0_sync_handler+0x88/0xec kswapd0: el0_sync+0x1c0/0x200 kswapd0: -> #1 ( &sbi->cp_rwsem ){++++}-{3:3} : kswapd0: lock_acquire+0x114/0x394 kswapd0: down_read+0x7c/0x98 kswapd0: f2fs_do_truncate_blocks+0x78/0x3dc kswapd0: f2fs_truncate+0xc8/0x128 kswapd0: f2fs_evict_inode+0x2b8/0x8b8 kswapd0: evict+0xd4/0x2f8 kswapd0: iput+0x1c0/0x258 kswapd0: do_unlinkat+0x170/0x2a0 kswapd0: __arm64_sys_unlinkat+0x4c/0x68 kswapd0: el0_svc_common.llvm.17258447499513131576+0xc4/0x1e8 kswapd0: do_el0_svc+0x28/0xa0 kswapd0: el0_svc+0x24/0x38 kswapd0: el0_sync_handler+0x88/0xec kswapd0: el0_sync+0x1c0/0x200
Cc: stable@vger.kernel.org Fixes: bdbc90fa55af ("f2fs: don't put dentry page in pagecache into highmem") Reviewed-by: Chao Yu chao@kernel.org Reviewed-by: Stanley Chu stanley.chu@mediatek.com Reviewed-by: Light Hsieh light.hsieh@mediatek.com Tested-by: Light Hsieh light.hsieh@mediatek.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/inode.c | 2 +- fs/f2fs/namei.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -527,7 +527,7 @@ make_now: inode->i_op = &f2fs_dir_inode_operations; inode->i_fop = &f2fs_dir_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - inode_nohighmem(inode); + mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); } else if (S_ISLNK(inode->i_mode)) { if (file_is_encrypt(inode)) inode->i_op = &f2fs_encrypted_symlink_inode_operations; --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -757,7 +757,7 @@ static int f2fs_mkdir(struct user_namesp inode->i_op = &f2fs_dir_inode_operations; inode->i_fop = &f2fs_dir_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; - inode_nohighmem(inode); + mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
set_inode_flag(inode, FI_INC_LINK); f2fs_lock_op(sbi);
From: Daeho Jeong daehojeong@google.com
commit 09631cf3234d32156e7cae32275f5a4144c683c5 upstream.
Need to include non-compressed blocks in compr_written_block to estimate average compression ratio more accurately.
Fixes: 5ac443e26a09 ("f2fs: add sysfs nodes to get runtime compression stat") Cc: stable@vger.kernel.org Signed-off-by: Daeho Jeong daehojeong@google.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/compress.c | 1 + 1 file changed, 1 insertion(+)
--- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1530,6 +1530,7 @@ int f2fs_write_multi_pages(struct compre if (cluster_may_compress(cc)) { err = f2fs_compress_pages(cc); if (err == -EAGAIN) { + add_compr_block_stat(cc->inode, cc->cluster_size); goto write; } else if (err) { f2fs_put_rpages_wbc(cc, wbc, true, 1);
From: Dongliang Mu mudongliangabcd@gmail.com
commit 5429c9dbc9025f9a166f64e22e3a69c94fd5b29b upstream.
if2fs_fill_super -> f2fs_build_segment_manager -> create_discard_cmd_control -> f2fs_start_discard_thread
It invokes kthread_run to create a thread and run issue_discard_thread.
However, if f2fs_build_node_manager fails, the control flow goes to free_nm and calls f2fs_destroy_node_manager. This function will free sbi->nm_info. However, if issue_discard_thread accesses sbi->nm_info after the deallocation, but before the f2fs_stop_discard_thread, it will cause UAF(Use-after-free).
-> f2fs_destroy_segment_manager -> destroy_discard_cmd_control -> f2fs_stop_discard_thread
Fix this by stopping discard thread before f2fs_destroy_node_manager.
Note that, the commit d6d2b491a82e1 introduces the call of f2fs_available_free_memory into issue_discard_thread.
Cc: stable@vger.kernel.org Fixes: d6d2b491a82e ("f2fs: allow to change discard policy based on cached discard cmds") Signed-off-by: Dongliang Mu mudongliangabcd@gmail.com Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/super.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -4352,6 +4352,8 @@ free_node_inode: free_stats: f2fs_destroy_stats(sbi); free_nm: + /* stop discard thread before destroying node manager */ + f2fs_stop_discard_thread(sbi); f2fs_destroy_node_manager(sbi); free_sm: f2fs_destroy_segment_manager(sbi);
From: Xiubo Li xiubli@redhat.com
commit 0e24421ac431e7af62d4acef6c638b85aae51728 upstream.
If the max_mds is decreased in a cephfs cluster, there is a window of time before the MDSs are removed. If a map goes out during this period, the mdsmap may show the decreased max_mds but still shows those MDSes as in or in the export target list.
Ensure that we don't fail the map decode in that case.
Cc: stable@vger.kernel.org URL: https://tracker.ceph.com/issues/52436 Fixes: d517b3983dd3 ("ceph: reconnect to the export targets on new mdsmaps") Signed-off-by: Xiubo Li xiubli@redhat.com Reviewed-by: Jeff Layton jlayton@kernel.org Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ceph/mdsmap.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -263,10 +263,6 @@ struct ceph_mdsmap *ceph_mdsmap_decode(v goto nomem; for (j = 0; j < num_export_targets; j++) { target = ceph_decode_32(&pexport_targets); - if (target >= m->possible_max_rank) { - err = -EIO; - goto corrupt; - } info->export_targets[j] = target; } } else {
From: Gao Xiang hsiangkao@linux.alibaba.com
commit 86432a6dca9bed79111990851df5756d3eb5f57c upstream.
There are pclusters in runtime marked with Z_EROFS_PCLUSTER_TAIL before actual I/O submission. Thus, the decompression chain can be extended if the following pcluster chain hooks such tail pcluster.
As the related comment mentioned, if some page is made of a hooked pcluster and another followed pcluster, it can be reused for in-place I/O (since I/O should be submitted anyway): _______________________________________________________________ | tail (partial) page | head (partial) page | |_____PRIMARY_HOOKED___|____________PRIMARY_FOLLOWED____________|
However, it's by no means safe to reuse as pagevec since if such PRIMARY_HOOKED pclusters finally move into bypass chain without I/O submission. It's somewhat hard to reproduce with LZ4 and I just found it (general protection fault) by ro_fsstressing a LZMA image for long time.
I'm going to actively clean up related code together with multi-page folio adaption in the next few months. Let's address it directly for easier backporting for now.
Call trace for reference: z_erofs_decompress_pcluster+0x10a/0x8a0 [erofs] z_erofs_decompress_queue.isra.36+0x3c/0x60 [erofs] z_erofs_runqueue+0x5f3/0x840 [erofs] z_erofs_readahead+0x1e8/0x320 [erofs] read_pages+0x91/0x270 page_cache_ra_unbounded+0x18b/0x240 filemap_get_pages+0x10a/0x5f0 filemap_read+0xa9/0x330 new_sync_read+0x11b/0x1a0 vfs_read+0xf1/0x190
Link: https://lore.kernel.org/r/20211103182006.4040-1-xiang@kernel.org Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support") Cc: stable@vger.kernel.org # 4.19+ Reviewed-by: Chao Yu chao@kernel.org Signed-off-by: Gao Xiang hsiangkao@linux.alibaba.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/erofs/zdata.c | 13 +++++++------ fs/erofs/zpvec.h | 13 ++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-)
--- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -373,8 +373,8 @@ static bool z_erofs_try_inplace_io(struc
/* callers must be with collection lock held */ static int z_erofs_attach_page(struct z_erofs_collector *clt, - struct page *page, - enum z_erofs_page_type type) + struct page *page, enum z_erofs_page_type type, + bool pvec_safereuse) { int ret;
@@ -384,9 +384,9 @@ static int z_erofs_attach_page(struct z_ z_erofs_try_inplace_io(clt, page)) return 0;
- ret = z_erofs_pagevec_enqueue(&clt->vector, page, type); + ret = z_erofs_pagevec_enqueue(&clt->vector, page, type, + pvec_safereuse); clt->cl->vcnt += (unsigned int)ret; - return ret ? 0 : -EAGAIN; }
@@ -729,7 +729,8 @@ hitted: tight &= (clt->mode >= COLLECT_PRIMARY_FOLLOWED);
retry: - err = z_erofs_attach_page(clt, page, page_type); + err = z_erofs_attach_page(clt, page, page_type, + clt->mode >= COLLECT_PRIMARY_FOLLOWED); /* should allocate an additional short-lived page for pagevec */ if (err == -EAGAIN) { struct page *const newpage = @@ -737,7 +738,7 @@ retry:
set_page_private(newpage, Z_EROFS_SHORTLIVED_PAGE); err = z_erofs_attach_page(clt, newpage, - Z_EROFS_PAGE_TYPE_EXCLUSIVE); + Z_EROFS_PAGE_TYPE_EXCLUSIVE, true); if (!err) goto retry; } --- a/fs/erofs/zpvec.h +++ b/fs/erofs/zpvec.h @@ -106,11 +106,18 @@ static inline void z_erofs_pagevec_ctor_
static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor, struct page *page, - enum z_erofs_page_type type) + enum z_erofs_page_type type, + bool pvec_safereuse) { - if (!ctor->next && type) - if (ctor->index + 1 == ctor->nr) + if (!ctor->next) { + /* some pages cannot be reused as pvec safely without I/O */ + if (type == Z_EROFS_PAGE_TYPE_EXCLUSIVE && !pvec_safereuse) + type = Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED; + + if (type != Z_EROFS_PAGE_TYPE_EXCLUSIVE && + ctor->index + 1 == ctor->nr) return false; + }
if (ctor->index >= ctor->nr) z_erofs_pagevec_ctor_pagedown(ctor, false);
From: Matthew Brost matthew.brost@intel.com
commit fc30a6764a54dea42291aeb7009bef7aa2fc1cd4 upstream.
Prior to this patch the blocked context counter was cleared on init_sched_state (used during registering a context & resets) which is incorrect. This state needs to be persistent or the counter can read the incorrect value resulting in scheduling never getting enabled again.
Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation") Signed-off-by: Matthew Brost matthew.brost@intel.com Reviewed-by: Daniel Vetter daniel.vetter@ffwll.ch Cc: stable@vger.kernel.org Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-2-matthew... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -152,7 +152,7 @@ static inline void init_sched_state(stru { /* Only should be called from guc_lrc_desc_pin() */ atomic_set(&ce->guc_sched_state_no_lock, 0); - ce->guc_state.sched_state = 0; + ce->guc_state.sched_state &= SCHED_STATE_BLOCKED_MASK; }
static inline bool
From: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com
commit 7607c44c157d343223510c8ffdf7206fdd2a6213 upstream.
When BLKDISCARD ioctl and data read race, the data read leaves stale page cache. To avoid the stale page cache, hold invalidate_lock of the block device file mapping. The stale page cache is observed when blktests test case block/009 is repeated hundreds of times.
This patch can be applied back to the stable kernel version v5.15.y with slight patch edit. Rework is required for older stable kernels.
Fixes: 351499a172c0 ("block: Invalidate cache on discard v2") Signed-off-by: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com Cc: stable@vger.kernel.org # v5.15 Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20211109104723.835533-2-shinichiro.kawasaki@wdc.co... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/ioctl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/block/ioctl.c +++ b/block/ioctl.c @@ -113,6 +113,7 @@ static int blk_ioctl_discard(struct bloc uint64_t range[2]; uint64_t start, len; struct request_queue *q = bdev_get_queue(bdev); + struct inode *inode = bdev->bd_inode; int err;
if (!(mode & FMODE_WRITE)) @@ -135,12 +136,17 @@ static int blk_ioctl_discard(struct bloc if (start + len > i_size_read(bdev->bd_inode)) return -EINVAL;
+ filemap_invalidate_lock(inode->i_mapping); err = truncate_bdev_range(bdev, mode, start, start + len - 1); if (err) - return err; + goto fail;
- return blkdev_issue_discard(bdev, start >> 9, len >> 9, - GFP_KERNEL, flags); + err = blkdev_issue_discard(bdev, start >> 9, len >> 9, + GFP_KERNEL, flags); + +fail: + filemap_invalidate_unlock(inode->i_mapping); + return err; }
static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
From: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com
commit 35e4c6c1a2fc2eb11b9306e95cda1fa06a511948 upstream.
When BLKZEROOUT ioctl and data read race, the data read leaves stale page cache. To avoid the stale page cache, hold invalidate_lock of the block device file mapping. The stale page cache is observed when blktests test case block/009 is modified to call "blkdiscard -z" command and repeated hundreds of times.
This patch can be applied back to the stable kernel version v5.15.y. Rework is required for older stable kernels.
Fixes: 22dd6d356628 ("block: invalidate the page cache when issuing BLKZEROOUT") Signed-off-by: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com Cc: stable@vger.kernel.org # v5.15 Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/20211109104723.835533-3-shinichiro.kawasaki@wdc.co... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/ioctl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/block/ioctl.c +++ b/block/ioctl.c @@ -154,6 +154,7 @@ static int blk_ioctl_zeroout(struct bloc { uint64_t range[2]; uint64_t start, end, len; + struct inode *inode = bdev->bd_inode; int err;
if (!(mode & FMODE_WRITE)) @@ -176,12 +177,17 @@ static int blk_ioctl_zeroout(struct bloc return -EINVAL;
/* Invalidate the page cache, including dirty pages */ + filemap_invalidate_lock(inode->i_mapping); err = truncate_bdev_range(bdev, mode, start, end); if (err) - return err; + goto fail;
- return blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL, - BLKDEV_ZERO_NOUNMAP); + err = blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL, + BLKDEV_ZERO_NOUNMAP); + +fail: + filemap_invalidate_unlock(inode->i_mapping); + return err; }
static int put_ushort(unsigned short __user *argp, unsigned short val)
From: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com
commit 86399ea071099ec8ee0a83ac9ad67f7df96a50ad upstream.
When BLKRESETZONE ioctl and data read race, the data read leaves stale page cache. The commit e5113505904e ("block: Discard page cache of zone reset target range") added page cache truncation to avoid stale page cache after the ioctl. However, the stale page cache still can be read during the reset zone operation for the ioctl. To avoid the stale page cache completely, hold invalidate_lock of the block device file mapping.
Fixes: e5113505904e ("block: Discard page cache of zone reset target range") Signed-off-by: Shin'ichiro Kawasaki shinichiro.kawasaki@wdc.com Cc: stable@vger.kernel.org # v5.15 Reviewed-by: Jan Kara jack@suse.cz Reviewed-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20211111085238.942492-1-shinichiro.kawasaki@wdc.co... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- block/blk-zoned.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
--- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -429,9 +429,10 @@ int blkdev_zone_mgmt_ioctl(struct block_ op = REQ_OP_ZONE_RESET;
/* Invalidate the page cache, including dirty pages. */ + filemap_invalidate_lock(bdev->bd_inode->i_mapping); ret = blkdev_truncate_zone_range(bdev, mode, &zrange); if (ret) - return ret; + goto fail; break; case BLKOPENZONE: op = REQ_OP_ZONE_OPEN; @@ -449,15 +450,9 @@ int blkdev_zone_mgmt_ioctl(struct block_ ret = blkdev_zone_mgmt(bdev, op, zrange.sector, zrange.nr_sectors, GFP_KERNEL);
- /* - * Invalidate the page cache again for zone reset: writes can only be - * direct for zoned devices so concurrent writes would not add any page - * to the page cache after/during reset. The page cache may be filled - * again due to concurrent reads though and dropping the pages for - * these is fine. - */ - if (!ret && cmd == BLKRESETZONE) - ret = blkdev_truncate_zone_range(bdev, mode, &zrange); +fail: + if (cmd == BLKRESETZONE) + filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
return ret; }
From: Marios Makassikis mmakassikis@freebox.fr
commit 78f1688a64cca77758ceb9b183088cf0054bfc82 upstream.
The validate_negotiate_info_req struct definition includes an extra field to access the data coming after the header. This causes the check in fsctl_validate_negotiate_info() to count the first element of the array twice. This in turn makes some valid requests fail, depending on whether they include padding or not.
Fixes: f7db8fd03a4b ("ksmbd: add validation in smb2_ioctl") Cc: stable@vger.kernel.org # v5.15 Acked-by: Namjae Jeon linkinjeon@kernel.org Acked-by: Hyunchul Lee hyc.lee@gmail.com Signed-off-by: Marios Makassikis mmakassikis@freebox.fr Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2pdu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -7319,7 +7319,7 @@ static int fsctl_validate_negotiate_info int ret = 0; int dialect;
- if (in_buf_len < sizeof(struct validate_negotiate_info_req) + + if (in_buf_len < offsetof(struct validate_negotiate_info_req, Dialects) + le16_to_cpu(neg_req->DialectCount) * sizeof(__le16)) return -EINVAL;
From: Namjae Jeon linkinjeon@kernel.org
commit b53ad8107ee873795ecb5039d46b5d5502d404f2 upstream.
When validating request length in ksmbd_check_message, 8byte alignment is not needed for compound request. It can cause wrong validation of request length.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3") Cc: stable@vger.kernel.org # v5.15 Acked-by: Hyunchul Lee hyc.lee@gmail.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ksmbd/smb2misc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
--- a/fs/ksmbd/smb2misc.c +++ b/fs/ksmbd/smb2misc.c @@ -358,12 +358,10 @@ int ksmbd_smb2_check_message(struct ksmb hdr = &pdu->hdr; }
- if (le32_to_cpu(hdr->NextCommand) > 0) { + if (le32_to_cpu(hdr->NextCommand) > 0) len = le32_to_cpu(hdr->NextCommand); - } else if (work->next_smb2_rcv_hdr_off) { + else if (work->next_smb2_rcv_hdr_off) len -= work->next_smb2_rcv_hdr_off; - len = round_up(len, 8); - }
if (check_smb2_hdr(hdr)) return 1;
From: Kishon Vijay Abraham I kishon@ti.com
commit 5c6c6d60e4b489308ae4da8424c869f7cc53cd12 upstream.
bcdma_get_*() checks if bchan is already allocated by checking if it has a NON NULL value. For the error cases, bchan will have error value and bcdma_get_*() considers this as already allocated (PASS) since the error values are NON NULL. This results in NULL pointer dereference error while de-referencing bchan.
Reset the value of bchan to NULL if a channel request fails.
CC: stable@vger.kernel.org Acked-by: Peter Ujfalusi peter.ujfalusi@gmail.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Link: https://lore.kernel.org/r/20211031032411.27235-2-kishon@ti.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/ti/k3-udma.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -1348,6 +1348,7 @@ static int bcdma_get_bchan(struct udma_c { struct udma_dev *ud = uc->ud; enum udma_tp_level tpl; + int ret;
if (uc->bchan) { dev_dbg(ud->dev, "chan%d: already have bchan%d allocated\n", @@ -1365,8 +1366,11 @@ static int bcdma_get_bchan(struct udma_c tpl = ud->bchan_tpl.levels - 1;
uc->bchan = __udma_reserve_bchan(ud, tpl, -1); - if (IS_ERR(uc->bchan)) - return PTR_ERR(uc->bchan); + if (IS_ERR(uc->bchan)) { + ret = PTR_ERR(uc->bchan); + uc->bchan = NULL; + return ret; + }
uc->tchan = uc->bchan;
From: Kishon Vijay Abraham I kishon@ti.com
commit eb91224e47ec33a0a32c9be0ec0fcb3433e555fd upstream.
udma_get_*() checks if rchan/tchan/rflow is already allocated by checking if it has a NON NULL value. For the error cases, rchan/tchan/rflow will have error value and udma_get_*() considers this as already allocated (PASS) since the error values are NON NULL. This results in NULL pointer dereference error while de-referencing rchan/tchan/rflow.
Reset the value of rchan/tchan/rflow to NULL if a channel request fails.
CC: stable@vger.kernel.org Acked-by: Peter Ujfalusi peter.ujfalusi@gmail.com Signed-off-by: Kishon Vijay Abraham I kishon@ti.com Link: https://lore.kernel.org/r/20211031032411.27235-3-kishon@ti.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/ti/k3-udma.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)
--- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -1380,6 +1380,7 @@ static int bcdma_get_bchan(struct udma_c static int udma_get_tchan(struct udma_chan *uc) { struct udma_dev *ud = uc->ud; + int ret;
if (uc->tchan) { dev_dbg(ud->dev, "chan%d: already have tchan%d allocated\n", @@ -1394,8 +1395,11 @@ static int udma_get_tchan(struct udma_ch */ uc->tchan = __udma_reserve_tchan(ud, uc->config.channel_tpl, uc->config.mapped_channel_id); - if (IS_ERR(uc->tchan)) - return PTR_ERR(uc->tchan); + if (IS_ERR(uc->tchan)) { + ret = PTR_ERR(uc->tchan); + uc->tchan = NULL; + return ret; + }
if (ud->tflow_cnt) { int tflow_id; @@ -1425,6 +1429,7 @@ static int udma_get_tchan(struct udma_ch static int udma_get_rchan(struct udma_chan *uc) { struct udma_dev *ud = uc->ud; + int ret;
if (uc->rchan) { dev_dbg(ud->dev, "chan%d: already have rchan%d allocated\n", @@ -1439,8 +1444,13 @@ static int udma_get_rchan(struct udma_ch */ uc->rchan = __udma_reserve_rchan(ud, uc->config.channel_tpl, uc->config.mapped_channel_id); + if (IS_ERR(uc->rchan)) { + ret = PTR_ERR(uc->rchan); + uc->rchan = NULL; + return ret; + }
- return PTR_ERR_OR_ZERO(uc->rchan); + return 0; }
static int udma_get_chan_pair(struct udma_chan *uc) @@ -1494,6 +1504,7 @@ static int udma_get_chan_pair(struct udm static int udma_get_rflow(struct udma_chan *uc, int flow_id) { struct udma_dev *ud = uc->ud; + int ret;
if (!uc->rchan) { dev_err(ud->dev, "chan%d: does not have rchan??\n", uc->id); @@ -1507,8 +1518,13 @@ static int udma_get_rflow(struct udma_ch }
uc->rflow = __udma_get_rflow(ud, flow_id); + if (IS_ERR(uc->rflow)) { + ret = PTR_ERR(uc->rflow); + uc->rflow = NULL; + return ret; + }
- return PTR_ERR_OR_ZERO(uc->rflow); + return 0; }
static void bcdma_put_bchan(struct udma_chan *uc)
From: Anatolij Gustschin agust@denx.de
commit adec566b05288f2787a1f88dbaf77ed8b0c644fa upstream.
memset() and memcpy() on an MMIO region like here results in a lockup at startup on mpc5200 platform (since this first happens during probing of the ATA and Ethernet drivers). Use memset_io() and memcpy_toio() instead.
Fixes: 2f9ea1bde0d1 ("bestcomm: core bestcomm support for Freescale MPC5200") Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Anatolij Gustschin agust@denx.de Link: https://lore.kernel.org/r/20211014094012.21286-1-agust@denx.de Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/dma/bestcomm/ata.c | 2 +- drivers/dma/bestcomm/bestcomm.c | 22 +++++++++++----------- drivers/dma/bestcomm/fec.c | 4 ++-- drivers/dma/bestcomm/gen_bd.c | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-)
--- a/drivers/dma/bestcomm/ata.c +++ b/drivers/dma/bestcomm/ata.c @@ -133,7 +133,7 @@ void bcom_ata_reset_bd(struct bcom_task struct bcom_ata_var *var;
/* Reset all BD */ - memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); + memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
tsk->index = 0; tsk->outdex = 0; --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -95,7 +95,7 @@ bcom_task_alloc(int bd_count, int bd_siz tsk->bd = bcom_sram_alloc(bd_count * bd_size, 4, &tsk->bd_pa); if (!tsk->bd) goto error; - memset(tsk->bd, 0x00, bd_count * bd_size); + memset_io(tsk->bd, 0x00, bd_count * bd_size);
tsk->num_bd = bd_count; tsk->bd_size = bd_size; @@ -186,16 +186,16 @@ bcom_load_image(int task, u32 *task_imag inc = bcom_task_inc(task);
/* Clear & copy */ - memset(var, 0x00, BCOM_VAR_SIZE); - memset(inc, 0x00, BCOM_INC_SIZE); + memset_io(var, 0x00, BCOM_VAR_SIZE); + memset_io(inc, 0x00, BCOM_INC_SIZE);
desc_src = (u32 *)(hdr + 1); var_src = desc_src + hdr->desc_size; inc_src = var_src + hdr->var_size;
- memcpy(desc, desc_src, hdr->desc_size * sizeof(u32)); - memcpy(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32)); - memcpy(inc, inc_src, hdr->inc_size * sizeof(u32)); + memcpy_toio(desc, desc_src, hdr->desc_size * sizeof(u32)); + memcpy_toio(var + hdr->first_var, var_src, hdr->var_size * sizeof(u32)); + memcpy_toio(inc, inc_src, hdr->inc_size * sizeof(u32));
return 0; } @@ -302,13 +302,13 @@ static int bcom_engine_init(void) return -ENOMEM; }
- memset(bcom_eng->tdt, 0x00, tdt_size); - memset(bcom_eng->ctx, 0x00, ctx_size); - memset(bcom_eng->var, 0x00, var_size); - memset(bcom_eng->fdt, 0x00, fdt_size); + memset_io(bcom_eng->tdt, 0x00, tdt_size); + memset_io(bcom_eng->ctx, 0x00, ctx_size); + memset_io(bcom_eng->var, 0x00, var_size); + memset_io(bcom_eng->fdt, 0x00, fdt_size);
/* Copy the FDT for the EU#3 */ - memcpy(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops)); + memcpy_toio(&bcom_eng->fdt[48], fdt_ops, sizeof(fdt_ops));
/* Initialize Task base structure */ for (task=0; task<BCOM_MAX_TASKS; task++) --- a/drivers/dma/bestcomm/fec.c +++ b/drivers/dma/bestcomm/fec.c @@ -140,7 +140,7 @@ bcom_fec_rx_reset(struct bcom_task *tsk) tsk->index = 0; tsk->outdex = 0;
- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); + memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */ bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_RX_BD_PRAGMA); @@ -241,7 +241,7 @@ bcom_fec_tx_reset(struct bcom_task *tsk) tsk->index = 0; tsk->outdex = 0;
- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); + memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */ bcom_set_task_pragma(tsk->tasknum, BCOM_FEC_TX_BD_PRAGMA); --- a/drivers/dma/bestcomm/gen_bd.c +++ b/drivers/dma/bestcomm/gen_bd.c @@ -142,7 +142,7 @@ bcom_gen_bd_rx_reset(struct bcom_task *t tsk->index = 0; tsk->outdex = 0;
- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); + memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */ bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_RX_BD_PRAGMA); @@ -226,7 +226,7 @@ bcom_gen_bd_tx_reset(struct bcom_task *t tsk->index = 0; tsk->outdex = 0;
- memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); + memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size);
/* Configure some stuff */ bcom_set_task_pragma(tsk->tasknum, BCOM_GEN_TX_BD_PRAGMA);
From: Daniel Borkmann daniel@iogearbox.net
[ Upstream commit 3dc20f4762c62d3b3f0940644881ed818aa7b2f5 ]
Currently, it is not possible to migrate a neighbor entry between NUD_PERMANENT state and NTF_USE flag with a dynamic NUD state from a user space control plane. Similarly, it is not possible to add/remove NTF_EXT_LEARNED flag from an existing neighbor entry in combination with NTF_USE flag.
This is due to the latter directly calling into neigh_event_send() without any meta data updates as happening in __neigh_update(). Thus, to enable this use case, extend the latter with a NEIGH_UPDATE_F_USE flag where we break the NUD_PERMANENT state in particular so that a latter neigh_event_send() is able to re-resolve a neighbor entry.
Before fix, NUD_PERMANENT -> NUD_* & NTF_USE:
# ./ip/ip n replace 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a PERMANENT [...] # ./ip/ip n replace 192.168.178.30 dev enp5s0 use extern_learn # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a PERMANENT [...]
As can be seen, despite the admin-triggered replace, the entry remains in the NUD_PERMANENT state.
After fix, NUD_PERMANENT -> NUD_* & NTF_USE:
# ./ip/ip n replace 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a PERMANENT [...] # ./ip/ip n replace 192.168.178.30 dev enp5s0 use extern_learn # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a extern_learn REACHABLE [...] # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a extern_learn STALE [...] # ./ip/ip n replace 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a PERMANENT [...]
After the fix, the admin-triggered replace switches to a dynamic state from the NTF_USE flag which triggered a new neighbor resolution. Likewise, we can transition back from there, if needed, into NUD_PERMANENT.
Similar before/after behavior can be observed for below transitions:
Before fix, NTF_USE -> NTF_USE | NTF_EXT_LEARNED -> NTF_USE:
# ./ip/ip n replace 192.168.178.30 dev enp5s0 use # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a REACHABLE [...] # ./ip/ip n replace 192.168.178.30 dev enp5s0 use extern_learn # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a REACHABLE [...]
After fix, NTF_USE -> NTF_USE | NTF_EXT_LEARNED -> NTF_USE:
# ./ip/ip n replace 192.168.178.30 dev enp5s0 use # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a REACHABLE [...] # ./ip/ip n replace 192.168.178.30 dev enp5s0 use extern_learn # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a extern_learn REACHABLE [...] # ./ip/ip n replace 192.168.178.30 dev enp5s0 use # ./ip/ip n 192.168.178.30 dev enp5s0 lladdr f4:8c:50:5e:71:9a REACHABLE [..]
Signed-off-by: Daniel Borkmann daniel@iogearbox.net Acked-by: Roopa Prabhu roopa@nvidia.com Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/neighbour.h | 1 + net/core/neighbour.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 990f9b1d17092..d5767e25509cc 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -253,6 +253,7 @@ static inline void *neighbour_priv(const struct neighbour *n) #define NEIGH_UPDATE_F_OVERRIDE 0x00000001 #define NEIGH_UPDATE_F_WEAK_OVERRIDE 0x00000002 #define NEIGH_UPDATE_F_OVERRIDE_ISROUTER 0x00000004 +#define NEIGH_UPDATE_F_USE 0x10000000 #define NEIGH_UPDATE_F_EXT_LEARNED 0x20000000 #define NEIGH_UPDATE_F_ISROUTER 0x40000000 #define NEIGH_UPDATE_F_ADMIN 0x80000000 diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 8457d5f97022b..3e58037a8ae6f 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1217,7 +1217,7 @@ static void neigh_update_hhs(struct neighbour *neigh) lladdr instead of overriding it if it is different. NEIGH_UPDATE_F_ADMIN means that the change is administrative. - + NEIGH_UPDATE_F_USE means that the entry is user triggered. NEIGH_UPDATE_F_OVERRIDE_ISROUTER allows to override existing NTF_ROUTER flag. NEIGH_UPDATE_F_ISROUTER indicates if the neighbour is known as @@ -1255,6 +1255,12 @@ static int __neigh_update(struct neighbour *neigh, const u8 *lladdr, goto out;
ext_learn_change = neigh_update_ext_learned(neigh, flags, ¬ify); + if (flags & NEIGH_UPDATE_F_USE) { + new = old & ~NUD_PERMANENT; + neigh->nud_state = new; + err = 0; + goto out; + }
if (!(new & NUD_VALID)) { neigh_del_timer(neigh); @@ -1963,22 +1969,20 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh,
if (protocol) neigh->protocol = protocol; - if (ndm->ndm_flags & NTF_EXT_LEARNED) flags |= NEIGH_UPDATE_F_EXT_LEARNED; - if (ndm->ndm_flags & NTF_ROUTER) flags |= NEIGH_UPDATE_F_ISROUTER; + if (ndm->ndm_flags & NTF_USE) + flags |= NEIGH_UPDATE_F_USE;
- if (ndm->ndm_flags & NTF_USE) { + err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags, + NETLINK_CB(skb).portid, extack); + if (!err && ndm->ndm_flags & NTF_USE) { neigh_event_send(neigh, NULL); err = 0; - } else - err = __neigh_update(neigh, lladdr, ndm->ndm_state, flags, - NETLINK_CB(skb).portid, extack); - + } neigh_release(neigh); - out: return err; }
From: Dominique Martinet asmadeus@codewreck.org
commit 27eb4c3144f7a5ebef3c9a261d80cb3e1fa784dc upstream.
Link: https://lkml.kernel.org/r/99338965-d36c-886e-cd0e-1d8fff2b4746@gmail.com Reported-by: syzbot+06472778c97ed94af66d@syzkaller.appspotmail.com Cc: stable@vger.kernel.org Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/9p/client.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/net/9p/client.c +++ b/net/9p/client.c @@ -541,6 +541,8 @@ static int p9_check_errors(struct p9_cli kfree(ename); } else { err = p9pdu_readf(&req->rc, c->proto_version, "d", &ecode); + if (err) + goto out_err; err = -ecode;
p9_debug(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
From: Matthew Wilcox (Oracle) willy@infradead.org
commit d417b49fff3e2f21043c834841e8623a6098741d upstream.
It is not safe to check page->index without holding the page lock. It can be changed if the page is moved between the swap cache and the page cache for a shmem file, for example. There is a VM_BUG_ON below which checks page->index is correct after taking the page lock.
Link: https://lkml.kernel.org/r/20210818144932.940640-1-willy@infradead.org Fixes: 5c211ba29deb ("mm: add and use find_lock_entries") Signed-off-by: Matthew Wilcox (Oracle) willy@infradead.org Reported-by: syzbot+c87be4f669d920c76330@syzkaller.appspotmail.com Cc: Hugh Dickins hughd@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/filemap.c | 1 - 1 file changed, 1 deletion(-)
--- a/mm/filemap.c +++ b/mm/filemap.c @@ -2093,7 +2093,6 @@ unsigned find_lock_entries(struct addres if (!xa_is_value(page)) { if (page->index < start) goto put; - VM_BUG_ON_PAGE(page->index != xas.xa_index, page); if (page->index + thp_nr_pages(page) - 1 > end) goto put; if (!trylock_page(page))
From: Vasily Averin vvs@virtuozzo.com
commit a4ebf1b6ca1e011289677239a2a361fde4a88076 upstream.
Memory cgroup charging allows killed or exiting tasks to exceed the hard limit. It is assumed that the amount of the memory charged by those tasks is bound and most of the memory will get released while the task is exiting. This is resembling a heuristic for the global OOM situation when tasks get access to memory reserves. There is no global memory shortage at the memcg level so the memcg heuristic is more relieved.
The above assumption is overly optimistic though. E.g. vmalloc can scale to really large requests and the heuristic would allow that. We used to have an early break in the vmalloc allocator for killed tasks but this has been reverted by commit b8c8a338f75e ("Revert "vmalloc: back off when the current task is killed""). There are likely other similar code paths which do not check for fatal signals in an allocation&charge loop. Also there are some kernel objects charged to a memcg which are not bound to a process life time.
It has been observed that it is not really hard to trigger these bypasses and cause global OOM situation.
One potential way to address these runaways would be to limit the amount of excess (similar to the global OOM with limited oom reserves). This is certainly possible but it is not really clear how much of an excess is desirable and still protects from global OOMs as that would have to consider the overall memcg configuration.
This patch is addressing the problem by removing the heuristic altogether. Bypass is only allowed for requests which either cannot fail or where the failure is not desirable while excess should be still limited (e.g. atomic requests). Implementation wise a killed or dying task fails to charge if it has passed the OOM killer stage. That should give all forms of reclaim chance to restore the limit before the failure (ENOMEM) and tell the caller to back off.
In addition, this patch renames should_force_charge() helper to task_is_dying() because now its use is not associated witch forced charging.
This patch depends on pagefault_out_of_memory() to not trigger out_of_memory(), because then a memcg failure can unwind to VM_FAULT_OOM and cause a global OOM killer.
Link: https://lkml.kernel.org/r/8f5cebbb-06da-4902-91f0-6566fc4b4203@virtuozzo.com Signed-off-by: Vasily Averin vvs@virtuozzo.com Suggested-by: Michal Hocko mhocko@suse.com Acked-by: Michal Hocko mhocko@suse.com Cc: Johannes Weiner hannes@cmpxchg.org Cc: Vladimir Davydov vdavydov.dev@gmail.com Cc: Roman Gushchin guro@fb.com Cc: Uladzislau Rezki urezki@gmail.com Cc: Vlastimil Babka vbabka@suse.cz Cc: Shakeel Butt shakeelb@google.com Cc: Mel Gorman mgorman@techsingularity.net Cc: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp 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/memcontrol.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-)
--- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -239,7 +239,7 @@ enum res_type { iter != NULL; \ iter = mem_cgroup_iter(NULL, iter, NULL))
-static inline bool should_force_charge(void) +static inline bool task_is_dying(void) { return tsk_is_oom_victim(current) || fatal_signal_pending(current) || (current->flags & PF_EXITING); @@ -1575,7 +1575,7 @@ static bool mem_cgroup_out_of_memory(str * A few threads which were not waiting at mutex_lock_killable() can * fail to bail out. Therefore, check again after holding oom_lock. */ - ret = should_force_charge() || out_of_memory(&oc); + ret = task_is_dying() || out_of_memory(&oc);
unlock: mutex_unlock(&oom_lock); @@ -2530,6 +2530,7 @@ static int try_charge_memcg(struct mem_c struct page_counter *counter; enum oom_status oom_status; unsigned long nr_reclaimed; + bool passed_oom = false; bool may_swap = true; bool drained = false; unsigned long pflags; @@ -2565,15 +2566,6 @@ retry: goto force;
/* - * Unlike in global OOM situations, memcg is not in a physical - * memory shortage. Allow dying and OOM-killed tasks to - * bypass the last charges so that they can exit quickly and - * free their memory. - */ - if (unlikely(should_force_charge())) - goto force; - - /* * Prevent unbounded recursion when reclaim operations need to * allocate memory. This might exceed the limits temporarily, * but we prefer facilitating memory reclaim and getting back @@ -2630,8 +2622,9 @@ retry: if (gfp_mask & __GFP_RETRY_MAYFAIL) goto nomem;
- if (fatal_signal_pending(current)) - goto force; + /* Avoid endless loop for tasks bypassed by the oom killer */ + if (passed_oom && task_is_dying()) + goto nomem;
/* * keep retrying as long as the memcg oom killer is able to make @@ -2640,14 +2633,10 @@ retry: */ oom_status = mem_cgroup_oom(mem_over_limit, gfp_mask, get_order(nr_pages * PAGE_SIZE)); - switch (oom_status) { - case OOM_SUCCESS: + if (oom_status == OOM_SUCCESS) { + passed_oom = true; nr_retries = MAX_RECLAIM_RETRIES; goto retry; - case OOM_FAILED: - goto force; - default: - goto nomem; } nomem: if (!(gfp_mask & __GFP_NOFAIL))
From: Vasily Averin vvs@virtuozzo.com
commit 0b28179a6138a5edd9d82ad2687c05b3773c387b upstream.
Patch series "memcg: prohibit unconditional exceeding the limit of dying tasks", v3.
Memory cgroup charging allows killed or exiting tasks to exceed the hard limit. It can be misused and allowed to trigger global OOM from inside a memcg-limited container. On the other hand if memcg fails allocation, called from inside #PF handler it triggers global OOM from inside pagefault_out_of_memory().
To prevent these problems this patchset: (a) removes execution of out_of_memory() from pagefault_out_of_memory(), becasue nobody can explain why it is necessary. (b) allow memcg to fail allocation of dying/killed tasks.
This patch (of 3):
Any allocation failure during the #PF path will return with VM_FAULT_OOM which in turn results in pagefault_out_of_memory which in turn executes out_out_memory() and can kill a random task.
An allocation might fail when the current task is the oom victim and there are no memory reserves left. The OOM killer is already handled at the page allocator level for the global OOM and at the charging level for the memcg one. Both have much more information about the scope of allocation/charge request. This means that either the OOM killer has been invoked properly and didn't lead to the allocation success or it has been skipped because it couldn't have been invoked. In both cases triggering it from here is pointless and even harmful.
It makes much more sense to let the killed task die rather than to wake up an eternally hungry oom-killer and send him to choose a fatter victim for breakfast.
Link: https://lkml.kernel.org/r/0828a149-786e-7c06-b70a-52d086818ea3@virtuozzo.com Signed-off-by: Vasily Averin vvs@virtuozzo.com Suggested-by: Michal Hocko mhocko@suse.com Acked-by: Michal Hocko mhocko@suse.com Cc: Johannes Weiner hannes@cmpxchg.org Cc: Mel Gorman mgorman@techsingularity.net Cc: Roman Gushchin guro@fb.com Cc: Shakeel Butt shakeelb@google.com Cc: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Cc: Uladzislau Rezki urezki@gmail.com Cc: Vladimir Davydov vdavydov.dev@gmail.com Cc: Vlastimil Babka vbabka@suse.cz 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/oom_kill.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -1137,6 +1137,9 @@ void pagefault_out_of_memory(void) if (mem_cgroup_oom_synchronize(true)) return;
+ if (fatal_signal_pending(current)) + return; + if (!mutex_trylock(&oom_lock)) return; out_of_memory(&oc);
From: Michal Hocko mhocko@suse.com
commit 60e2793d440a3ec95abb5d6d4fc034a4b480472d upstream.
Any allocation failure during the #PF path will return with VM_FAULT_OOM which in turn results in pagefault_out_of_memory. This can happen for 2 different reasons. a) Memcg is out of memory and we rely on mem_cgroup_oom_synchronize to perform the memcg OOM handling or b) normal allocation fails.
The latter is quite problematic because allocation paths already trigger out_of_memory and the page allocator tries really hard to not fail allocations. Anyway, if the OOM killer has been already invoked there is no reason to invoke it again from the #PF path. Especially when the OOM condition might be gone by that time and we have no way to find out other than allocate.
Moreover if the allocation failed and the OOM killer hasn't been invoked then we are unlikely to do the right thing from the #PF context because we have already lost the allocation context and restictions and therefore might oom kill a task from a different NUMA domain.
This all suggests that there is no legitimate reason to trigger out_of_memory from pagefault_out_of_memory so drop it. Just to be sure that no #PF path returns with VM_FAULT_OOM without allocation print a warning that this is happening before we restart the #PF.
[VvS: #PF allocation can hit into limit of cgroup v1 kmem controller. This is a local problem related to memcg, however, it causes unnecessary global OOM kills that are repeated over and over again and escalate into a real disaster. This has been broken since kmem accounting has been introduced for cgroup v1 (3.8). There was no kmem specific reclaim for the separate limit so the only way to handle kmem hard limit was to return with ENOMEM. In upstream the problem will be fixed by removing the outdated kmem limit, however stable and LTS kernels cannot do it and are still affected. This patch fixes the problem and should be backported into stable/LTS.]
Link: https://lkml.kernel.org/r/f5fd8dd8-0ad4-c524-5f65-920b01972a42@virtuozzo.com Signed-off-by: Michal Hocko mhocko@suse.com Signed-off-by: Vasily Averin vvs@virtuozzo.com Acked-by: Michal Hocko mhocko@suse.com Cc: Johannes Weiner hannes@cmpxchg.org Cc: Mel Gorman mgorman@techsingularity.net Cc: Roman Gushchin guro@fb.com Cc: Shakeel Butt shakeelb@google.com Cc: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Cc: Uladzislau Rezki urezki@gmail.com Cc: Vladimir Davydov vdavydov.dev@gmail.com Cc: Vlastimil Babka vbabka@suse.cz 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/oom_kill.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-)
--- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -1120,19 +1120,15 @@ bool out_of_memory(struct oom_control *o }
/* - * The pagefault handler calls here because it is out of memory, so kill a - * memory-hogging task. If oom_lock is held by somebody else, a parallel oom - * killing is already in progress so do nothing. + * The pagefault handler calls here because some allocation has failed. We have + * to take care of the memcg OOM here because this is the only safe context without + * any locks held but let the oom killer triggered from the allocation context care + * about the global OOM. */ void pagefault_out_of_memory(void) { - struct oom_control oc = { - .zonelist = NULL, - .nodemask = NULL, - .memcg = NULL, - .gfp_mask = 0, - .order = 0, - }; + static DEFINE_RATELIMIT_STATE(pfoom_rs, DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST);
if (mem_cgroup_oom_synchronize(true)) return; @@ -1140,10 +1136,8 @@ void pagefault_out_of_memory(void) if (fatal_signal_pending(current)) return;
- if (!mutex_trylock(&oom_lock)) - return; - out_of_memory(&oc); - mutex_unlock(&oom_lock); + if (__ratelimit(&pfoom_rs)) + pr_warn("Huh VM_FAULT_OOM leaked out to the #PF handler. Retrying PF\n"); }
SYSCALL_DEFINE2(process_mrelease, int, pidfd, unsigned int, flags)
From: Rongwei Wang rongwei.wang@linux.alibaba.com
commit 55fc0d91746759c71bc165bba62a2db64ac98e35 upstream.
Patch series "fix two bugs for file THP".
This patch (of 2):
Transparent huge page has supported read-only non-shmem files. The file- backed THP is collapsed by khugepaged and truncated when written (for shared libraries).
However, there is a race when multiple writers truncate the same page cache concurrently.
In that case, subpage(s) of file THP can be revealed by find_get_entry in truncate_inode_pages_range, which will trigger PageTail BUG_ON in truncate_inode_page, as follows:
page:000000009e420ff2 refcount:1 mapcount:0 mapping:0000000000000000 index:0x7ff pfn:0x50c3ff head:0000000075ff816d order:9 compound_mapcount:0 compound_pincount:0 flags: 0x37fffe0000010815(locked|uptodate|lru|arch_1|head) raw: 37fffe0000000000 fffffe0013108001 dead000000000122 dead000000000400 raw: 0000000000000001 0000000000000000 00000000ffffffff 0000000000000000 head: 37fffe0000010815 fffffe001066bd48 ffff000404183c20 0000000000000000 head: 0000000000000600 0000000000000000 00000001ffffffff ffff000c0345a000 page dumped because: VM_BUG_ON_PAGE(PageTail(page)) ------------[ cut here ]------------ kernel BUG at mm/truncate.c:213! Internal error: Oops - BUG: 0 [#1] SMP Modules linked in: xfs(E) libcrc32c(E) rfkill(E) ... CPU: 14 PID: 11394 Comm: check_madvise_d Kdump: ... Hardware name: ECS, BIOS 0.0.0 02/06/2015 pstate: 60400005 (nZCv daif +PAN -UAO -TCO BTYPE=--) Call trace: truncate_inode_page+0x64/0x70 truncate_inode_pages_range+0x550/0x7e4 truncate_pagecache+0x58/0x80 do_dentry_open+0x1e4/0x3c0 vfs_open+0x38/0x44 do_open+0x1f0/0x310 path_openat+0x114/0x1dc do_filp_open+0x84/0x134 do_sys_openat2+0xbc/0x164 __arm64_sys_openat+0x74/0xc0 el0_svc_common.constprop.0+0x88/0x220 do_el0_svc+0x30/0xa0 el0_svc+0x20/0x30 el0_sync_handler+0x1a4/0x1b0 el0_sync+0x180/0x1c0 Code: aa0103e0 900061e1 910ec021 9400d300 (d4210000)
This patch mainly to lock filemap when one enter truncate_pagecache(), avoiding truncating the same page cache concurrently.
Link: https://lkml.kernel.org/r/20211025092134.18562-1-rongwei.wang@linux.alibaba.... Link: https://lkml.kernel.org/r/20211025092134.18562-2-rongwei.wang@linux.alibaba.... Fixes: eb6ecbed0aa2 ("mm, thp: relax the VM_DENYWRITE constraint on file-backed THPs") Signed-off-by: Xu Yu xuyu@linux.alibaba.com Signed-off-by: Rongwei Wang rongwei.wang@linux.alibaba.com Suggested-by: Matthew Wilcox (Oracle) willy@infradead.org Tested-by: Song Liu song@kernel.org Cc: Collin Fijalkovich cfijalkovich@google.com Cc: Hugh Dickins hughd@google.com Cc: Mike Kravetz mike.kravetz@oracle.com Cc: William Kucharski william.kucharski@oracle.com Cc: Yang Shi shy828301@gmail.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 --- fs/open.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/open.c +++ b/fs/open.c @@ -856,8 +856,11 @@ static int do_dentry_open(struct file *f * of THPs into the page cache will fail. */ smp_mb(); - if (filemap_nr_thps(inode->i_mapping)) + if (filemap_nr_thps(inode->i_mapping)) { + filemap_invalidate_lock(inode->i_mapping); truncate_pagecache(inode, 0); + filemap_invalidate_unlock(inode->i_mapping); + } }
return 0;
From: Rongwei Wang rongwei.wang@linux.alibaba.com
commit 8468e937df1f31411d1e127fa38db064af051fe5 upstream.
When truncating pagecache on file THP, the private pages of a process should not be unmapped mapping. This incorrect behavior on a dynamic shared libraries which will cause related processes to happen core dump.
A simple test for a DSO (Prerequisite is the DSO mapped in file THP):
int main(int argc, char *argv[]) { int fd;
fd = open(argv[1], O_WRONLY); if (fd < 0) { perror("open"); }
close(fd); return 0; }
The test only to open a target DSO, and do nothing. But this operation will lead one or more process to happen core dump. This patch mainly to fix this bug.
Link: https://lkml.kernel.org/r/20211025092134.18562-3-rongwei.wang@linux.alibaba.... Fixes: eb6ecbed0aa2 ("mm, thp: relax the VM_DENYWRITE constraint on file-backed THPs") Signed-off-by: Rongwei Wang rongwei.wang@linux.alibaba.com Tested-by: Xu Yu xuyu@linux.alibaba.com Cc: Matthew Wilcox (Oracle) willy@infradead.org Cc: Song Liu song@kernel.org Cc: William Kucharski william.kucharski@oracle.com Cc: Hugh Dickins hughd@google.com Cc: Yang Shi shy828301@gmail.com Cc: Mike Kravetz mike.kravetz@oracle.com Cc: Collin Fijalkovich cfijalkovich@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 --- fs/open.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/fs/open.c +++ b/fs/open.c @@ -857,8 +857,17 @@ static int do_dentry_open(struct file *f */ smp_mb(); if (filemap_nr_thps(inode->i_mapping)) { + struct address_space *mapping = inode->i_mapping; + filemap_invalidate_lock(inode->i_mapping); - truncate_pagecache(inode, 0); + /* + * unmap_mapping_range just need to be called once + * here, because the private pages is not need to be + * unmapped mapping (e.g. data segment of dynamic + * shared libraries here). + */ + unmap_mapping_range(mapping, 0, 0, 0); + truncate_inode_pages(mapping, 0); filemap_invalidate_unlock(inode->i_mapping); } }
From: Jack Andersen jackoalan@gmail.com
commit 313c84b5ae4104e48c661d5d706f9f4c425fd50f upstream.
This patch extends the DLN2 driver; adding cell for adc_dln2 module.
The original patch[1] fell through the cracks when the driver was added so ADC has never actually been usable. That patch did not have ACPI support which was added in v5.9, so the oldest supported version this current patch can be backported to is 5.10.
[1] https://www.spinics.net/lists/linux-iio/msg33975.html
Cc: stable@vger.kernel.org # 5.10+ Signed-off-by: Jack Andersen jackoalan@gmail.com Signed-off-by: Noralf Trønnes noralf@tronnes.org Signed-off-by: Lee Jones lee.jones@linaro.org Link: https://lore.kernel.org/r/20211018112541.25466-1-noralf@tronnes.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mfd/dln2.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
--- a/drivers/mfd/dln2.c +++ b/drivers/mfd/dln2.c @@ -50,6 +50,7 @@ enum dln2_handle { DLN2_HANDLE_GPIO, DLN2_HANDLE_I2C, DLN2_HANDLE_SPI, + DLN2_HANDLE_ADC, DLN2_HANDLES };
@@ -653,6 +654,7 @@ enum { DLN2_ACPI_MATCH_GPIO = 0, DLN2_ACPI_MATCH_I2C = 1, DLN2_ACPI_MATCH_SPI = 2, + DLN2_ACPI_MATCH_ADC = 3, };
static struct dln2_platform_data dln2_pdata_gpio = { @@ -683,6 +685,16 @@ static struct mfd_cell_acpi_match dln2_a .adr = DLN2_ACPI_MATCH_SPI, };
+/* Only one ADC port supported */ +static struct dln2_platform_data dln2_pdata_adc = { + .handle = DLN2_HANDLE_ADC, + .port = 0, +}; + +static struct mfd_cell_acpi_match dln2_acpi_match_adc = { + .adr = DLN2_ACPI_MATCH_ADC, +}; + static const struct mfd_cell dln2_devs[] = { { .name = "dln2-gpio", @@ -702,6 +714,12 @@ static const struct mfd_cell dln2_devs[] .platform_data = &dln2_pdata_spi, .pdata_size = sizeof(struct dln2_platform_data), }, + { + .name = "dln2-adc", + .acpi_match = &dln2_acpi_match_adc, + .platform_data = &dln2_pdata_adc, + .pdata_size = sizeof(struct dln2_platform_data), + }, };
static void dln2_stop(struct dln2_dev *dln2)
From: Marek Vasut marex@denx.de
commit 33a5471f8da976bf271a1ebbd6b9d163cb0cb6aa upstream.
The note in c2adda27d202f ("video: backlight: Add of_find_backlight helper in backlight.c") says that gpio-backlight uses brightness as power state. This has been fixed since in ec665b756e6f7 ("backlight: gpio-backlight: Correct initial power state handling") and other backlight drivers do not require this workaround. Drop the workaround.
This fixes the case where e.g. pwm-backlight can perfectly well be set to brightness 0 on boot in DT, which without this patch leads to the display brightness to be max instead of off.
Fixes: c2adda27d202f ("video: backlight: Add of_find_backlight helper in backlight.c") Cc: stable@vger.kernel.org # 5.4+ Cc: stable@vger.kernel.org # 4.19.x: ec665b756e6f7: backlight: gpio-backlight: Correct initial power state handling Signed-off-by: Marek Vasut marex@denx.de Acked-by: Noralf Trønnes noralf@tronnes.org Reviewed-by: Daniel Thompson daniel.thompson@linaro.org Signed-off-by: Lee Jones lee.jones@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/video/backlight/backlight.c | 6 ------ 1 file changed, 6 deletions(-)
--- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -688,12 +688,6 @@ static struct backlight_device *of_find_ of_node_put(np); if (!bd) return ERR_PTR(-EPROBE_DEFER); - /* - * Note: gpio_backlight uses brightness as - * power state during probe - */ - if (!bd->props.brightness) - bd->props.brightness = bd->props.max_brightness; } }
From: Coly Li colyli@suse.de
commit 8468f45091d2866affed6f6a7aecc20779139173 upstream.
In bcache_device_free(), pointer disk is referenced still in ida_simple_remove() after blk_cleanup_disk() gets called on this pointer. This may cause a potential panic by use-after-free on the disk pointer.
This patch fixes the problem by calling blk_cleanup_disk() after ida_simple_remove().
Fixes: bc70852fd104 ("bcache: convert to blk_alloc_disk/blk_cleanup_disk") Signed-off-by: Coly Li colyli@suse.de Cc: Christoph Hellwig hch@lst.de Cc: Hannes Reinecke hare@suse.de Cc: Ulf Hansson ulf.hansson@linaro.org Cc: stable@vger.kernel.org # v5.14+ Reviewed-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20211103064917.67383-1-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -885,9 +885,9 @@ static void bcache_device_free(struct bc bcache_device_detach(d);
if (disk) { - blk_cleanup_disk(disk); ida_simple_remove(&bcache_device_idx, first_minor_to_idx(disk->first_minor)); + blk_cleanup_disk(disk); }
bioset_exit(&d->bio_split);
From: Coly Li colyli@suse.de
commit 2878feaed543c35f9dbbe6d8ce36fb67ac803eef upstream.
This reverts commit 2fd3e5efe791946be0957c8e1eed9560b541fe46.
The above commit replaces page_address(bv->bv_page) by bvec_virt(bv) to avoid directly access to bv->bv_page, but in situation bv->bv_offset is not zero and page_address(bv->bv_page) is not equal to bvec_virt(bv). In such case a memory corruption may happen because memory in next page is tainted by following line in do_btree_node_write(), memcpy(bvec_virt(bv), addr, PAGE_SIZE);
This patch reverts the mentioned commit to avoid the memory corruption.
Fixes: 2fd3e5efe791 ("bcache: use bvec_virt") Signed-off-by: Coly Li colyli@suse.de Cc: Christoph Hellwig hch@lst.de Cc: stable@vger.kernel.org # 5.15 Signed-off-by: Christoph Hellwig hch@lst.de Link: https://lore.kernel.org/r/20211103151041.70516-1-colyli@suse.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/btree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -378,7 +378,7 @@ static void do_btree_node_write(struct b struct bvec_iter_all iter_all;
bio_for_each_segment_all(bv, b->bio, iter_all) { - memcpy(bvec_virt(bv), addr, PAGE_SIZE); + memcpy(page_address(bv->bv_page), addr, PAGE_SIZE); addr += PAGE_SIZE; }
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
commit 2aa36604e8243698ff22bd5fef0dd0c6bb07ba92 upstream.
It is generally unsafe to call put_device() with dpm_list_mtx held, because the given device's release routine may carry out an action depending on that lock which then may deadlock, so modify the system-wide suspend and resume of devices to always drop dpm_list_mtx before calling put_device() (and adjust white space somewhat while at it).
For instance, this prevents the following splat from showing up in the kernel log after a system resume in certain configurations:
[ 3290.969514] ====================================================== [ 3290.969517] WARNING: possible circular locking dependency detected [ 3290.969519] 5.15.0+ #2420 Tainted: G S [ 3290.969523] ------------------------------------------------------ [ 3290.969525] systemd-sleep/4553 is trying to acquire lock: [ 3290.969529] ffff888117ab1138 ((wq_completion)hci0#2){+.+.}-{0:0}, at: flush_workqueue+0x87/0x4a0 [ 3290.969554] but task is already holding lock: [ 3290.969556] ffffffff8280fca8 (dpm_list_mtx){+.+.}-{3:3}, at: dpm_resume+0x12e/0x3e0 [ 3290.969571] which lock already depends on the new lock.
[ 3290.969573] the existing dependency chain (in reverse order) is: [ 3290.969575] -> #3 (dpm_list_mtx){+.+.}-{3:3}: [ 3290.969583] __mutex_lock+0x9d/0xa30 [ 3290.969591] device_pm_add+0x2e/0xe0 [ 3290.969597] device_add+0x4d5/0x8f0 [ 3290.969605] hci_conn_add_sysfs+0x43/0xb0 [bluetooth] [ 3290.969689] hci_conn_complete_evt.isra.71+0x124/0x750 [bluetooth] [ 3290.969747] hci_event_packet+0xd6c/0x28a0 [bluetooth] [ 3290.969798] hci_rx_work+0x213/0x640 [bluetooth] [ 3290.969842] process_one_work+0x2aa/0x650 [ 3290.969851] worker_thread+0x39/0x400 [ 3290.969859] kthread+0x142/0x170 [ 3290.969865] ret_from_fork+0x22/0x30 [ 3290.969872] -> #2 (&hdev->lock){+.+.}-{3:3}: [ 3290.969881] __mutex_lock+0x9d/0xa30 [ 3290.969887] hci_event_packet+0xba/0x28a0 [bluetooth] [ 3290.969935] hci_rx_work+0x213/0x640 [bluetooth] [ 3290.969978] process_one_work+0x2aa/0x650 [ 3290.969985] worker_thread+0x39/0x400 [ 3290.969993] kthread+0x142/0x170 [ 3290.969999] ret_from_fork+0x22/0x30 [ 3290.970004] -> #1 ((work_completion)(&hdev->rx_work)){+.+.}-{0:0}: [ 3290.970013] process_one_work+0x27d/0x650 [ 3290.970020] worker_thread+0x39/0x400 [ 3290.970028] kthread+0x142/0x170 [ 3290.970033] ret_from_fork+0x22/0x30 [ 3290.970038] -> #0 ((wq_completion)hci0#2){+.+.}-{0:0}: [ 3290.970047] __lock_acquire+0x15cb/0x1b50 [ 3290.970054] lock_acquire+0x26c/0x300 [ 3290.970059] flush_workqueue+0xae/0x4a0 [ 3290.970066] drain_workqueue+0xa1/0x130 [ 3290.970073] destroy_workqueue+0x34/0x1f0 [ 3290.970081] hci_release_dev+0x49/0x180 [bluetooth] [ 3290.970130] bt_host_release+0x1d/0x30 [bluetooth] [ 3290.970195] device_release+0x33/0x90 [ 3290.970201] kobject_release+0x63/0x160 [ 3290.970211] dpm_resume+0x164/0x3e0 [ 3290.970215] dpm_resume_end+0xd/0x20 [ 3290.970220] suspend_devices_and_enter+0x1a4/0xba0 [ 3290.970229] pm_suspend+0x26b/0x310 [ 3290.970236] state_store+0x42/0x90 [ 3290.970243] kernfs_fop_write_iter+0x135/0x1b0 [ 3290.970251] new_sync_write+0x125/0x1c0 [ 3290.970257] vfs_write+0x360/0x3c0 [ 3290.970263] ksys_write+0xa7/0xe0 [ 3290.970269] do_syscall_64+0x3a/0x80 [ 3290.970276] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 3290.970284] other info that might help us debug this:
[ 3290.970285] Chain exists of: (wq_completion)hci0#2 --> &hdev->lock --> dpm_list_mtx
[ 3290.970297] Possible unsafe locking scenario:
[ 3290.970299] CPU0 CPU1 [ 3290.970300] ---- ---- [ 3290.970302] lock(dpm_list_mtx); [ 3290.970306] lock(&hdev->lock); [ 3290.970310] lock(dpm_list_mtx); [ 3290.970314] lock((wq_completion)hci0#2); [ 3290.970319] *** DEADLOCK ***
[ 3290.970321] 7 locks held by systemd-sleep/4553: [ 3290.970325] #0: ffff888103bcd448 (sb_writers#4){.+.+}-{0:0}, at: ksys_write+0xa7/0xe0 [ 3290.970341] #1: ffff888115a14488 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x103/0x1b0 [ 3290.970355] #2: ffff888100f719e0 (kn->active#233){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x10c/0x1b0 [ 3290.970369] #3: ffffffff82661048 (autosleep_lock){+.+.}-{3:3}, at: state_store+0x12/0x90 [ 3290.970384] #4: ffffffff82658ac8 (system_transition_mutex){+.+.}-{3:3}, at: pm_suspend+0x9f/0x310 [ 3290.970399] #5: ffffffff827f2a48 (acpi_scan_lock){+.+.}-{3:3}, at: acpi_suspend_begin+0x4c/0x80 [ 3290.970416] #6: ffffffff8280fca8 (dpm_list_mtx){+.+.}-{3:3}, at: dpm_resume+0x12e/0x3e0 [ 3290.970428] stack backtrace: [ 3290.970431] CPU: 3 PID: 4553 Comm: systemd-sleep Tainted: G S 5.15.0+ #2420 [ 3290.970438] Hardware name: Dell Inc. XPS 13 9380/0RYJWW, BIOS 1.5.0 06/03/2019 [ 3290.970441] Call Trace: [ 3290.970446] dump_stack_lvl+0x44/0x57 [ 3290.970454] check_noncircular+0x105/0x120 [ 3290.970468] ? __lock_acquire+0x15cb/0x1b50 [ 3290.970474] __lock_acquire+0x15cb/0x1b50 [ 3290.970487] lock_acquire+0x26c/0x300 [ 3290.970493] ? flush_workqueue+0x87/0x4a0 [ 3290.970503] ? __raw_spin_lock_init+0x3b/0x60 [ 3290.970510] ? lockdep_init_map_type+0x58/0x240 [ 3290.970519] flush_workqueue+0xae/0x4a0 [ 3290.970526] ? flush_workqueue+0x87/0x4a0 [ 3290.970544] ? drain_workqueue+0xa1/0x130 [ 3290.970552] drain_workqueue+0xa1/0x130 [ 3290.970561] destroy_workqueue+0x34/0x1f0 [ 3290.970572] hci_release_dev+0x49/0x180 [bluetooth] [ 3290.970624] bt_host_release+0x1d/0x30 [bluetooth] [ 3290.970687] device_release+0x33/0x90 [ 3290.970695] kobject_release+0x63/0x160 [ 3290.970705] dpm_resume+0x164/0x3e0 [ 3290.970710] ? dpm_resume_early+0x251/0x3b0 [ 3290.970718] dpm_resume_end+0xd/0x20 [ 3290.970723] suspend_devices_and_enter+0x1a4/0xba0 [ 3290.970737] pm_suspend+0x26b/0x310 [ 3290.970746] state_store+0x42/0x90 [ 3290.970755] kernfs_fop_write_iter+0x135/0x1b0 [ 3290.970764] new_sync_write+0x125/0x1c0 [ 3290.970777] vfs_write+0x360/0x3c0 [ 3290.970785] ksys_write+0xa7/0xe0 [ 3290.970794] do_syscall_64+0x3a/0x80 [ 3290.970803] entry_SYSCALL_64_after_hwframe+0x44/0xae [ 3290.970811] RIP: 0033:0x7f41b1328164 [ 3290.970819] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 80 00 00 00 00 8b 05 4a d2 2c 00 48 63 ff 85 c0 75 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 f3 c3 66 90 55 53 48 89 d5 48 89 f3 48 83 [ 3290.970824] RSP: 002b:00007ffe6ae21b28 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 [ 3290.970831] RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f41b1328164 [ 3290.970836] RDX: 0000000000000004 RSI: 000055965e651070 RDI: 0000000000000004 [ 3290.970839] RBP: 000055965e651070 R08: 000055965e64f390 R09: 00007f41b1e3d1c0 [ 3290.970843] R10: 000000000000000a R11: 0000000000000246 R12: 0000000000000004 [ 3290.970846] R13: 0000000000000001 R14: 000055965e64f2b0 R15: 0000000000000004
Cc: All applicable stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/power/main.c | 84 +++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 27 deletions(-)
--- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -711,6 +711,7 @@ static void dpm_noirq_resume_devices(pm_ dev = to_device(dpm_noirq_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_late_early_list); + mutex_unlock(&dpm_list_mtx);
if (!is_async(dev)) { @@ -725,8 +726,9 @@ static void dpm_noirq_resume_devices(pm_ } }
- mutex_lock(&dpm_list_mtx); put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); @@ -852,6 +854,7 @@ void dpm_resume_early(pm_message_t state dev = to_device(dpm_late_early_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_suspended_list); + mutex_unlock(&dpm_list_mtx);
if (!is_async(dev)) { @@ -865,8 +868,10 @@ void dpm_resume_early(pm_message_t state pm_dev_err(dev, state, " early", error); } } - mutex_lock(&dpm_list_mtx); + put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); @@ -1029,7 +1034,12 @@ void dpm_resume(pm_message_t state) } if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); + + mutex_unlock(&dpm_list_mtx); + put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); @@ -1107,14 +1117,16 @@ void dpm_complete(pm_message_t state) get_device(dev); dev->power.is_prepared = false; list_move(&dev->power.entry, &list); + mutex_unlock(&dpm_list_mtx);
trace_device_pm_callback_start(dev, "", state.event); device_complete(dev, state); trace_device_pm_callback_end(dev, 0);
- mutex_lock(&dpm_list_mtx); put_device(dev); + + mutex_lock(&dpm_list_mtx); } list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); @@ -1299,17 +1311,21 @@ static int dpm_noirq_suspend_devices(pm_ error = device_suspend_noirq(dev);
mutex_lock(&dpm_list_mtx); + if (error) { pm_dev_err(dev, state, " noirq", error); dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; - } - if (!list_empty(&dev->power.entry)) + } else if (!list_empty(&dev->power.entry)) { list_move(&dev->power.entry, &dpm_noirq_list); + } + + mutex_unlock(&dpm_list_mtx); + put_device(dev);
- if (async_error) + mutex_lock(&dpm_list_mtx); + + if (error || async_error) break; } mutex_unlock(&dpm_list_mtx); @@ -1476,23 +1492,28 @@ int dpm_suspend_late(pm_message_t state) struct device *dev = to_device(dpm_suspended_list.prev);
get_device(dev); + mutex_unlock(&dpm_list_mtx);
error = device_suspend_late(dev);
mutex_lock(&dpm_list_mtx); + if (!list_empty(&dev->power.entry)) list_move(&dev->power.entry, &dpm_late_early_list);
if (error) { pm_dev_err(dev, state, " late", error); dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; } + + mutex_unlock(&dpm_list_mtx); + put_device(dev);
- if (async_error) + mutex_lock(&dpm_list_mtx); + + if (error || async_error) break; } mutex_unlock(&dpm_list_mtx); @@ -1752,21 +1773,27 @@ int dpm_suspend(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev);
get_device(dev); + mutex_unlock(&dpm_list_mtx);
error = device_suspend(dev);
mutex_lock(&dpm_list_mtx); + if (error) { pm_dev_err(dev, state, "", error); dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; - } - if (!list_empty(&dev->power.entry)) + } else if (!list_empty(&dev->power.entry)) { list_move(&dev->power.entry, &dpm_suspended_list); + } + + mutex_unlock(&dpm_list_mtx); + put_device(dev); - if (async_error) + + mutex_lock(&dpm_list_mtx); + + if (error || async_error) break; } mutex_unlock(&dpm_list_mtx); @@ -1883,6 +1910,7 @@ int dpm_prepare(pm_message_t state) struct device *dev = to_device(dpm_list.next);
get_device(dev); + mutex_unlock(&dpm_list_mtx);
trace_device_pm_callback_start(dev, "", state.event); @@ -1890,21 +1918,23 @@ int dpm_prepare(pm_message_t state) trace_device_pm_callback_end(dev, error);
mutex_lock(&dpm_list_mtx); - if (error) { - if (error == -EAGAIN) { - put_device(dev); - error = 0; - continue; - } + + if (!error) { + dev->power.is_prepared = true; + if (!list_empty(&dev->power.entry)) + list_move_tail(&dev->power.entry, &dpm_prepared_list); + } else if (error == -EAGAIN) { + error = 0; + } else { dev_info(dev, "not prepared for power transition: code %d\n", error); - put_device(dev); - break; } - dev->power.is_prepared = true; - if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_prepared_list); + + mutex_unlock(&dpm_list_mtx); + put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); trace_suspend_resume(TPS("dpm_prepare"), state.event, false);
From: Thomas Richter tmricht@linux.ibm.com
commit 9d48c7afedf91a02d03295837ec76b2fb5e7d3fe upstream.
When a CPU is hotplugged while the perf stat -e cycles command is running, a wrong (very large) value is displayed immediately after the CPU removal:
Check the values, shouldn't be too high as in time counts unit events 1.001101919 29261846 cycles 2.002454499 17523405 cycles 3.003659292 24361161 cycles 4.004816983 18446744073638406144 cycles 5.005671647 <not counted> cycles ...
The CPU hotplug off took place after 3 seconds. The issue is the read of the event count value after 4 seconds when the CPU is not available and the read of the counter returns an error. This is treated as a counter value of zero. This results in a very large value (0 - previous_value).
Fix this by detecting the hotplugged off CPU and report 0 instead of a very large number.
Cc: stable@vger.kernel.org Fixes: a029a4eab39e ("s390/cpumf: Allow concurrent access for CPU Measurement Counter Facility") Reported-by: Sumanth Korikkar sumanthk@linux.ibm.com Signed-off-by: Thomas Richter tmricht@linux.ibm.com Reviewed-by: Sumanth Korikkar sumanthk@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kernel/perf_cpum_cf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -687,8 +687,10 @@ static void cpumf_pmu_stop(struct perf_e false); if (cfdiag_diffctr(cpuhw, event->hw.config_base)) cfdiag_push_sample(event, cpuhw); - } else + } else if (cpuhw->flags & PMU_F_RESERVED) { + /* Only update when PMU not hotplugged off */ hw_perf_event_update(event); + } hwc->state |= PERF_HES_UPTODATE; } }
From: Vineeth Vijayan vneethv@linux.ibm.com
commit a4751f157c194431fae9e9c493f456df8272b871 upstream.
Check the validity of subchanel before reading other fields in the schib.
Fixes: d3683c055212 ("s390/cio: add dev_busid sysfs entry for each subchannel") CC: stable@vger.kernel.org Reported-by: Cornelia Huck cohuck@redhat.com Signed-off-by: Vineeth Vijayan vneethv@linux.ibm.com Reviewed-by: Cornelia Huck cohuck@redhat.com Link: https://lore.kernel.org/r/20211105154451.847288-1-vneethv@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/cio/css.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -437,8 +437,8 @@ static ssize_t dev_busid_show(struct dev struct subchannel *sch = to_subchannel(dev); struct pmcw *pmcw = &sch->schib.pmcw;
- if ((pmcw->st == SUBCHANNEL_TYPE_IO || - pmcw->st == SUBCHANNEL_TYPE_MSG) && pmcw->dnv) + if ((pmcw->st == SUBCHANNEL_TYPE_IO && pmcw->dnv) || + (pmcw->st == SUBCHANNEL_TYPE_MSG && pmcw->w)) return sysfs_emit(buf, "0.%x.%04x\n", sch->schid.ssid, pmcw->dev); else
From: Sven Schnelle svens@linux.ibm.com
commit 213fca9e23b59581c573d558aa477556f00b8198 upstream.
commit 9c6c273aa424 ("timer: Remove init_timer_on_stack() in favor of timer_setup_on_stack()") changed the timer setup from init_timer_on_stack(() to timer_setup(), but missed to change the mod_timer() call. And while at it, use msecs_to_jiffies() instead of the open coded timeout calculation.
Cc: stable@vger.kernel.org Fixes: 9c6c273aa424 ("timer: Remove init_timer_on_stack() in favor of timer_setup_on_stack()") Signed-off-by: Sven Schnelle svens@linux.ibm.com Reviewed-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/char/tape_std.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c @@ -53,7 +53,6 @@ int tape_std_assign(struct tape_device *device) { int rc; - struct timer_list timeout; struct tape_request *request;
request = tape_alloc_request(2, 11); @@ -70,7 +69,7 @@ tape_std_assign(struct tape_device *devi * So we set up a timeout for this call. */ timer_setup(&request->timer, tape_std_assign_timeout, 0); - mod_timer(&timeout, jiffies + 2 * HZ); + mod_timer(&request->timer, jiffies + msecs_to_jiffies(2000));
rc = tape_do_io_interruptible(device, request);
From: Harald Freudenberger freude@linux.ibm.com
commit 3826350e6dd435e244eb6e47abad5a47c169ebc2 upstream.
When a queue is switched to soft offline during heavy load and later switched to soft online again and now used, it may be that the caller is blocked forever in the ioctl call.
The failure occurs because there is a pending reply after the queue(s) have been switched to offline. This orphaned reply is received when the queue is switched to online and is accidentally counted for the outstanding replies. So when there was a valid outstanding reply and this orphaned reply is received it counts as the outstanding one thus dropping the outstanding counter to 0. Voila, with this counter the receive function is not called any more and the real outstanding reply is never received (until another request comes in...) and the ioctl blocks.
The fix is simple. However, instead of readjusting the counter when an orphaned reply is detected, I check the queue status for not empty and compare this to the outstanding counter. So if the queue is not empty then the counter must not drop to 0 but at least have a value of 1.
Signed-off-by: Harald Freudenberger freude@linux.ibm.com Cc: stable@vger.kernel.org Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/crypto/ap_queue.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -157,6 +157,8 @@ static struct ap_queue_status ap_sm_recv switch (status.response_code) { case AP_RESPONSE_NORMAL: aq->queue_count = max_t(int, 0, aq->queue_count - 1); + if (!status.queue_empty && !aq->queue_count) + aq->queue_count++; if (aq->queue_count > 0) mod_timer(&aq->timeout, jiffies + aq->request_timeout);
From: Halil Pasic pasic@linux.ibm.com
commit ad9a14517263a16af040598c7920c09ca9670a31 upstream.
Since commit 48720ba56891 ("virtio/s390: use DMA memory for ccw I/O and classic notifiers") we were supposed to make sure that virtio_ccw_release_dev() completes before the ccw device and the attached dma pool are torn down, but unfortunately we did not. Before that commit it used to be OK to delay cleaning up the memory allocated by virtio-ccw indefinitely (which isn't really intuitive for guys used to destruction happens in reverse construction order), but now we trigger a BUG_ON if the genpool is destroyed before all memory allocated from it is deallocated. Which brings down the guest. We can observe this problem, when unregister_virtio_device() does not give up the last reference to the virtio_device (e.g. because a virtio-scsi attached scsi disk got removed without previously unmounting its previously mounted partition).
To make sure that the genpool is only destroyed after all the necessary freeing is done let us take a reference on the ccw device on each ccw_device_dma_zalloc() and give it up on each ccw_device_dma_free().
Actually there are multiple approaches to fixing the problem at hand that can work. The upside of this one is that it is the safest one while remaining simple. We don't crash the guest even if the driver does not pair allocations and frees. The downside is the reference counting overhead, that the reference counting for ccw devices becomes more complex, in a sense that we need to pair the calls to the aforementioned functions for it to be correct, and that if we happen to leak, we leak more than necessary (the whole ccw device instead of just the genpool).
Some alternatives to this approach are taking a reference in virtio_ccw_online() and giving it up in virtio_ccw_release_dev() or making sure virtio_ccw_release_dev() completes its work before virtio_ccw_remove() returns. The downside of these approaches is that these are less safe against programming errors.
Cc: stable@vger.kernel.org # v5.3 Signed-off-by: Halil Pasic pasic@linux.ibm.com Fixes: 48720ba56891 ("virtio/s390: use DMA memory for ccw I/O and classic notifiers") Reported-by: bfu@redhat.com Reviewed-by: Vineeth Vijayan vneethv@linux.ibm.com Acked-by: Cornelia Huck cohuck@redhat.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/cio/device_ops.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -825,13 +825,23 @@ EXPORT_SYMBOL_GPL(ccw_device_get_chid); */ void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size) { - return cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size); + void *addr; + + if (!get_device(&cdev->dev)) + return NULL; + addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size); + if (IS_ERR_OR_NULL(addr)) + put_device(&cdev->dev); + return addr; } EXPORT_SYMBOL(ccw_device_dma_zalloc);
void ccw_device_dma_free(struct ccw_device *cdev, void *cpu_addr, size_t size) { + if (!cpu_addr) + return; cio_gp_dma_free(cdev->private->dma_pool, cpu_addr, size); + put_device(&cdev->dev); } EXPORT_SYMBOL(ccw_device_dma_free);
From: Peng Fan peng.fan@nxp.com
commit 24acbd9dc934f5d9418a736c532d3970a272063e upstream.
It seems luckliy work on i.MX platform, but it is wrong. Need use memcpy_toio, not memcpy_fromio.
Fixes: 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va") Tested-by: Dong Aisheng aisheng.dong@nxp.com (i.MX8MQ) Reported-by: kernel test robot lkp@intel.com Reported-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210910090621.3073540-2-peng.fan@oss.nxp.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/remoteproc/remoteproc_elf_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/remoteproc/remoteproc_elf_loader.c +++ b/drivers/remoteproc/remoteproc_elf_loader.c @@ -220,7 +220,7 @@ int rproc_elf_load_segments(struct rproc /* put the segment where the remote processor expects it */ if (filesz) { if (is_iomem) - memcpy_fromio(ptr, (void __iomem *)(elf_data + offset), filesz); + memcpy_toio((void __iomem *)ptr, elf_data + offset, filesz); else memcpy(ptr, elf_data + offset, filesz); }
From: Dong Aisheng aisheng.dong@nxp.com
commit 970675f61bf5761d7e5326f6e4df995ecdba5e11 upstream.
Currently the is_iomem is a random value in the stack which may be default to true even on those platforms that not use iomem to store firmware.
Cc: Bjorn Andersson bjorn.andersson@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Fixes: 40df0a91b2a5 ("remoteproc: add is_iomem to da_to_va") Reviewed-and-tested-by: Peng Fan peng.fan@nxp.com Signed-off-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210910090621.3073540-3-peng.fan@oss.nxp.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/remoteproc/remoteproc_coredump.c | 2 +- drivers/remoteproc/remoteproc_elf_loader.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/remoteproc/remoteproc_coredump.c +++ b/drivers/remoteproc/remoteproc_coredump.c @@ -152,8 +152,8 @@ static void rproc_copy_segment(struct rp struct rproc_dump_segment *segment, size_t offset, size_t size) { + bool is_iomem = false; void *ptr; - bool is_iomem;
if (segment->dump) { segment->dump(rproc, segment, dest, offset, size); --- a/drivers/remoteproc/remoteproc_elf_loader.c +++ b/drivers/remoteproc/remoteproc_elf_loader.c @@ -178,8 +178,8 @@ int rproc_elf_load_segments(struct rproc u64 filesz = elf_phdr_get_p_filesz(class, phdr); u64 offset = elf_phdr_get_p_offset(class, phdr); u32 type = elf_phdr_get_p_type(class, phdr); + bool is_iomem = false; void *ptr; - bool is_iomem;
if (type != PT_LOAD) continue;
From: Dong Aisheng aisheng.dong@nxp.com
commit afe670e23af91d8a74a8d7049f6e0984bbf6ea11 upstream.
vdev regions are typically named vdev0buffer, vdev0ring0, vdev0ring1 and etc. Change to strncmp to cover them all.
Fixes: 8f2d8961640f ("remoteproc: imx_rproc: ignore mapping vdev regions") Reviewed-and-tested-by: Peng Fan peng.fan@nxp.com Signed-off-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210910090621.3073540-5-peng.fan@oss.nxp.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/remoteproc/imx_rproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -582,8 +582,8 @@ static int imx_rproc_addr_init(struct im struct resource res;
node = of_parse_phandle(np, "memory-region", a); - /* Not map vdev region */ - if (!strcmp(node->name, "vdev")) + /* Not map vdevbuffer, vdevring region */ + if (!strncmp(node->name, "vdev", strlen("vdev"))) continue; err = of_address_to_resource(node, 0, &res); if (err) {
From: Dong Aisheng aisheng.dong@nxp.com
commit e90547d59d4e29e269e22aa6ce590ed0b41207d2 upstream.
Usually the dash '-' is preferred in node name. So far, not dts in upstream kernel, so we just update node name in driver.
Cc: Bjorn Andersson bjorn.andersson@linaro.org Cc: Mathieu Poirier mathieu.poirier@linaro.org Fixes: 5e4c1243071d ("remoteproc: imx_rproc: support remote cores booted before Linux Kernel") Reviewed-and-tested-by: Peng Fan peng.fan@nxp.com Signed-off-by: Dong Aisheng aisheng.dong@nxp.com Signed-off-by: Peng Fan peng.fan@nxp.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210910090621.3073540-6-peng.fan@oss.nxp.com Signed-off-by: Mathieu Poirier mathieu.poirier@linaro.org Signed-off-by: Bjorn Andersson bjorn.andersson@linaro.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/remoteproc/imx_rproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -604,7 +604,7 @@ static int imx_rproc_addr_init(struct im } priv->mem[b].sys_addr = res.start; priv->mem[b].size = resource_size(&res); - if (!strcmp(node->name, "rsc_table")) + if (!strcmp(node->name, "rsc-table")) priv->rsc_table = priv->mem[b].cpu_addr; b++; }
From: Miquel Raynal miquel.raynal@bootlin.com
commit 9be1446ece291a1f08164bd056bed3d698681f8b upstream.
The introduction of the generic ECC engine API lead to a number of changes in various drivers which broke some of them. Here is a typical example: I expected the SM_ORDER option to be handled by the Hamming ECC engine internals. Problem: the fsmc driver does not instantiate (yet) a real ECC engine object so we had to use a 'bare' ECC helper instead of the shiny rawnand functions. However, when not intializing this engine properly and using the bare helpers, we do not get the SM ORDER feature handled automatically. It looks like this was lost in the process so let's ensure we use the right SM ORDER now.
Fixes: ad9ffdce4539 ("mtd: rawnand: fsmc: Fix external use of SW Hamming ECC helper") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928221507.199198-2-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/fsmc_nand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/mtd/nand/raw/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c @@ -438,8 +438,10 @@ static int fsmc_correct_ecc1(struct nand unsigned char *read_ecc, unsigned char *calc_ecc) { + bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER; + return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc, - chip->ecc.size, false); + chip->ecc.size, sm_order); }
/* Count the number of 0's in buff upto a max of max_bits */
From: Miquel Raynal miquel.raynal@bootlin.com
commit d707bb74daae07879e0fc1b4b960f8f2d0a5fe5d upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: 59d93473323a ("mtd: rawnand: ams-delta: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-2-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/ams-delta.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/ams-delta.c +++ b/drivers/mtd/nand/raw/ams-delta.c @@ -217,9 +217,8 @@ static int gpio_nand_setup_interface(str
static int gpio_nand_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -370,6 +369,13 @@ static int gpio_nand_probe(struct platfo /* Release write protection */ gpiod_set_value(priv->gpiod_nwp, 0);
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Scan to find existence of the device */ err = nand_scan(this, 1); if (err)
From: Miquel Raynal miquel.raynal@bootlin.com
commit 6bcd2960af1b7bacb2f1e710ab0c0b802d900501 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: d525914b5bd8 ("mtd: rawnand: xway: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Cc: Jan Hoffmann jan@3e8.eu Cc: Kestrel seventyfour kestrelseventyfour@gmail.com Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Tested-by: Jan Hoffmann jan@3e8.eu Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-10-miquel.raynal@boo... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/xway_nand.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/xway_nand.c +++ b/drivers/mtd/nand/raw/xway_nand.c @@ -148,9 +148,8 @@ static void xway_write_buf(struct nand_c
static int xway_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -219,6 +218,13 @@ static int xway_nand_probe(struct platfo | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P | cs_flag, EBU_NAND_CON);
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Scan to find existence of the device */ err = nand_scan(&data->chip, 1); if (err)
From: Miquel Raynal miquel.raynal@bootlin.com
commit f9d8570b7fd6f4f08528ce2f5e39787a8a260cd6 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: 6dd09f775b72 ("mtd: rawnand: mpc5121: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-5-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/mpc5121_nfc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/mpc5121_nfc.c +++ b/drivers/mtd/nand/raw/mpc5121_nfc.c @@ -605,9 +605,8 @@ static void mpc5121_nfc_free(struct devi
static int mpc5121_nfc_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -772,6 +771,13 @@ static int mpc5121_nfc_probe(struct plat goto error; }
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Detect NAND chips */ retval = nand_scan(chip, be32_to_cpup(chips_no)); if (retval) {
From: Miquel Raynal miquel.raynal@bootlin.com
commit b5b5b4dc6fcd8194b9dd38c8acdc5ab71adf44f8 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: f6341f6448e0 ("mtd: rawnand: gpio: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-4-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/gpio.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/gpio.c +++ b/drivers/mtd/nand/raw/gpio.c @@ -163,9 +163,8 @@ static int gpio_nand_exec_op(struct nand
static int gpio_nand_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -365,6 +364,13 @@ static int gpio_nand_probe(struct platfo if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) gpiod_direction_output(gpiomtd->nwp, 1);
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + ret = nand_scan(chip, 1); if (ret) goto err_wp;
From: Miquel Raynal miquel.raynal@bootlin.com
commit f16b7d2a5e810fcf4b15d096246d0d445da9cc88 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: 8fc6f1f042b2 ("mtd: rawnand: pasemi: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-7-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/pasemi_nand.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/pasemi_nand.c +++ b/drivers/mtd/nand/raw/pasemi_nand.c @@ -75,9 +75,8 @@ static int pasemi_device_ready(struct na
static int pasemi_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -154,6 +153,13 @@ static int pasemi_nand_probe(struct plat /* Enable the following for a flash based bad block table */ chip->bbt_options = NAND_BBT_USE_FLASH;
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Scan to find existence of the device */ err = nand_scan(chip, 1); if (err)
From: Miquel Raynal miquel.raynal@bootlin.com
commit 194ac63de6ff56d30c48e3ac19c8a412f9c1408e upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: 553508cec2e8 ("mtd: rawnand: orion: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-6-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/orion_nand.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/orion_nand.c +++ b/drivers/mtd/nand/raw/orion_nand.c @@ -85,9 +85,8 @@ static void orion_nand_read_buf(struct n
static int orion_nand_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -190,6 +189,13 @@ static int __init orion_nand_probe(struc return ret; }
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + nc->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + ret = nand_scan(nc, 1); if (ret) goto no_dev;
From: Miquel Raynal miquel.raynal@bootlin.com
commit 325fd539fc84f0aaa0ceb9d7d3b8718582473dc5 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: 612e048e6aab ("mtd: rawnand: plat_nand: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-8-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/plat_nand.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/plat_nand.c +++ b/drivers/mtd/nand/raw/plat_nand.c @@ -21,9 +21,8 @@ struct plat_nand_data {
static int plat_nand_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -94,6 +93,13 @@ static int plat_nand_probe(struct platfo goto out; }
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + /* Scan to find existence of the device */ err = nand_scan(&data->chip, pdata->chip.nr_chips); if (err)
From: Miquel Raynal miquel.raynal@bootlin.com
commit 7e3cdba176ba59eaf4d463d273da0718e3626140 upstream.
Following the introduction of the generic ECC engine infrastructure, it was necessary to reorganize the code and move the ECC configuration in the ->attach_chip() hook. Failing to do that properly lead to a first series of fixes supposed to stabilize the situation. Unfortunately, this only fixed the use of software ECC engines, preventing any other kind of engine to be used, including on-die ones.
It is now time to (finally) fix the situation by ensuring that we still provide a default (eg. software ECC) but will still support different ECC engines such as on-die ECC engines if properly described in the device tree.
There are no changes needed on the core side in order to do this, but we just need to leverage the logic there which allows: 1- a subsystem default (set to Host engines in the raw NAND world) 2- a driver specific default (here set to software ECC engines) 3- any type of engine requested by the user (ie. described in the DT)
As the raw NAND subsystem has not yet been fully converted to the ECC engine infrastructure, in order to provide a default ECC engine for this driver we need to set chip->ecc.engine_type *before* calling nand_scan(). During the initialization step, the core will consider this entry as the default engine for this driver. This value may of course be overloaded by the user if the usual DT properties are provided.
Fixes: dbffc8ccdf3a ("mtd: rawnand: au1550: Move the ECC initialization to ->attach_chip()") Cc: stable@vger.kernel.org Signed-off-by: Miquel Raynal miquel.raynal@bootlin.com Link: https://lore.kernel.org/linux-mtd/20210928222258.199726-3-miquel.raynal@boot... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mtd/nand/raw/au1550nd.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
--- a/drivers/mtd/nand/raw/au1550nd.c +++ b/drivers/mtd/nand/raw/au1550nd.c @@ -239,9 +239,8 @@ static int au1550nd_exec_op(struct nand_
static int au1550nd_attach_chip(struct nand_chip *chip) { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - - if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
return 0; @@ -310,6 +309,13 @@ static int au1550nd_probe(struct platfor if (pd->devwidth) this->options |= NAND_BUSWIDTH_16;
+ /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + ret = nand_scan(this, 1); if (ret) { dev_err(&pdev->dev, "NAND scan failed with %d\n", ret);
From: Gustavo A. R. Silva gustavoars@kernel.org
commit 61cb9ac66b30374c7fd8a8b2a3c4f8f432c72e36 upstream.
(!ptr && !ptr->foo) strikes again. :)
The expression (!ptr && !ptr->foo) is bogus and in case ptr is NULL, it leads to a NULL pointer dereference: ptr->foo.
Fix this by converting && to ||
This issue was detected with the help of Coccinelle, and audited and fixed manually.
Fixes: 1a0d0d5ed5e3 ("powerpc/vas: Add platform specific user window operations") Cc: stable@vger.kernel.org Signed-off-by: Gustavo A. R. Silva gustavoars@kernel.org Reviewed-by: Tyrel Datwyler tyreld@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211015050345.GA1161918@embeddedor Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/book3s/vas-api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/platforms/book3s/vas-api.c +++ b/arch/powerpc/platforms/book3s/vas-api.c @@ -303,7 +303,7 @@ static int coproc_ioc_tx_win_open(struct return -EINVAL; }
- if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->open_win) { + if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->open_win) { pr_err("VAS API is not registered\n"); return -EACCES; } @@ -373,7 +373,7 @@ static int coproc_mmap(struct file *fp, return -EINVAL; }
- if (!cp_inst->coproc->vops && !cp_inst->coproc->vops->paste_addr) { + if (!cp_inst->coproc->vops || !cp_inst->coproc->vops->paste_addr) { pr_err("%s(): VAS API is not registered\n", __func__); return -EACCES; }
From: Hari Bathini hbathini@linux.ibm.com
commit 44a8214de96bafb5210e43bfa2c97c19bf75af3d upstream.
Running program with bpf-to-bpf function calls results in data access exception (0x300) with the below call trace:
bpf_int_jit_compile+0x238/0x750 (unreliable) bpf_check+0x2008/0x2710 bpf_prog_load+0xb00/0x13a0 __sys_bpf+0x6f4/0x27c0 sys_bpf+0x2c/0x40 system_call_exception+0x164/0x330 system_call_vectored_common+0xe8/0x278
as bpf_int_jit_compile() tries writing to write protected JIT code location during the extra pass.
Fix it by holding off write protection of JIT code until the extra pass, where branch target addresses fixup happens.
Fixes: 62e3d4210ac9 ("powerpc/bpf: Write protect JIT code") Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Hari Bathini hbathini@linux.ibm.com Reviewed-by: Naveen N. Rao naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211025055649.114728-1-hbathini@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/net/bpf_jit_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -241,8 +241,8 @@ skip_codegen_passes: fp->jited_len = alloclen;
bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE)); - bpf_jit_binary_lock_ro(bpf_hdr); if (!fp->is_func || extra_pass) { + bpf_jit_binary_lock_ro(bpf_hdr); bpf_prog_fill_jited_linfo(fp, addrs); out_addrs: kfree(addrs);
From: Nicholas Piggin npiggin@gmail.com
commit 81291383ffde08b23bce75e7d6b2575ce9d3475c upstream.
A e5500 machine running a 32-bit kernel sometimes hangs at boot, seemingly going into an infinite loop of instruction storage interrupts.
The ESR (Exception Syndrome Register) has a value of 0x800000 (store) when this happens, which is likely set by a previous store. An instruction TLB miss interrupt would then leave ESR unchanged, and if no PTE exists it calls directly to the instruction storage interrupt handler without changing ESR.
access_error() does not cause a segfault due to a store to a read-only vma because is_exec is true. Most subsequent fault handling does not check for a write fault on a read-only vma, and might do strange things like create a writeable PTE or call page_mkwrite on a read only vma or file. It's not clear what happens here to cause the infinite faulting in this case, a fault handler failure or low level PTE or TLB handling.
In any case this can be fixed by having the instruction storage interrupt zero regs->dsisr rather than storing the ESR value to it.
Fixes: a01a3f2ddbcd ("powerpc: remove arguments from fault handler functions") Cc: stable@vger.kernel.org # v5.12+ Reported-by: Jacques de Laval jacques.delaval@protonmail.com Signed-off-by: Nicholas Piggin npiggin@gmail.com Tested-by: Jacques de Laval jacques.delaval@protonmail.com Reviewed-by: Christophe Leroy christophe.leroy@csgroup.eu Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211028133043.4159501-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/head_booke.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
--- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -465,12 +465,21 @@ label: bl do_page_fault; \ b interrupt_return
+/* + * Instruction TLB Error interrupt handlers may call InstructionStorage + * directly without clearing ESR, so the ESR at this point may be left over + * from a prior interrupt. + * + * In any case, do_page_fault for BOOK3E does not use ESR and always expects + * dsisr to be 0. ESR_DST from a prior store in particular would confuse fault + * handling. + */ #define INSTRUCTION_STORAGE_EXCEPTION \ START_EXCEPTION(InstructionStorage) \ - NORMAL_EXCEPTION_PROLOG(0x400, INST_STORAGE); \ - mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \ + NORMAL_EXCEPTION_PROLOG(0x400, INST_STORAGE); \ + li r5,0; /* Store 0 in regs->esr (dsisr) */ \ stw r5,_ESR(r11); \ - stw r12, _DEAR(r11); /* Pass SRR0 as arg2 */ \ + stw r12, _DEAR(r11); /* Set regs->dear (dar) to SRR0 */ \ prepare_transfer_to_handler; \ bl do_page_fault; \ b interrupt_return
From: Vasant Hegde hegdevasant@linux.vnet.ibm.com
commit 52862ab33c5d97490f3fa345d6529829e6d6637b upstream.
Commit 587164cd, introduced new opal message type (OPAL_MSG_PRD2) and added opal notifier. But I missed to unregister the notifier during module unload path. This results in below call trace if you try to unload and load opal_prd module.
Also add new notifier_block for OPAL_MSG_PRD2 message.
Sample calltrace (modprobe -r opal_prd; modprobe opal_prd) BUG: Unable to handle kernel data access on read at 0xc0080000192200e0 Faulting instruction address: 0xc00000000018d1cc Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA PowerNV CPU: 66 PID: 7446 Comm: modprobe Kdump: loaded Tainted: G E 5.14.0prd #759 NIP: c00000000018d1cc LR: c00000000018d2a8 CTR: c0000000000cde10 REGS: c0000003c4c0f0a0 TRAP: 0300 Tainted: G E (5.14.0prd) MSR: 9000000002009033 <SF,HV,VEC,EE,ME,IR,DR,RI,LE> CR: 24224824 XER: 20040000 CFAR: c00000000018d2a4 DAR: c0080000192200e0 DSISR: 40000000 IRQMASK: 1 ... NIP notifier_chain_register+0x2c/0xc0 LR atomic_notifier_chain_register+0x48/0x80 Call Trace: 0xc000000002090610 (unreliable) atomic_notifier_chain_register+0x58/0x80 opal_message_notifier_register+0x7c/0x1e0 opal_prd_probe+0x84/0x150 [opal_prd] platform_probe+0x78/0x130 really_probe+0x110/0x5d0 __driver_probe_device+0x17c/0x230 driver_probe_device+0x60/0x130 __driver_attach+0xfc/0x220 bus_for_each_dev+0xa8/0x130 driver_attach+0x34/0x50 bus_add_driver+0x1b0/0x300 driver_register+0x98/0x1a0 __platform_driver_register+0x38/0x50 opal_prd_driver_init+0x34/0x50 [opal_prd] do_one_initcall+0x60/0x2d0 do_init_module+0x7c/0x320 load_module+0x3394/0x3650 __do_sys_finit_module+0xd4/0x160 system_call_exception+0x140/0x290 system_call_common+0xf4/0x258
Fixes: 587164cd593c ("powerpc/powernv: Add new opal message type") Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Vasant Hegde hegdevasant@linux.vnet.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211028165716.41300-1-hegdevasant@linux.vnet.ibm.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/powernv/opal-prd.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
--- a/arch/powerpc/platforms/powernv/opal-prd.c +++ b/arch/powerpc/platforms/powernv/opal-prd.c @@ -369,6 +369,12 @@ static struct notifier_block opal_prd_ev .priority = 0, };
+static struct notifier_block opal_prd_event_nb2 = { + .notifier_call = opal_prd_msg_notifier, + .next = NULL, + .priority = 0, +}; + static int opal_prd_probe(struct platform_device *pdev) { int rc; @@ -390,9 +396,10 @@ static int opal_prd_probe(struct platfor return rc; }
- rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb); + rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb2); if (rc) { pr_err("Couldn't register PRD2 event notifier\n"); + opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); return rc; }
@@ -401,6 +408,8 @@ static int opal_prd_probe(struct platfor pr_err("failed to register miscdev\n"); opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); + opal_message_notifier_unregister(OPAL_MSG_PRD2, + &opal_prd_event_nb2); return rc; }
@@ -411,6 +420,7 @@ static int opal_prd_remove(struct platfo { misc_deregister(&opal_prd_dev); opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); + opal_message_notifier_unregister(OPAL_MSG_PRD2, &opal_prd_event_nb2); return 0; }
From: Russell Currey ruscur@russell.cc
commit 3c12b4df8d5e026345a19886ae375b3ebc33c0b6 upstream.
The mitigation-patching.sh script in the powerpc selftests toggles all mitigations on and off simultaneously, revealing that rfi_flush and stf_barrier cannot safely operate at the same time due to races in updating the static key.
On some systems, the static key code throws a warning and the kernel remains functional. On others, the kernel will hang or crash.
Fix this by slapping on a mutex.
Fixes: 13799748b957 ("powerpc/64: use interrupt restart table to speed up return from interrupt") Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Russell Currey ruscur@russell.cc Acked-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211027072410.40950-1-ruscur@russell.cc Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/lib/feature-fixups.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -228,6 +228,7 @@ static void do_stf_exit_barrier_fixups(e
static bool stf_exit_reentrant = false; static bool rfi_exit_reentrant = false; +static DEFINE_MUTEX(exit_flush_lock);
static int __do_stf_barrier_fixups(void *data) { @@ -253,6 +254,9 @@ void do_stf_barrier_fixups(enum stf_barr * low level interrupt exit code before patching. After the patching, * if allowed, then flip the branch to allow fast exits. */ + + // Prevent static key update races with do_rfi_flush_fixups() + mutex_lock(&exit_flush_lock); static_branch_enable(&interrupt_exit_not_reentrant);
stop_machine(__do_stf_barrier_fixups, &types, NULL); @@ -264,6 +268,8 @@ void do_stf_barrier_fixups(enum stf_barr
if (stf_exit_reentrant && rfi_exit_reentrant) static_branch_disable(&interrupt_exit_not_reentrant); + + mutex_unlock(&exit_flush_lock); }
void do_uaccess_flush_fixups(enum l1d_flush_type types) @@ -486,6 +492,9 @@ void do_rfi_flush_fixups(enum l1d_flush_ * without stop_machine, so this could be achieved with a broadcast * IPI instead, but this matches the stf sequence. */ + + // Prevent static key update races with do_stf_barrier_fixups() + mutex_lock(&exit_flush_lock); static_branch_enable(&interrupt_exit_not_reentrant);
stop_machine(__do_rfi_flush_fixups, &types, NULL); @@ -497,6 +506,8 @@ void do_rfi_flush_fixups(enum l1d_flush_
if (stf_exit_reentrant && rfi_exit_reentrant) static_branch_disable(&interrupt_exit_not_reentrant); + + mutex_unlock(&exit_flush_lock); }
void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)
From: Nicholas Piggin npiggin@gmail.com
commit 4a5cb51f3db4be547225a4bce7a43d41b231382b upstream.
The check_return_regs_valid() can cause a false positive if the return regs are marked as norestart and they are an HSRR type interrupt, because the low bit in the bottom of regs->trap causes interrupt type matching to fail.
This can occcur for example on bare metal with a HV privileged doorbell interrupt that causes a signal, but do_signal returns early because get_signal() fails, and takes the "No signal to deliver" path. In this case no signal was delivered so the return location is not changed so return SRRs are not invalidated, yet set_trap_norestart is called, which messes up the match. Building go-1.16.6 is known to reproduce this.
Fix it by using the TRAP() accessor which masks out the low bit.
Fixes: 6eaaf9de3599 ("powerpc/64s/interrupt: Check and fix srr_valid without crashing") Cc: stable@vger.kernel.org # v5.14+ Signed-off-by: Nicholas Piggin npiggin@gmail.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211026122531.3599918-1-npiggin@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/kernel/interrupt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -266,7 +266,7 @@ static void check_return_regs_valid(stru if (trap_is_scv(regs)) return;
- trap = regs->trap; + trap = TRAP(regs); // EE in HV mode sets HSRRs like 0xea0 if (cpu_has_feature(CPU_FTR_HVMODE) && trap == INTERRUPT_EXTERNAL) trap = 0xea0;
From: Nathan Lynch nathanl@linux.ibm.com
commit 319fa1a52e438a6e028329187783a25ad498c4e6 upstream.
On VMs with NX encryption, compression, and/or RNG offload, these capabilities are described by nodes in the ibm,platform-facilities device tree hierarchy:
$ tree -d /sys/firmware/devicetree/base/ibm,platform-facilities/ /sys/firmware/devicetree/base/ibm,platform-facilities/ ├── ibm,compression-v1 ├── ibm,random-v1 └── ibm,sym-encryption-v1
3 directories
The acceleration functions that these nodes describe are not disrupted by live migration, not even temporarily.
But the post-migration ibm,update-nodes sequence firmware always sends "delete" messages for this hierarchy, followed by an "add" directive to reconstruct it via ibm,configure-connector (log with debugging statements enabled in mobility.c):
mobility: removing node /ibm,platform-facilities/ibm,random-v1:4294967285 mobility: removing node /ibm,platform-facilities/ibm,compression-v1:4294967284 mobility: removing node /ibm,platform-facilities/ibm,sym-encryption-v1:4294967283 mobility: removing node /ibm,platform-facilities:4294967286 ... mobility: added node /ibm,platform-facilities:4294967286
Note we receive a single "add" message for the entire hierarchy, and what we receive from the ibm,configure-connector sequence is the top-level platform-facilities node along with its three children. The debug message simply reports the parent node and not the whole subtree.
Also, significantly, the nodes added are almost completely equivalent to the ones removed; even phandles are unchanged. ibm,shared-interrupt-pool in the leaf nodes is the only property I've observed to differ, and Linux does not use that. So in practice, the sum of update messages Linux receives for this hierarchy is equivalent to minor property updates.
We succeed in removing the original hierarchy from the device tree. But the vio bus code is ignorant of this, and does not unbind or relinquish its references. The leaf nodes, still reachable through sysfs, of course still refer to the now-freed ibm,platform-facilities parent node, which makes use-after-free possible:
refcount_t: addition on 0; use-after-free. WARNING: CPU: 3 PID: 1706 at lib/refcount.c:25 refcount_warn_saturate+0x164/0x1f0 refcount_warn_saturate+0x160/0x1f0 (unreliable) kobject_get+0xf0/0x100 of_node_get+0x30/0x50 of_get_parent+0x50/0xb0 of_fwnode_get_parent+0x54/0x90 fwnode_count_parents+0x50/0x150 fwnode_full_name_string+0x30/0x110 device_node_string+0x49c/0x790 vsnprintf+0x1c0/0x4c0 sprintf+0x44/0x60 devspec_show+0x34/0x50 dev_attr_show+0x40/0xa0 sysfs_kf_seq_show+0xbc/0x200 kernfs_seq_show+0x44/0x60 seq_read_iter+0x2a4/0x740 kernfs_fop_read_iter+0x254/0x2e0 new_sync_read+0x120/0x190 vfs_read+0x1d0/0x240
Moreover, the "new" replacement subtree is not correctly added to the device tree, resulting in ibm,platform-facilities parent node without the appropriate leaf nodes, and broken symlinks in the sysfs device hierarchy:
$ tree -d /sys/firmware/devicetree/base/ibm,platform-facilities/ /sys/firmware/devicetree/base/ibm,platform-facilities/
0 directories
$ cd /sys/devices/vio ; find . -xtype l -exec file {} + ./ibm,sym-encryption-v1/of_node: broken symbolic link to ../../../firmware/devicetree/base/ibm,platform-facilities/ibm,sym-encryption-v1 ./ibm,random-v1/of_node: broken symbolic link to ../../../firmware/devicetree/base/ibm,platform-facilities/ibm,random-v1 ./ibm,compression-v1/of_node: broken symbolic link to ../../../firmware/devicetree/base/ibm,platform-facilities/ibm,compression-v1
This is because add_dt_node() -> dlpar_attach_node() attaches only the parent node returned from configure-connector, ignoring any children. This should be corrected for the general case, but fixing that won't help with the stale OF node references, which is the more urgent problem.
One way to address that would be to make the drivers respond to node removal notifications, so that node references can be dropped appropriately. But this would likely force the drivers to disrupt active clients for no useful purpose: equivalent nodes are immediately re-added. And recall that the acceleration capabilities described by the nodes remain available throughout the whole process.
The solution I believe to be robust for this situation is to convert remove+add of a node with an unchanged phandle to an update of the node's properties in the Linux device tree structure. That would involve changing and adding a fair amount of code, and may take several iterations to land.
Until that can be realized we have a confirmed use-after-free and the possibility of memory corruption. So add a limited workaround that discriminates on the node type, ignoring adds and removes. This should be amenable to backporting in the meantime.
Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Cc: stable@vger.kernel.org Signed-off-by: Nathan Lynch nathanl@linux.ibm.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20211020194703.2613093-1-nathanl@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/pseries/mobility.c | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)
--- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -63,6 +63,27 @@ static int mobility_rtas_call(int token,
static int delete_dt_node(struct device_node *dn) { + struct device_node *pdn; + bool is_platfac; + + pdn = of_get_parent(dn); + is_platfac = of_node_is_type(dn, "ibm,platform-facilities") || + of_node_is_type(pdn, "ibm,platform-facilities"); + of_node_put(pdn); + + /* + * The drivers that bind to nodes in the platform-facilities + * hierarchy don't support node removal, and the removal directive + * from firmware is always followed by an add of an equivalent + * node. The capability (e.g. RNG, encryption, compression) + * represented by the node is never interrupted by the migration. + * So ignore changes to this part of the tree. + */ + if (is_platfac) { + pr_notice("ignoring remove operation for %pOFfp\n", dn); + return 0; + } + pr_debug("removing node %pOFfp\n", dn); dlpar_detach_node(dn); return 0; @@ -222,6 +243,19 @@ static int add_dt_node(struct device_nod if (!dn) return -ENOENT;
+ /* + * Since delete_dt_node() ignores this node type, this is the + * necessary counterpart. We also know that a platform-facilities + * node returned from dlpar_configure_connector() has children + * attached, and dlpar_attach_node() only adds the parent, leaking + * the children. So ignore these on the add side for now. + */ + if (of_node_is_type(dn, "ibm,platform-facilities")) { + pr_notice("ignoring add operation for %pOF\n", dn); + dlpar_free_cc_nodes(dn); + return 0; + } + rc = dlpar_attach_node(dn, parent_dn); if (rc) dlpar_free_cc_nodes(dn);
From: Xiaoming Ni nixiaoming@huawei.com
commit c45361abb9185b1e172bd75eff51ad5f601ccae4 upstream.
When CONFIG_SMP=y, timebase synchronization is required when the second kernel is started.
arch/powerpc/kernel/smp.c: int __cpu_up(unsigned int cpu, struct task_struct *tidle) { ... if (smp_ops->give_timebase) smp_ops->give_timebase(); ... }
void start_secondary(void *unused) { ... if (smp_ops->take_timebase) smp_ops->take_timebase(); ... }
When CONFIG_HOTPLUG_CPU=n and CONFIG_KEXEC_CORE=n, smp_85xx_ops.give_timebase is NULL, smp_85xx_ops.take_timebase is NULL, As a result, the timebase is not synchronized.
Timebase synchronization does not depend on CONFIG_HOTPLUG_CPU.
Fixes: 56f1ba280719 ("powerpc/mpc85xx: refactor the PM operations") Cc: stable@vger.kernel.org # v4.6+ Signed-off-by: Xiaoming Ni nixiaoming@huawei.com Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://lore.kernel.org/r/20210929033646.39630-3-nixiaoming@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/85xx/Makefile | 4 +++- arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c | 4 ++++ arch/powerpc/platforms/85xx/smp.c | 12 ++++++------ 3 files changed, 13 insertions(+), 7 deletions(-)
--- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -3,7 +3,9 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o +ifneq ($(CONFIG_FSL_CORENET_RCPM),y) +obj-$(CONFIG_SMP) += mpc85xx_pm_ops.o +endif
obj-y += common.o
--- a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c @@ -17,6 +17,7 @@
static struct ccsr_guts __iomem *guts;
+#ifdef CONFIG_FSL_PMC static void mpc85xx_irq_mask(int cpu) {
@@ -49,6 +50,7 @@ static void mpc85xx_cpu_up_prepare(int c {
} +#endif
static void mpc85xx_freeze_time_base(bool freeze) { @@ -76,10 +78,12 @@ static const struct of_device_id mpc85xx
static const struct fsl_pm_ops mpc85xx_pm_ops = { .freeze_time_base = mpc85xx_freeze_time_base, +#ifdef CONFIG_FSL_PMC .irq_mask = mpc85xx_irq_mask, .irq_unmask = mpc85xx_irq_unmask, .cpu_die = mpc85xx_cpu_die, .cpu_up_prepare = mpc85xx_cpu_up_prepare, +#endif };
int __init mpc85xx_setup_pmc(void) --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -40,7 +40,6 @@ struct epapr_spin_table { u32 pir; };
-#ifdef CONFIG_HOTPLUG_CPU static u64 timebase; static int tb_req; static int tb_valid; @@ -112,6 +111,7 @@ static void mpc85xx_take_timebase(void) local_irq_restore(flags); }
+#ifdef CONFIG_HOTPLUG_CPU static void smp_85xx_cpu_offline_self(void) { unsigned int cpu = smp_processor_id(); @@ -495,21 +495,21 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.probe = NULL; }
-#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_FSL_CORENET_RCPM + /* Assign a value to qoriq_pm_ops on PPC_E500MC */ fsl_rcpm_init(); -#endif - -#ifdef CONFIG_FSL_PMC +#else + /* Assign a value to qoriq_pm_ops on !PPC_E500MC */ mpc85xx_setup_pmc(); #endif if (qoriq_pm_ops) { smp_85xx_ops.give_timebase = mpc85xx_give_timebase; smp_85xx_ops.take_timebase = mpc85xx_take_timebase; +#ifdef CONFIG_HOTPLUG_CPU smp_85xx_ops.cpu_offline_self = smp_85xx_cpu_offline_self; smp_85xx_ops.cpu_die = qoriq_cpu_kill; - } #endif + } smp_ops = &smp_85xx_ops;
#ifdef CONFIG_KEXEC_CORE
From: Jernej Skrabec jernej.skrabec@gmail.com
commit c302c98da646409d657a473da202f10f417f3ff1 upstream.
Macros SUN8I_CSC_CTRL() and SUN8I_CSC_COEFF() don't follow usual recommendation of having arguments enclosed in parenthesis. While that didn't change anything for quite sometime, it actually become important after CSC code rework with commit ea067aee45a8 ("drm/sun4i: de2/de3: Remove redundant CSC matrices").
Without this fix, colours are completely off for supported YVU formats on SoCs with DE2 (A64, H3, R40, etc.).
Fix the issue by enclosing macro arguments in parenthesis.
Cc: stable@vger.kernel.org # 5.12+ Fixes: 883029390550 ("drm/sun4i: Add DE2 CSC library") Reported-by: Roman Stratiienko r.stratiienko@gmail.com Signed-off-by: Jernej Skrabec jernej.skrabec@gmail.com Reviewed-by: Chen-Yu Tsai wens@csie.org Signed-off-by: Maxime Ripard maxime@cerno.tech Link: https://patchwork.freedesktop.org/patch/msgid/20210831184819.93670-1-jernej.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/sun4i/sun8i_csc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/sun4i/sun8i_csc.h +++ b/drivers/gpu/drm/sun4i/sun8i_csc.h @@ -16,8 +16,8 @@ struct sun8i_mixer; #define CCSC10_OFFSET 0xA0000 #define CCSC11_OFFSET 0xF0000
-#define SUN8I_CSC_CTRL(base) (base + 0x0) -#define SUN8I_CSC_COEFF(base, i) (base + 0x10 + 4 * i) +#define SUN8I_CSC_CTRL(base) ((base) + 0x0) +#define SUN8I_CSC_COEFF(base, i) ((base) + 0x10 + 4 * (i))
#define SUN8I_CSC_CTRL_EN BIT(0)
From: Pali Rohár pali@kernel.org
commit 460275f124fb072dca218a6b43b6370eebbab20d upstream.
Define a macro PCI_EXP_DEVCTL_PAYLOAD_* for every possible Max Payload Size in linux/pci_regs.h, in the same style as PCI_EXP_DEVCTL_READRQ_*.
Link: https://lore.kernel.org/r/20211005180952.6812-2-kabel@kernel.org Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Reviewed-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/uapi/linux/pci_regs.h | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -504,6 +504,12 @@ #define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ #define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */ #define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ +#define PCI_EXP_DEVCTL_PAYLOAD_128B 0x0000 /* 128 Bytes */ +#define PCI_EXP_DEVCTL_PAYLOAD_256B 0x0020 /* 256 Bytes */ +#define PCI_EXP_DEVCTL_PAYLOAD_512B 0x0040 /* 512 Bytes */ +#define PCI_EXP_DEVCTL_PAYLOAD_1024B 0x0060 /* 1024 Bytes */ +#define PCI_EXP_DEVCTL_PAYLOAD_2048B 0x0080 /* 2048 Bytes */ +#define PCI_EXP_DEVCTL_PAYLOAD_4096B 0x00a0 /* 4096 Bytes */ #define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ #define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ #define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
From: Pali Rohár pali@kernel.org
commit a4e17d65dafdd3513042d8f00404c9b6068a825c upstream.
Change PCIe Max Payload Size setting in PCIe Device Control register to 512 bytes to align with PCIe Link Initialization sequence as defined in Marvell Armada 3700 Functional Specification. According to the specification, maximal Max Payload Size supported by this device is 512 bytes.
Without this kernel prints suspicious line:
pci 0000:01:00.0: Upstream bridge's Max Payload Size set to 256 (was 16384, max 512)
With this change it changes to:
pci 0000:01:00.0: Upstream bridge's Max Payload Size set to 256 (was 512, max 512)
Link: https://lore.kernel.org/r/20211005180952.6812-3-kabel@kernel.org Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Marek Behún kabel@kernel.org Signed-off-by: Lorenzo Pieralisi lorenzo.pieralisi@arm.com Reviewed-by: Marek Behún kabel@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/pci/controller/pci-aardvark.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -597,8 +597,9 @@ static void advk_pcie_setup_hw(struct ad reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); reg &= ~PCI_EXP_DEVCTL_RELAX_EN; reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; + reg &= ~PCI_EXP_DEVCTL_PAYLOAD; reg &= ~PCI_EXP_DEVCTL_READRQ; - reg |= PCI_EXP_DEVCTL_PAYLOAD; /* Set max payload size */ + reg |= PCI_EXP_DEVCTL_PAYLOAD_512B; reg |= PCI_EXP_DEVCTL_READRQ_512B; advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL);
From: Trond Myklebust trond.myklebust@hammerspace.com
commit ea7a1019d8baf8503ecd6e3ec8436dec283569e6 upstream.
The premise of commit 6f9f17287e78 ("SUNRPC: Mitigate cond_resched() in xprt_transmit()") was that cond_resched() is expensive and unnecessary when there has been just a single send. The point of cond_resched() is to ensure that tasks that should pre-empt this one get a chance to do so when it is safe to do so. The code prior to commit 6f9f17287e78 failed to take into account that it was keeping a rpc_task pinned for longer than it needed to, and so rather than doing a full revert, let's just move the cond_resched.
Signed-off-by: Trond Myklebust trond.myklebust@hammerspace.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/sunrpc/xprt.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
--- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1603,15 +1603,14 @@ xprt_transmit(struct rpc_task *task) { struct rpc_rqst *next, *req = task->tk_rqstp; struct rpc_xprt *xprt = req->rq_xprt; - int counter, status; + int status;
spin_lock(&xprt->queue_lock); - counter = 0; - while (!list_empty(&xprt->xmit_queue)) { - if (++counter == 20) + for (;;) { + next = list_first_entry_or_null(&xprt->xmit_queue, + struct rpc_rqst, rq_xmit); + if (!next) break; - next = list_first_entry(&xprt->xmit_queue, - struct rpc_rqst, rq_xmit); xprt_pin_rqst(next); spin_unlock(&xprt->queue_lock); status = xprt_request_transmit(next, task); @@ -1619,13 +1618,16 @@ xprt_transmit(struct rpc_task *task) status = 0; spin_lock(&xprt->queue_lock); xprt_unpin_rqst(next); - if (status == 0) { - if (!xprt_request_data_received(task) || - test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) - continue; - } else if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) - task->tk_status = status; - break; + if (status < 0) { + if (test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) + task->tk_status = status; + break; + } + /* Was @task transmitted, and has it received a reply? */ + if (xprt_request_data_received(task) && + !test_bit(RPC_TASK_NEED_XMIT, &task->tk_runstate)) + break; + cond_resched_lock(&xprt->queue_lock); } spin_unlock(&xprt->queue_lock); }
From: Mario Limonciello mario.limonciello@amd.com
commit 91adec9e07097e538691daed5d934e7886dd1dc3 upstream.
commit 652de07addd2 ("drm/amd/display: Fully switch to dmub for all dcn21 asics") switched over to using dmub on Renoir to fix Gitlab 1735, but this implied a new dependency on newer firmware which might not be met on older kernel versions.
Since sw_init runs before hw_init, there is an opportunity to determine whether or not the firmware version is new to adjust the behavior.
Cc: Roman.Li@amd.com BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1772 BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1735 Fixes: 652de07addd2 ("drm/amd/display: Fully switch to dmub for all dcn21 asics") Signed-off-by: Mario Limonciello mario.limonciello@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Roman Li Roman.Li@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.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1141,8 +1141,15 @@ static int amdgpu_dm_init(struct amdgpu_ case CHIP_RAVEN: case CHIP_RENOIR: init_data.flags.gpu_vm_support = true; - if (ASICREV_IS_GREEN_SARDINE(adev->external_rev_id)) + switch (adev->dm.dmcub_fw_version) { + case 0: /* development */ + case 0x1: /* linux-firmware.git hash 6d9f399 */ + case 0x01000000: /* linux-firmware.git hash 9a0b0f4 */ + init_data.flags.disable_dmcu = false; + break; + default: init_data.flags.disable_dmcu = true; + } break; case CHIP_VANGOGH: case CHIP_YELLOW_CARP:
On 11/15/21 9:51 AM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On Mon, 15 Nov 2021 17:51:35 +0100, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
5.15.3-rc1 Successfully Compiled and booted on my Raspberry PI 4b (8g) (bcm2711)
Tested-by: Fox Chen foxhlchen@gmail.com
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 device. Following kernel crash reported on stable-rc 5.15.
metadata: git branch: linux-5.15.y git repo: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc git commit: ff5232812521d01d1ddfd8f36559a9cf83fea928 git describe: v5.15.2-918-gff5232812521 make_kernelversion: 5.15.3-rc1 kernel-config: https://builds.tuxbuild.com/20yUV5tYmCSzjklEffg3Dhkbdzi/config
Kernel crash log: ----------------- [ 1.178361] kvm [1]: Hyp mode initialized successfully [ 1.184780] Unable to handle kernel NULL pointer dereference at virtual address 000000000000019b [ 1.193599] Mem abort info: [ 1.196394] ESR = 0x96000044 [ 1.199458] EC = 0x25: DABT (current EL), IL = 32 bits [ 1.204786] SET = 0, FnV = 0 [ 1.207848] EA = 0, S1PTW = 0 [ 1.210998] FSC = 0x04: level 0 translation fault [ 1.215889] Data abort info: [ 1.218777] ISV = 0, ISS = 0x00000044 [ 1.222623] CM = 0, WnR = 1 [ 1.225605] [000000000000019b] user address but active_mm is swapper [ 1.231979] Internal error: Oops: 96000044 [#1] PREEMPT SMP [ 1.237559] Modules linked in: [ 1.240617] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.3-rc1 #1 [ 1.246894] Hardware name: ARM Juno development board (r2) (DT) [ 1.252820] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 1.259793] pc : crypto_register_alg+0x88/0xe4 [ 1.264246] lr : crypto_register_alg+0x78/0xe4 [ 1.268694] sp : ffff800012b9bce0 [ 1.272008] x29: ffff800012b9bce0 x28: 0000000000000000 x27: ffff800012644c80 [ 1.279162] x26: ffff000820d95480 x25: ffff000820d96000 x24: ffff800012644d3a [ 1.286313] x23: ffff800012644cba x22: 0000000000000000 x21: ffff800012742518 [ 1.293463] x20: 0000000000000000 x19: ffffffffffffffef x18: ffffffffffffffff [ 1.300614] x17: 000000000000003f x16: 0000000000000010 x15: ffff000800844a1c [ 1.307765] x14: 0000000000000001 x13: 293635326168732c x12: 2973656128636263 [ 1.314916] x11: 0000000000000010 x10: 0101010101010101 x9 : ffff80001054b5a8 [ 1.322066] x8 : 7f7f7f7f7f7f7f7f x7 : fefefefefeff6462 x6 : 0000808080808080 [ 1.329217] x5 : 0000000000000000 x4 : 8080808080800000 x3 : 0000000000000000 [ 1.336367] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff800012742518 [ 1.343517] Call trace: [ 1.345962] crypto_register_alg+0x88/0xe4 [ 1.350062] crypto_register_skcipher+0x80/0x9c [ 1.354600] simd_skcipher_create_compat+0x19c/0x1d0 [ 1.359572] cpu_feature_match_AES_init+0x9c/0xdc [ 1.364284] do_one_initcall+0x50/0x2b0 [ 1.368125] kernel_init_freeable+0x250/0x2d8 [ 1.372488] kernel_init+0x30/0x140 [ 1.375981] ret_from_fork+0x10/0x20 [ 1.379562] Code: 2a0003f6 710002df aa1503e0 1a9fd7e1 (3906b261) [ 1.385667] ---[ end trace a032e96fc9ec202d ]--- [ 1.390350] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 1.398018] SMP: stopping secondary CPUs [ 1.401947] Kernel Offset: disabled [ 1.405434] CPU features: 0x10001871,00000846 [ 1.409794] Memory Limit: none [ 1.412849] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
build link: ----------- https://builds.tuxbuild.com/20yUV5tYmCSzjklEffg3Dhkbdzi/build.log
build config: ------------- https://builds.tuxbuild.com/20yUV5tYmCSzjklEffg3Dhkbdzi/config
-- Linaro LKFT https://lkft.linaro.org
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
metadata: git branch: linux-5.15.y git repo: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc git commit: ff5232812521d01d1ddfd8f36559a9cf83fea928 git describe: v5.15.2-918-gff5232812521 make_kernelversion: 5.15.3-rc1 kernel-config: https://builds.tuxbuild.com/20yUV5tYmCSzjklEffg3Dhkbdzi/config
Kernel crash log:
[ 1.178361] kvm [1]: Hyp mode initialized successfully [ 1.184780] Unable to handle kernel NULL pointer dereference at virtual address 000000000000019b [ 1.193599] Mem abort info: [ 1.196394] ESR = 0x96000044 [ 1.199458] EC = 0x25: DABT (current EL), IL = 32 bits [ 1.204786] SET = 0, FnV = 0 [ 1.207848] EA = 0, S1PTW = 0 [ 1.210998] FSC = 0x04: level 0 translation fault [ 1.215889] Data abort info: [ 1.218777] ISV = 0, ISS = 0x00000044 [ 1.222623] CM = 0, WnR = 1 [ 1.225605] [000000000000019b] user address but active_mm is swapper [ 1.231979] Internal error: Oops: 96000044 [#1] PREEMPT SMP [ 1.237559] Modules linked in: [ 1.240617] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.3-rc1 #1 [ 1.246894] Hardware name: ARM Juno development board (r2) (DT) [ 1.252820] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 1.259793] pc : crypto_register_alg+0x88/0xe4 [ 1.264246] lr : crypto_register_alg+0x78/0xe4 [ 1.268694] sp : ffff800012b9bce0 [ 1.272008] x29: ffff800012b9bce0 x28: 0000000000000000 x27: ffff800012644c80 [ 1.279162] x26: ffff000820d95480 x25: ffff000820d96000 x24: ffff800012644d3a [ 1.286313] x23: ffff800012644cba x22: 0000000000000000 x21: ffff800012742518 [ 1.293463] x20: 0000000000000000 x19: ffffffffffffffef x18: ffffffffffffffff [ 1.300614] x17: 000000000000003f x16: 0000000000000010 x15: ffff000800844a1c [ 1.307765] x14: 0000000000000001 x13: 293635326168732c x12: 2973656128636263 [ 1.314916] x11: 0000000000000010 x10: 0101010101010101 x9 : ffff80001054b5a8 [ 1.322066] x8 : 7f7f7f7f7f7f7f7f x7 : fefefefefeff6462 x6 : 0000808080808080 [ 1.329217] x5 : 0000000000000000 x4 : 8080808080800000 x3 : 0000000000000000 [ 1.336367] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff800012742518 [ 1.343517] Call trace: [ 1.345962] crypto_register_alg+0x88/0xe4 [ 1.350062] crypto_register_skcipher+0x80/0x9c [ 1.354600] simd_skcipher_create_compat+0x19c/0x1d0 [ 1.359572] cpu_feature_match_AES_init+0x9c/0xdc [ 1.364284] do_one_initcall+0x50/0x2b0 [ 1.368125] kernel_init_freeable+0x250/0x2d8 [ 1.372488] kernel_init+0x30/0x140 [ 1.375981] ret_from_fork+0x10/0x20 [ 1.379562] Code: 2a0003f6 710002df aa1503e0 1a9fd7e1 (3906b261) [ 1.385667] ---[ end trace a032e96fc9ec202d ]--- [ 1.390350] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 1.398018] SMP: stopping secondary CPUs [ 1.401947] Kernel Offset: disabled [ 1.405434] CPU features: 0x10001871,00000846 [ 1.409794] Memory Limit: none [ 1.412849] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---
Reported-by: Linux Kernel Functional Testing lkft@linaro.org
build link:
https://builds.tuxbuild.com/20yUV5tYmCSzjklEffg3Dhkbdzi/build.log
build config:
https://builds.tuxbuild.com/20yUV5tYmCSzjklEffg3Dhkbdzi/config
- Naresh
On Tue, Nov 16, 2021 at 02:09:44PM +0530, Naresh Kamboju wrote:
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
Is this also an issue on 5.16-rc1?
thanks,
greg k-h
On 16/11/2021 08:48, Greg Kroah-Hartman wrote:
On Tue, Nov 16, 2021 at 02:09:44PM +0530, Naresh Kamboju wrote:
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
I am seeing the same for Tegra as well and bisect is pointing to the above for me too.
Is this also an issue on 5.16-rc1?
I have not observed the same issue for 5.16-rc1.
Jon
Hi Jon,
On Tue, Nov 16, 2021 at 10:23 AM Jon Hunter jonathanh@nvidia.com wrote:
On 16/11/2021 08:48, Greg Kroah-Hartman wrote:
On Tue, Nov 16, 2021 at 02:09:44PM +0530, Naresh Kamboju wrote:
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
That's commit adad556efcdd ("crypto: api - Fix built-in testing dependency failures")
I am seeing the same for Tegra as well and bisect is pointing to the above for me too.
Is this also an issue on 5.16-rc1?
I have not observed the same issue for 5.16-rc1.
Following the "Fixes: adad556efcdd" chain:
cad439fc040efe5f ("crypto: api - Do not create test larvals if manager is disabled") beaaaa37c664e9af ("crypto: api - Fix boot-up crash when crypto manager is disabled")
Gr{oetje,eeting}s,
Geert
-- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Tue, Nov 16, 2021 at 11:12:23AM +0100, Geert Uytterhoeven wrote:
Hi Jon,
On Tue, Nov 16, 2021 at 10:23 AM Jon Hunter jonathanh@nvidia.com wrote:
On 16/11/2021 08:48, Greg Kroah-Hartman wrote:
On Tue, Nov 16, 2021 at 02:09:44PM +0530, Naresh Kamboju wrote:
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
That's commit adad556efcdd ("crypto: api - Fix built-in testing dependency failures")
I am seeing the same for Tegra as well and bisect is pointing to the above for me too.
Is this also an issue on 5.16-rc1?
I have not observed the same issue for 5.16-rc1.
Following the "Fixes: adad556efcdd" chain:
cad439fc040efe5f ("crypto: api - Do not create test larvals if manager is disabled") beaaaa37c664e9af ("crypto: api - Fix boot-up crash when crypto manager is disabled")
Argh, yes, I didn't run my "check for fixes for patches in the queue" script which would have caught these. I'll go queue these up and a few others that it just caught...
thanks,
greg k-h
On Tue, Nov 16, 2021 at 11:39:52AM +0100, Greg Kroah-Hartman wrote:
On Tue, Nov 16, 2021 at 11:12:23AM +0100, Geert Uytterhoeven wrote:
Hi Jon,
On Tue, Nov 16, 2021 at 10:23 AM Jon Hunter jonathanh@nvidia.com wrote:
On 16/11/2021 08:48, Greg Kroah-Hartman wrote:
On Tue, Nov 16, 2021 at 02:09:44PM +0530, Naresh Kamboju wrote:
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote: > > This is the start of the stable review cycle for the 5.15.3 release. > There are 917 patches in this series, all will be posted as a response > to this one. If anyone has any issues with these being applied, please > let me know. > > Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... > or in the git tree and branch at: > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y > and the diffstat can be found below. > > thanks, > > greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
That's commit adad556efcdd ("crypto: api - Fix built-in testing dependency failures")
I am seeing the same for Tegra as well and bisect is pointing to the above for me too.
Is this also an issue on 5.16-rc1?
I have not observed the same issue for 5.16-rc1.
Following the "Fixes: adad556efcdd" chain:
cad439fc040efe5f ("crypto: api - Do not create test larvals if manager is disabled") beaaaa37c664e9af ("crypto: api - Fix boot-up crash when crypto manager is disabled")
Argh, yes, I didn't run my "check for fixes for patches in the queue" script which would have caught these. I'll go queue these up and a few others that it just caught...
Now fixed up, along with another "fix for the fix for the fix" patch that was needed.
greg k-h
On Tue, 16 Nov 2021 at 14:18, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
On Tue, Nov 16, 2021 at 02:09:44PM +0530, Naresh Kamboju wrote:
On Tue, 16 Nov 2021 at 12:06, Naresh Kamboju naresh.kamboju@linaro.org wrote:
On Tue, 16 Nov 2021 at 00:03, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 5.15.3 release. There are 917 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Wed, 17 Nov 2021 16:52:23 +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.3-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y and the diffstat can be found below.
thanks,
greg k-h
Regression found on arm64 juno-r2 / qemu. Following kernel crash reported on stable-rc 5.15.
Anders bisected this kernel crash and found the first bad commit,
Herbert Xu herbert@gondor.apana.org.au crypto: api - Fix built-in testing dependency failures
Is this also an issue on 5.16-rc1?
Not an issue on 5.16-rc1. 5.16-rc1 boot successful on arm64 juno-r2 / qemu-arm64.
- Naresh
linux-stable-mirror@lists.linaro.org