6.1.31-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 6.1.31-rc1 review
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +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/v6.x/stable-review/patch-6.1.31-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.1.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 6.1.31-rc1
David Epping <[email protected]>
net: phy: mscc: add VSC8502 to MODULE_DEVICE_TABLE
Christophe JAILLET <[email protected]>
3c589_cs: Fix an error handling path in tc589_probe()
Wen Gu <[email protected]>
net/smc: Reset connection when trying to use SMCRv2 fails.
Sen Chu <[email protected]>
regulator: mt6359: add read check for PMIC MT6359
Sudeep Holla <[email protected]>
firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors
Hugo Villeneuve <[email protected]>
arm64: dts: imx8mn-var-som: fix PHY detection bug by adding deassert delay
Shay Drory <[email protected]>
net/mlx5: Devcom, serialize devcom registration
Shay Drory <[email protected]>
net/mlx5: Devcom, fix error flow in mlx5_devcom_register_device
Shay Drory <[email protected]>
net/mlx5: Collect command failures data only for known commands
Roi Dayan <[email protected]>
net/mlx5: Fix error message when failing to allocate device memory
Yevgeny Kliteynik <[email protected]>
net/mlx5: DR, Check force-loopback RC QP capability independently from RoCE
Shay Drory <[email protected]>
net/mlx5: Handle pairing of E-switch via uplink un/load APIs
Erez Shitrit <[email protected]>
net/mlx5: DR, Fix crc32 calculation to work on big-endian (BE) CPUs
Jakub Kicinski <[email protected]>
net/mlx5e: do as little as possible in napi poll when budget is 0
Vlad Buslov <[email protected]>
net/mlx5e: Use correct encap attribute during invalidation
Vlad Buslov <[email protected]>
net/mlx5e: Fix deadlock in tc route query code
Rahul Rameshbabu <[email protected]>
net/mlx5e: Fix SQ wake logic in ptp napi_poll context
Dan Carpenter <[email protected]>
platform/mellanox: mlxbf-pmc: fix sscanf() error checking
Christophe JAILLET <[email protected]>
forcedeth: Fix an error handling path in nv_probe()
Xin Long <[email protected]>
sctp: fix an issue that plpmtu can never go to complete state
Dave Jiang <[email protected]>
cxl: Wait Memory_Info_Valid before access memory related info
Amadeusz Sławiński <[email protected]>
ASoC: Intel: avs: Access path components under lock
Cezary Rojewski <[email protected]>
ASoC: Intel: avs: Fix declaration of enum avs_channel_config
Cezary Rojewski <[email protected]>
ASoC: Intel: Skylake: Fix declaration of enum skl_ch_cfg
Vernon Lovejoy <[email protected]>
x86/show_trace_log_lvl: Ensure stack pointer is aligned, again
Dan Carpenter <[email protected]>
xen/pvcalls-back: fix double frees with pvcalls_new_active_socket()
Maximilian Heyne <[email protected]>
x86/pci/xen: populate MSI sysfs entries
Alexander Stein <[email protected]>
ARM: dts: imx6qdl-mba6: Add missing pvcie-supply regulator
Dan Carpenter <[email protected]>
coresight: Fix signedness bug in tmc_etr_buf_insert_barrier_packet()
Steve Wahl <[email protected]>
platform/x86: ISST: Remove 8 socket limit
Alexander Stein <[email protected]>
regulator: pca9450: Fix BUCK2 enable_mask
Hao Ge <[email protected]>
fs: fix undefined behavior in bit shift for SB_NOUSER
Sudeep Holla <[email protected]>
firmware: arm_ffa: Fix FFA device names for logical partitions
Sudeep Holla <[email protected]>
firmware: arm_ffa: Check if ffa_driver remove is present before executing
Etienne Carriere <[email protected]>
optee: fix uninited async notif value
Daisuke Nojiri <[email protected]>
power: supply: sbs-charger: Fix INHIBITED bit for Status reg
Hans de Goede <[email protected]>
power: supply: bq24190: Call power_supply_changed() after updating input current
Hans de Goede <[email protected]>
power: supply: bq25890: Call power_supply_changed() after updating input current or voltage
Hans de Goede <[email protected]>
power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to stabilize
Hans de Goede <[email protected]>
power: supply: bq27xxx: Ensure power_supply_changed() is called on current sign changes
Hans de Goede <[email protected]>
power: supply: bq27xxx: Move bq27xxx_battery_update() down
Hans de Goede <[email protected]>
power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status()
Hans de Goede <[email protected]>
power: supply: bq27xxx: Fix poll_interval handling and races on remove
Hans de Goede <[email protected]>
power: supply: bq27xxx: Fix I2C IRQ race on remove
Hans de Goede <[email protected]>
power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition
Kang Chen <[email protected]>
power: supply: mt6360: add a check of devm_work_autocancel in mt6360_charger_probe
Hans de Goede <[email protected]>
power: supply: leds: Fix blink to LED on transition
Steve French <[email protected]>
cifs: mapchars mount option ignored
Gavrilov Ilia <[email protected]>
ipv6: Fix out-of-bounds access in ipv6_find_tlv()
Horatiu Vultur <[email protected]>
lan966x: Fix unloading/loading of the driver
Anton Protopopov <[email protected]>
bpf: fix a memory leak in the LRU and LRU_PERCPU hash maps
Will Deacon <[email protected]>
bpf: Fix mask generation for 32-bit narrow loads of 64-bit fields
Sunil Goutham <[email protected]>
octeontx2-pf: Fix TSOv6 offload
Po-Hsu Lin <[email protected]>
selftests: fib_tests: mute cleanup error message
Matthew Auld <[email protected]>
drm: fix drmm_mutex_init()
Pratyush Yadav <[email protected]>
net: fix skb leak in __skb_tstamp_tx()
Ravulapati Vishnu Vardhan Rao <[email protected]>
ASoC: lpass: Fix for KASAN use_after_free out of bounds
Alan Stern <[email protected]>
media: radio-shark: Add endpoint checks
Alan Stern <[email protected]>
USB: sisusbvga: Add endpoint checks
Alan Stern <[email protected]>
USB: core: Add routines for endpoint checks in old drivers
Kuniyuki Iwashima <[email protected]>
udplite: Fix NULL pointer dereference in __sk_mem_raise_allocated().
Taehee Yoo <[email protected]>
net: fix stack overflow when LRO is disabled for virtual interfaces
Alan Stern <[email protected]>
fbdev: udlfb: Fix endpoint check
Tetsuo Handa <[email protected]>
debugobjects: Don't wake up kswapd from fill_pool()
Jiaxun Yang <[email protected]>
irqchip/mips-gic: Use raw spinlock for gic_lock
Jiaxun Yang <[email protected]>
irqchip/mips-gic: Don't touch vl_map if a local interrupt is not routable
Zhang Rui <[email protected]>
x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms
Kan Liang <[email protected]>
perf/x86/uncore: Correct the number of CHAs on SPR
Jack Xiao <[email protected]>
drm/amd/amdgpu: limit one queue per gang
Hardik Garg <[email protected]>
selftests/memfd: Fix unknown type name build failure
Carlos Llamas <[email protected]>
binder: fix UAF of alloc->vma in race with munmap()
Carlos Llamas <[email protected]>
binder: fix UAF caused by faulty buffer cleanup
Carlos Llamas <[email protected]>
binder: add lockless binder_alloc_(set|get)_vma()
Carlos Llamas <[email protected]>
Revert "android: binder: stop saving a pointer to the VMA"
Carlos Llamas <[email protected]>
Revert "binder_alloc: add missing mmap_lock calls when using the VMA"
Jonatas Esteves <[email protected]>
drm/amd/pm: Fix output of pp_od_clk_voltage
Evan Quan <[email protected]>
drm/amd/pm: add missing NotifyPowerSource message mapping for SMU13.0.7
Alex Deucher <[email protected]>
drm/radeon: reintroduce radeon_dp_work_func content
Jocelyn Falempe <[email protected]>
drm/mgag200: Fix gamma lut not initialized.
Frank Li <[email protected]>
dt-binding: cdns,usb3: Fix cdns,on-chip-buff-size type
Josef Bacik <[email protected]>
btrfs: use nofs when cleaning up aborted transactions
Zev Weiss <[email protected]>
gpio: mockup: Fix mode of debugfs files
Helge Deller <[email protected]>
parisc: Handle kprobes breakpoints only in kernel context
Helge Deller <[email protected]>
parisc: Enable LOCKDEP support
Helge Deller <[email protected]>
parisc: Allow to reboot machine after system halt
Helge Deller <[email protected]>
parisc: Fix flush_dcache_page() for usage from irq context
Helge Deller <[email protected]>
parisc: Handle kgdb breakpoints only in kernel context
Helge Deller <[email protected]>
parisc: Use num_present_cpus() in alternative patching code
Max Filippov <[email protected]>
xtensa: add __bswap{si,di}2 helpers
Max Filippov <[email protected]>
xtensa: fix signal delivery to FDPIC process
Finn Thain <[email protected]>
m68k: Move signal frame following exception on 68020/030
Tudor Ambarus <[email protected]>
net: cdc_ncm: Deal with too low values of dwNtbOutMaxSize
Matthias Kaehlcke <[email protected]>
ASoC: rt5682: Disable jack detection interrupt during suspend
Hans de Goede <[email protected]>
power: supply: bq25890: Fix external_power_changed race
Hans de Goede <[email protected]>
power: supply: axp288_fuel_gauge: Fix external_power_changed race
Christian Loehle <[email protected]>
mmc: block: ensure error propagation for non-blk
Haibo Chen <[email protected]>
mmc: sdhci-esdhc-imx: make "no-mmc-hs400" works
Trond Myklebust <[email protected]>
SUNRPC: Don't change task->tk_status after the call to rpc_exit_task
Bin Li <[email protected]>
ALSA: hda/realtek: Enable headset onLenovo M70/M90
Takashi Iwai <[email protected]>
ALSA: hda: Fix unhandled register update during auto-suspend period
Adam Stylinski <[email protected]>
ALSA: hda/ca0132: add quirk for EVGA X299 DARK
David Arcari <[email protected]>
platform/x86/intel/ifs: Annotate work queue on stack so object debug does not complain
Dave Hansen <[email protected]>
x86/mm: Avoid incomplete Global INVLPG flushes
Peter Collingbourne <[email protected]>
arm64: Also reset KASAN tag if page is not PG_mte_tagged
Roberto Sassu <[email protected]>
ocfs2: Switch to security_inode_init_security()
Robin Chen <[email protected]>
drm/amd/display: hpd rx irq not working with eDP interface
Steffen Bätz <[email protected]>
net: dsa: mv88e6xxx: Add RGMII delay to 88E6320
Hans de Goede <[email protected]>
platform/x86: hp-wmi: Fix cast to smaller integer type warning
Kees Cook <[email protected]>
skbuff: Proactively round up to kmalloc bucket size
Jack Xiao <[email protected]>
drm/amdgpu/mes11: enable reg active poll
Jack Xiao <[email protected]>
drm/amd/amdgpu: update mes11 api def
Gregory Oakes <[email protected]>
watchdog: sp5100_tco: Immediately trigger upon starting.
Jarkko Sakkinen <[email protected]>
tpm: Prevent hwrng from activating during resume
Jarkko Sakkinen <[email protected]>
tpm: Re-enable TPM chip boostrapping non-tpm_tis TPM drivers
Lino Sanfilippo <[email protected]>
tpm, tpm_tis: startup chip before testing for interrupts
Jarkko Sakkinen <[email protected]>
tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume
Lino Sanfilippo <[email protected]>
tpm, tpm_tis: Only handle supported interrupts
Lino Sanfilippo <[email protected]>
tpm, tpm_tis: Avoid cache incoherency in test for interrupts
Linyu Yuan <[email protected]>
usb: dwc3: fix gadget mode suspend interrupt handler issue
-------------
Diffstat:
.../devicetree/bindings/usb/cdns,usb3.yaml | 2 +- Makefile | 4 +- arch/arm/boot/dts/imx6qdl-mba6.dtsi | 1 + arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi | 8 +- arch/arm64/mm/copypage.c | 5 +- arch/m68k/kernel/signal.c | 14 +- arch/parisc/Kconfig | 4 + arch/parisc/include/asm/cacheflush.h | 4 + arch/parisc/kernel/alternative.c | 2 +- arch/parisc/kernel/cache.c | 5 +- arch/parisc/kernel/process.c | 11 +- arch/parisc/kernel/traps.c | 8 +- arch/x86/events/intel/uncore_snbep.c | 11 ++ arch/x86/kernel/cpu/topology.c | 5 +- arch/x86/kernel/dumpstack.c | 7 +- arch/x86/mm/init.c | 25 +++ arch/x86/pci/xen.c | 8 +- arch/xtensa/kernel/signal.c | 35 +++- arch/xtensa/kernel/xtensa_ksyms.c | 4 + arch/xtensa/lib/Makefile | 2 +- arch/xtensa/lib/bswapdi2.S | 21 +++ arch/xtensa/lib/bswapsi2.S | 16 ++ drivers/android/binder.c | 28 ++- drivers/android/binder_alloc.c | 64 ++++--- drivers/android/binder_alloc.h | 4 +- drivers/android/binder_alloc_selftest.c | 2 +- drivers/char/tpm/tpm-chip.c | 52 ++++-- drivers/char/tpm/tpm-interface.c | 10 ++ drivers/char/tpm/tpm.h | 1 + drivers/char/tpm/tpm_tis.c | 2 +- drivers/char/tpm/tpm_tis_core.c | 187 ++++++++++++--------- drivers/char/tpm/tpm_tis_core.h | 3 +- drivers/cxl/core/pci.c | 85 +++++++++- drivers/cxl/cxlpci.h | 2 + drivers/firmware/arm_ffa/bus.c | 19 ++- drivers/firmware/arm_ffa/driver.c | 6 + drivers/gpio/gpio-mockup.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 9 +- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 1 + drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 +- drivers/gpu/drm/amd/display/dc/dc_types.h | 6 + drivers/gpu/drm/amd/include/mes_v11_api_def.h | 6 +- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 12 +- .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 1 + drivers/gpu/drm/drm_managed.c | 22 +-- drivers/gpu/drm/mgag200/mgag200_mode.c | 5 + drivers/gpu/drm/radeon/radeon_irq_kms.c | 10 ++ drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +- drivers/irqchip/irq-mips-gic.c | 32 ++-- drivers/media/radio/radio-shark.c | 10 ++ drivers/media/radio/radio-shark2.c | 10 ++ drivers/mmc/core/block.c | 5 + drivers/mmc/host/sdhci-esdhc-imx.c | 18 +- drivers/net/bonding/bond_main.c | 8 +- drivers/net/dsa/mv88e6xxx/chip.c | 2 + drivers/net/dsa/mv88e6xxx/port.c | 9 + drivers/net/dsa/mv88e6xxx/port.h | 2 + drivers/net/ethernet/3com/3c589_cs.c | 11 +- .../net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 3 +- drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c | 2 + .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h | 2 + drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 23 +-- drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 19 ++- drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c | 16 +- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 4 + .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 7 +- .../net/ethernet/mellanox/mlx5/core/lib/devcom.c | 70 ++++++-- .../net/ethernet/mellanox/mlx5/core/lib/devcom.h | 1 + drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- .../ethernet/mellanox/mlx5/core/steering/dr_cmd.c | 4 +- .../ethernet/mellanox/mlx5/core/steering/dr_ste.c | 3 +- .../net/ethernet/microchip/lan966x/lan966x_main.c | 10 ++ drivers/net/ethernet/nvidia/forcedeth.c | 1 + drivers/net/phy/mscc/mscc_main.c | 1 + drivers/net/team/team.c | 7 +- drivers/net/usb/cdc_ncm.c | 24 ++- drivers/platform/mellanox/mlxbf-pmc.c | 5 +- drivers/platform/x86/hp/hp-wmi.c | 2 +- drivers/platform/x86/intel/ifs/load.c | 2 +- .../x86/intel/speed_select_if/isst_if_common.c | 12 +- drivers/power/supply/axp288_fuel_gauge.c | 2 +- drivers/power/supply/bq24190_charger.c | 1 + drivers/power/supply/bq25890_charger.c | 5 +- drivers/power/supply/bq27xxx_battery.c | 175 ++++++++++--------- drivers/power/supply/bq27xxx_battery_i2c.c | 3 +- drivers/power/supply/mt6360_charger.c | 4 +- drivers/power/supply/power_supply_leds.c | 5 +- drivers/power/supply/sbs-charger.c | 2 +- drivers/regulator/mt6359-regulator.c | 7 +- drivers/regulator/pca9450-regulator.c | 4 +- drivers/tee/optee/smc_abi.c | 4 +- drivers/usb/core/usb.c | 76 +++++++++ drivers/usb/dwc3/core.h | 2 + drivers/usb/dwc3/gadget.c | 10 +- drivers/usb/misc/sisusbvga/sisusb.c | 14 ++ drivers/video/fbdev/udlfb.c | 13 +- drivers/watchdog/sp5100_tco.c | 4 + drivers/xen/pvcalls-back.c | 9 +- fs/btrfs/disk-io.c | 9 + fs/cifs/fs_context.c | 8 + fs/ocfs2/namei.c | 2 + fs/ocfs2/xattr.c | 30 +++- include/drm/drm_managed.h | 18 +- include/linux/arm_ffa.h | 1 + include/linux/fs.h | 42 ++--- include/linux/if_team.h | 1 + include/linux/mlx5/mlx5_ifc.h | 4 +- include/linux/msi.h | 9 +- include/linux/power/bq27xxx_battery.h | 4 + include/linux/tpm.h | 14 +- include/linux/usb.h | 5 + include/net/bonding.h | 1 + include/uapi/sound/skl-tplg-interface.h | 3 +- kernel/bpf/hashtab.c | 6 +- kernel/bpf/verifier.c | 2 +- kernel/irq/msi.c | 4 +- lib/debugobjects.c | 2 +- net/core/skbuff.c | 56 +++--- net/ipv4/udplite.c | 2 + net/ipv6/exthdrs_core.c | 2 + net/ipv6/udplite.c | 2 + net/sctp/transport.c | 11 +- net/smc/af_smc.c | 9 +- net/smc/smc_core.c | 1 + net/sunrpc/sched.c | 5 +- sound/hda/hdac_device.c | 2 +- sound/pci/hda/patch_ca0132.c | 1 + sound/pci/hda/patch_realtek.c | 2 + sound/soc/codecs/lpass-tx-macro.c | 5 + sound/soc/codecs/rt5682-i2c.c | 4 +- sound/soc/codecs/rt5682.c | 6 + sound/soc/codecs/rt5682.h | 1 + sound/soc/intel/avs/apl.c | 6 +- sound/soc/intel/avs/messages.h | 2 +- tools/testing/selftests/memfd/fuse_test.c | 1 + tools/testing/selftests/net/fib_tests.sh | 2 +- 138 files changed, 1201 insertions(+), 511 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/119 usb: dwc3: fix gadget mode suspend interrupt handler issue
From: Linyu Yuan <[email protected]>
[ Upstream commit 4e8ef34e36f2839ef8c8da521ab7035956436818 ]
When work in gadget mode, currently driver doesn't update software level link_state correctly as link state change event is not enabled for most devices, in function dwc3_gadget_suspend_interrupt(), it will only pass suspend event to UDC core when software level link state changes, so when interrupt generated in sequences of suspend -> reset -> conndone -> suspend, link state is not updated during reset and conndone, so second suspend interrupt event will not pass to UDC core.
Remove link_state compare in dwc3_gadget_suspend_interrupt() and add a suspended flag to replace the compare function.
--- drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/gadget.c | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-)
drivers/usb/dwc3/core.h +2 -0
@@ -1110,6 +1110,7 @@ struct dwc3_scratchpad_array {* 3 - Reserved * @dis_metastability_quirk: set to disable metastability quirk. * @dis_split_quirk: set to disable split boundary. +* @suspended: set to track suspend event due to U3/L2. * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. * @max_cfg_eps: current max number of IN eps used across all USB configs.
@@ -1327,6 +1328,7 @@ struct dwc3 { unsigned dis_split_quirk:1; unsigned async_callbacks:1; + unsigned suspended:1;u16 imod_interval;
drivers/usb/dwc3/gadget.c +9 -1
@@ -3828,6 +3828,8 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) {int reg; + dwc->suspended = false; +dwc3_gadget_set_link_state (dwc,DWC3_LINK_STATE_RX_DET ); reg =dwc3_readl (dwc->regs,DWC3_DCTL );
@@ -3859,6 +3861,8 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) {u32 reg; + dwc->suspended = false; +/* * Ideally, dwc3_reset_gadget() would trigger the function * drivers to stop any active transfers through ep disable.
@@ -4088,6 +4092,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)static void dwc3_gadget_wakeup_interrupt (struct dwc3 *dwc) { + dwc->suspended = false; +/* * TODO take core out of low power mode when that's * implemented.
@@ -4203,8 +4209,10 @@ static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc, {enum dwc3_link_state next = evtinfo &DWC3_LINK_STATE_MASK ; -if (dwc->link_state != next && next ==DWC3_LINK_STATE_U3 ) +if (!dwc->suspended && next ==DWC3_LINK_STATE_U3 ) { + dwc->suspended = true;dwc3_suspend_gadget (dwc); + } dwc->link_state = next; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 2/119 tpm, tpm_tis: Avoid cache incoherency in test for interrupts
In reply to Greg Kroah-HartmanFrom: Lino Sanfilippo <[email protected]>
[ Upstream commit 858e8b792d06f45c427897bd90205a1d90bf430f ]
The interrupt handler that sets the boolean variable irq_tested may run on another CPU as the thread that checks irq_tested as part of the irq test in tpm_tis_send().
Since nothing guarantees cache coherency between CPUs for unsynchronized accesses to boolean variables the testing thread might not perceive the value change done in the interrupt handler.
Avoid this issue by setting the bit TPM_TIS_IRQ_TESTED in the flags field of the tpm_tis_data struct and by accessing this field with the bit manipulating functions that provide cache coherency.
Also convert all other existing sites to use the proper macros when accessing this bitfield.
Stable-dep-of: 1398aa803f19 ("tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume")
--- drivers/char/tpm/tpm_tis.c | 2 +- drivers/char/tpm/tpm_tis_core.c | 21 +++++++++++---------- drivers/char/tpm/tpm_tis_core.h | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-)
drivers/char/tpm/tpm_tis.c +1 -1
@@ -243,7 +243,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info) irq = tpm_info->irq;if (itpm ||is_itpm (ACPI_COMPANION (dev))) - phy->priv.flags |=TPM_TIS_ITPM_WORKAROUND ; +set_bit (TPM_TIS_ITPM_WORKAROUND , &phy->priv.flags);return tpm_tis_core_init (dev, &phy->priv, irq, &tpm_tcg,ACPI_HANDLE (dev));
drivers/char/tpm/tpm_tis_core.c +11 -10
@@ -376,7 +376,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)struct tpm_tis_data *priv =dev_get_drvdata (&chip->dev);int rc, status, burstcnt;size_t count =0 ; -bool itpm = priv->flags &TPM_TIS_ITPM_WORKAROUND ; +bool itpm =test_bit (TPM_TIS_ITPM_WORKAROUND , &priv->flags); status =tpm_tis_status (chip);if ((status &TPM_STS_COMMAND_READY ) ==0 ) {
@@ -509,7 +509,8 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)int rc, irq;struct tpm_tis_data *priv =dev_get_drvdata (&chip->dev); -if (!(chip->flags &TPM_CHIP_FLAG_IRQ ) || priv->irq_tested) +if (!(chip->flags &TPM_CHIP_FLAG_IRQ ) || +test_bit (TPM_TIS_IRQ_TESTED , &priv->flags))return tpm_tis_send_main (chip, buf, len);/* Verify receipt of the expected IRQ */
@@ -519,11 +520,11 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) rc =tpm_tis_send_main (chip, buf, len); priv->irq = irq; chip->flags |=TPM_CHIP_FLAG_IRQ ; -if (!priv->irq_tested) +if (!test_bit (TPM_TIS_IRQ_TESTED , &priv->flags))tpm_msleep (1 ); -if (!priv->irq_tested) +if (!test_bit (TPM_TIS_IRQ_TESTED , &priv->flags))disable_interrupts (chip); - priv->irq_tested = true; +set_bit (TPM_TIS_IRQ_TESTED , &priv->flags);return rc; }
@@ -666,7 +667,7 @@ static int probe_itpm(struct tpm_chip *chip)size_t len =sizeof (cmd_getticks);u16 vendor; -if (priv->flags &TPM_TIS_ITPM_WORKAROUND ) +if (test_bit (TPM_TIS_ITPM_WORKAROUND , &priv->flags))return 0 ; rc =tpm_tis_read16 (priv,TPM_DID_VID (0 ), &vendor);
@@ -686,13 +687,13 @@ static int probe_itpm(struct tpm_chip *chip)tpm_tis_ready (chip); - priv->flags |=TPM_TIS_ITPM_WORKAROUND ; +set_bit (TPM_TIS_ITPM_WORKAROUND , &priv->flags); rc =tpm_tis_send_data (chip, cmd_getticks, len);if (rc ==0 )dev_info (&chip->dev,"Detected an iTPM.\n" );else { - priv->flags &= ~TPM_TIS_ITPM_WORKAROUND ; +clear_bit (TPM_TIS_ITPM_WORKAROUND , &priv->flags); rc = -EFAULT ; }
@@ -736,7 +737,7 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)if (interrupt ==0 )return IRQ_NONE ; - priv->irq_tested = true; +set_bit (TPM_TIS_IRQ_TESTED , &priv->flags);if (interrupt &TPM_INTF_DATA_AVAIL_INT )wake_up_interruptible (&priv->read_queue);if (interrupt &TPM_INTF_LOCALITY_CHANGE_INT )
@@ -819,7 +820,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask,if (rc <0 ) goto restore_irqs; - priv->irq_tested = false; +clear_bit (TPM_TIS_IRQ_TESTED , &priv->flags);/* Generate an interrupt by having the core call through to * tpm_tis_send
drivers/char/tpm/tpm_tis_core.h +1 -1
@@ -87,6 +87,7 @@ enum tpm_tis_flags {TPM_TIS_ITPM_WORKAROUND =BIT (0 ),TPM_TIS_INVALID_STATUS =BIT (1 ),TPM_TIS_DEFAULT_CANCELLATION =BIT (2 ), + TPM_TIS_IRQ_TESTED = BIT(3), }; struct tpm_tis_data {
@@ -95,7 +96,6 @@ struct tpm_tis_data {unsigned int locality_count;int locality;int irq; -bool irq_tested;unsigned long flags;void __iomem *ilb_base_addr;u16 clkrun_enabled;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 3/119 tpm, tpm_tis: Only handle supported interrupts
In reply to Greg Kroah-HartmanFrom: Lino Sanfilippo <[email protected]>
[ Upstream commit e87fcf0dc2b47fac5b4824f00f74dfbcd4acd363 ]
According to the TPM Interface Specification (TIS) support for "stsValid" and "commandReady" interrupts is only optional.
This has to be taken into account when handling the interrupts in functions like wait_for_tpm_stat(). To determine the supported interrupts use the capability query.
Also adjust wait_for_tpm_stat() to only wait for interrupt reported status changes. After that process all the remaining status changes by polling the status register.
Stable-dep-of: 1398aa803f19 ("tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume")
--- drivers/char/tpm/tpm_tis_core.c | 120 +++++++++++++++++++------------- drivers/char/tpm/tpm_tis_core.h | 1 + 2 files changed, 73 insertions(+), 48 deletions(-)
drivers/char/tpm/tpm_tis_core.c +72 -48
@@ -53,41 +53,63 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,long rc;u8 status;bool canceled = false; +u8 sts_mask =0 ; +int ret =0 ;/* check current status */ status = chip->ops->status (chip);if ((status & mask) == mask)return 0 ; - stop = jiffies + timeout; +/* check what status changes can be handled by irqs */ +if (priv->int_mask &TPM_INTF_STS_VALID_INT ) + sts_mask |=TPM_STS_VALID ; -if (chip->flags &TPM_CHIP_FLAG_IRQ ) { +if (priv->int_mask &TPM_INTF_DATA_AVAIL_INT ) + sts_mask |=TPM_STS_DATA_AVAIL ; + +if (priv->int_mask &TPM_INTF_CMD_READY_INT ) + sts_mask |=TPM_STS_COMMAND_READY ; + + sts_mask &= mask; + + stop = jiffies + timeout; +/* process status changes with irq support */ +if (sts_mask) { + ret = -ETIME ; again: timeout = stop - jiffies;if ((long )timeout <=0 )return -ETIME ; rc =wait_event_interruptible_timeout (*queue, -wait_for_tpm_stat_cond (chip, mask, check_cancel, +wait_for_tpm_stat_cond (chip, sts_mask, check_cancel, &canceled), timeout);if (rc >0 ) {if (canceled)return -ECANCELED ; -return 0 ; + ret =0 ; }if (rc == -ERESTARTSYS &&freezing (current)) {clear_thread_flag (TIF_SIGPENDING ); goto again; } - }else { -do { -usleep_range (priv->timeout_min, - priv->timeout_max); - status = chip->ops->status (chip); -if ((status & mask) == mask) -return 0 ; - }while (time_before (jiffies, stop)); } + +if (ret) +return ret; + + mask &= ~sts_mask; +if (!mask)/* all done */ +return 0 ; +/* process status changes without irq support */ +do { + status = chip->ops->status (chip); +if ((status & mask) == mask) +return 0 ; +usleep_range (priv->timeout_min, + priv->timeout_max); + }while (time_before (jiffies, stop));return -ETIME ; }
@@ -1032,8 +1054,40 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,if (rc <0 ) goto out_err; - intmask |=TPM_INTF_CMD_READY_INT |TPM_INTF_LOCALITY_CHANGE_INT | -TPM_INTF_DATA_AVAIL_INT |TPM_INTF_STS_VALID_INT ; +/* Figure out the capabilities */ + rc =tpm_tis_read32 (priv,TPM_INTF_CAPS (priv->locality), &intfcaps); +if (rc <0 ) + goto out_err; + +dev_dbg (dev,"TPM interface capabilities (0x%x):\n" , + intfcaps); +if (intfcaps &TPM_INTF_BURST_COUNT_STATIC ) +dev_dbg (dev,"\tBurst Count Static\n" ); +if (intfcaps &TPM_INTF_CMD_READY_INT ) { + intmask |=TPM_INTF_CMD_READY_INT ; +dev_dbg (dev,"\tCommand Ready Int Support\n" ); + } +if (intfcaps &TPM_INTF_INT_EDGE_FALLING ) +dev_dbg (dev,"\tInterrupt Edge Falling\n" ); +if (intfcaps &TPM_INTF_INT_EDGE_RISING ) +dev_dbg (dev,"\tInterrupt Edge Rising\n" ); +if (intfcaps &TPM_INTF_INT_LEVEL_LOW ) +dev_dbg (dev,"\tInterrupt Level Low\n" ); +if (intfcaps &TPM_INTF_INT_LEVEL_HIGH ) +dev_dbg (dev,"\tInterrupt Level High\n" ); +if (intfcaps &TPM_INTF_LOCALITY_CHANGE_INT ) { + intmask |=TPM_INTF_LOCALITY_CHANGE_INT ; +dev_dbg (dev,"\tLocality Change Int Support\n" ); + } +if (intfcaps &TPM_INTF_STS_VALID_INT ) { + intmask |=TPM_INTF_STS_VALID_INT ; +dev_dbg (dev,"\tSts Valid Int Support\n" ); + } +if (intfcaps &TPM_INTF_DATA_AVAIL_INT ) { + intmask |=TPM_INTF_DATA_AVAIL_INT ; +dev_dbg (dev,"\tData Avail Int Support\n" ); + } + intmask &= ~TPM_GLOBAL_INT_ENABLE ; rc =tpm_tis_request_locality (chip,0 );
@@ -1067,32 +1121,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, goto out_err; } -/* Figure out the capabilities */ - rc =tpm_tis_read32 (priv,TPM_INTF_CAPS (priv->locality), &intfcaps); -if (rc <0 ) - goto out_err; - -dev_dbg (dev,"TPM interface capabilities (0x%x):\n" , - intfcaps); -if (intfcaps &TPM_INTF_BURST_COUNT_STATIC ) -dev_dbg (dev,"\tBurst Count Static\n" ); -if (intfcaps &TPM_INTF_CMD_READY_INT ) -dev_dbg (dev,"\tCommand Ready Int Support\n" ); -if (intfcaps &TPM_INTF_INT_EDGE_FALLING ) -dev_dbg (dev,"\tInterrupt Edge Falling\n" ); -if (intfcaps &TPM_INTF_INT_EDGE_RISING ) -dev_dbg (dev,"\tInterrupt Edge Rising\n" ); -if (intfcaps &TPM_INTF_INT_LEVEL_LOW ) -dev_dbg (dev,"\tInterrupt Level Low\n" ); -if (intfcaps &TPM_INTF_INT_LEVEL_HIGH ) -dev_dbg (dev,"\tInterrupt Level High\n" ); -if (intfcaps &TPM_INTF_LOCALITY_CHANGE_INT ) -dev_dbg (dev,"\tLocality Change Int Support\n" ); -if (intfcaps &TPM_INTF_STS_VALID_INT ) -dev_dbg (dev,"\tSts Valid Int Support\n" ); -if (intfcaps &TPM_INTF_DATA_AVAIL_INT ) -dev_dbg (dev,"\tData Avail Int Support\n" ); -/* INTERRUPT Setup */ init_waitqueue_head (&priv->read_queue);init_waitqueue_head (&priv->int_queue);
@@ -1123,7 +1151,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,else tpm_tis_probe_irq (chip, intmask); -if (!(chip->flags &TPM_CHIP_FLAG_IRQ )) { +if (chip->flags &TPM_CHIP_FLAG_IRQ ) { + priv->int_mask = intmask; + }else {dev_err (&chip->dev,FW_BUG "TPM interrupt not working, polling instead\n" );
@@ -1170,13 +1200,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)if (rc <0 ) goto out; - rc =tpm_tis_read32 (priv,TPM_INT_ENABLE (priv->locality), &intmask); -if (rc <0 ) - goto out; - - intmask |=TPM_INTF_CMD_READY_INT - |TPM_INTF_LOCALITY_CHANGE_INT |TPM_INTF_DATA_AVAIL_INT - |TPM_INTF_STS_VALID_INT |TPM_GLOBAL_INT_ENABLE ; + intmask = priv->int_mask |TPM_GLOBAL_INT_ENABLE ;tpm_tis_write32 (priv,TPM_INT_ENABLE (priv->locality), intmask);
drivers/char/tpm/tpm_tis_core.h +1 -0
@@ -96,6 +96,7 @@ struct tpm_tis_data {unsigned int locality_count;int locality;int irq; +unsigned int int_mask;unsigned long flags;void __iomem *ilb_base_addr;u16 clkrun_enabled;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 4/119 tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume
In reply to Greg Kroah-HartmanFrom: Jarkko Sakkinen <[email protected]>
[ Upstream commit 1398aa803f198b7a386fdd8404666043e95f4c16 ]
Before sending a TPM command, CLKRUN protocol must be disabled. This is not done in the case of tpm1_do_selftest() call site inside tpm_tis_resume().
Address this by decorating the calls with tpm_chip_{start,stop}, which should be always used to arm and disarm the TPM chip for transmission.
Finally, move the call to the main TPM driver callback as the last step because it should arm the chip by itself, if it needs that type of functionality.
--- drivers/char/tpm/tpm_tis_core.c | 43 +++++++++++++++------------------ 1 file changed, 19 insertions(+), 24 deletions(-)
drivers/char/tpm/tpm_tis_core.c +19 -24
@@ -1190,25 +1190,20 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)u32 intmask;int rc; -if (chip->ops->clk_enable !=NULL ) - chip->ops->clk_enable (chip, true); - -/* reenable interrupts that device may have lost or -* BIOS/firmware may have disabled +/* +* Re-enable interrupts that device may have lost or BIOS/firmware may +* have disabled. */ rc =tpm_tis_write8 (priv,TPM_INT_VECTOR (priv->locality), priv->irq); -if (rc <0 ) - goto out; +if (rc <0 ) { +dev_err (&chip->dev,"Setting IRQ failed.\n" ); +return ; + } intmask = priv->int_mask |TPM_GLOBAL_INT_ENABLE ; - -tpm_tis_write32 (priv,TPM_INT_ENABLE (priv->locality), intmask); - -out: -if (chip->ops->clk_enable !=NULL ) - chip->ops->clk_enable (chip, false); - -return ; + rc =tpm_tis_write32 (priv,TPM_INT_ENABLE (priv->locality), intmask); +if (rc <0 ) +dev_err (&chip->dev,"Enabling interrupts failed.\n" ); }int tpm_tis_resume (struct device *dev)
@@ -1216,27 +1211,27 @@ int tpm_tis_resume(struct device *dev)struct tpm_chip *chip =dev_get_drvdata (dev);int ret; - ret =tpm_tis_request_locality (chip,0 ); -if (ret <0 ) + ret =tpm_chip_start (chip); +if (ret)return ret;if (chip->flags &TPM_CHIP_FLAG_IRQ )tpm_tis_reenable_interrupts (chip); - ret =tpm_pm_resume (dev); -if (ret) - goto out; -/* * TPM 1.2 requires self-test on resume. This function actually returns * an error code but for unknown reason it isn't handled. */ if (!(chip->flags &TPM_CHIP_FLAG_TPM2 ))tpm1_do_selftest (chip); -out: -tpm_tis_relinquish_locality (chip,0 ); - return ret; +tpm_chip_stop (chip); + + ret =tpm_pm_resume (dev); +if (ret) +return ret; + + return 0; }EXPORT_SYMBOL_GPL (tpm_tis_resume);#endif
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 5/119 tpm, tpm_tis: startup chip before testing for interrupts
In reply to Greg Kroah-HartmanFrom: Lino Sanfilippo <[email protected]>
[ Upstream commit 548eb516ec0f7a484a23a902835899341164b8ea ]
In tpm_tis_gen_interrupt() a request for a property value is sent to the TPM to test if interrupts are generated. However after a power cycle the TPM responds with TPM_RC_INITIALIZE which indicates that the TPM is not yet properly initialized.
Fix this by first starting the TPM up before the request is sent. For this the startup implementation is removed from tpm_chip_register() and put into the new function tpm_chip_startup() which is called before the interrupts are tested.
Stable-dep-of: 99d464506255 ("tpm: Prevent hwrng from activating during resume")
--- drivers/char/tpm/tpm-chip.c | 38 +++++++++++++++++++++------------ drivers/char/tpm/tpm.h | 1 + drivers/char/tpm/tpm_tis_core.c | 5 +++++ 3 files changed, 30 insertions(+), 14 deletions(-)
drivers/char/tpm/tpm-chip.c +24 -14
@@ -601,6 +601,30 @@ static int tpm_get_pcr_allocation(struct tpm_chip *chip)return rc; } +/* +* tpm_chip_startup() - performs auto startup and allocates the PCRs +* @chip: TPM chip to use. +*/ +int tpm_chip_startup (struct tpm_chip *chip) +{ +int rc; + + rc =tpm_chip_start (chip); +if (rc) +return rc; + + rc =tpm_auto_startup (chip); +if (rc) + goto stop; + + rc =tpm_get_pcr_allocation (chip); +stop: +tpm_chip_stop (chip); + +return rc; +} +EXPORT_SYMBOL_GPL (tpm_chip_startup); +/* * tpm_chip_register() - create a character device for the TPM chip * @chip: TPM chip to use.
@@ -616,20 +640,6 @@ int tpm_chip_register(struct tpm_chip *chip) {int rc; - rc =tpm_chip_start (chip); -if (rc) -return rc; - rc =tpm_auto_startup (chip); -if (rc) { -tpm_chip_stop (chip); -return rc; - } - - rc =tpm_get_pcr_allocation (chip); -tpm_chip_stop (chip); -if (rc) -return rc; -tpm_sysfs_add_device (chip);tpm_bios_log_setup (chip);
drivers/char/tpm/tpm.h +1 -0
@@ -263,6 +263,7 @@ static inline void tpm_msleep(unsigned int delay_msec) delay_msec * 1000); }; +int tpm_chip_startup (struct tpm_chip *chip);int tpm_chip_start (struct tpm_chip *chip);void tpm_chip_stop (struct tpm_chip *chip);struct tpm_chip *tpm_find_get_ops (struct tpm_chip *chip);
drivers/char/tpm/tpm_tis_core.c +5 -0
@@ -1124,6 +1124,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,/* INTERRUPT Setup */ init_waitqueue_head (&priv->read_queue);init_waitqueue_head (&priv->int_queue); + + rc =tpm_chip_startup (chip); +if (rc) + goto out_err; +if (irq !=-1 ) {/* * Before doing irq testing issue a command to the TPM in polling mode
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 6/119 tpm: Re-enable TPM chip boostrapping non-tpm_tis TPM drivers
In reply to Greg Kroah-HartmanFrom: Jarkko Sakkinen <[email protected]>
[ Upstream commit 0c8862de05c1a087795ee0a87bf61a6394306cc0 ]
TPM chip bootstrapping was removed from tpm_chip_register(), and it was relocated to tpm_tis_core. This breaks all drivers which are not based on tpm_tis because the chip will not get properly initialized.
Take the corrective steps:
1. Rename tpm_chip_startup() as tpm_chip_bootstrap() and make it one-shot.
2. Call tpm_chip_bootstrap() in tpm_chip_register(), which reverts the things as tehy used to be.
Stable-dep-of: 99d464506255 ("tpm: Prevent hwrng from activating during resume")
--- drivers/char/tpm/tpm-chip.c | 22 +++++++++++++++++++--- drivers/char/tpm/tpm.h | 2 +- drivers/char/tpm/tpm_tis_core.c | 2 +- include/linux/tpm.h | 13 +++++++------ 4 files changed, 28 insertions(+), 11 deletions(-)
drivers/char/tpm/tpm-chip.c +19 -3
@@ -602,13 +602,19 @@ static int tpm_get_pcr_allocation(struct tpm_chip *chip) }/* -* tpm_chip_startup() - performs auto startup and allocates the PCRs +* tpm_chip_bootstrap() - Boostrap TPM chip after power on * @chip: TPM chip to use. +* +* Initialize TPM chip after power on. This a one-shot function: subsequent +* calls will have no effect. */ -int tpm_chip_startup (struct tpm_chip *chip) +int tpm_chip_bootstrap (struct tpm_chip *chip) {int rc; +if (chip->flags &TPM_CHIP_FLAG_BOOTSTRAPPED ) +return 0 ; + rc =tpm_chip_start (chip);if (rc)return rc;
@@ -621,9 +627,15 @@ int tpm_chip_startup(struct tpm_chip *chip) stop:tpm_chip_stop (chip); +/* +* Unconditionally set, as driver initialization should cease, when the +* boostrapping process fails. +*/ + chip->flags |=TPM_CHIP_FLAG_BOOTSTRAPPED ; +return rc; } -EXPORT_SYMBOL_GPL (tpm_chip_startup); +EXPORT_SYMBOL_GPL (tpm_chip_bootstrap);/* * tpm_chip_register() - create a character device for the TPM chip
@@ -640,6 +652,10 @@ int tpm_chip_register(struct tpm_chip *chip) {int rc; + rc =tpm_chip_bootstrap (chip); +if (rc) +return rc; +tpm_sysfs_add_device (chip);tpm_bios_log_setup (chip);
drivers/char/tpm/tpm.h +1 -1
@@ -263,7 +263,7 @@ static inline void tpm_msleep(unsigned int delay_msec) delay_msec * 1000); }; -int tpm_chip_startup (struct tpm_chip *chip); +int tpm_chip_bootstrap (struct tpm_chip *chip);int tpm_chip_start (struct tpm_chip *chip);void tpm_chip_stop (struct tpm_chip *chip);struct tpm_chip *tpm_find_get_ops (struct tpm_chip *chip);
drivers/char/tpm/tpm_tis_core.c +1 -1
@@ -1125,7 +1125,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,init_waitqueue_head (&priv->read_queue);init_waitqueue_head (&priv->int_queue); - rc =tpm_chip_startup (chip); + rc =tpm_chip_bootstrap (chip);if (rc) goto out_err;
include/linux/tpm.h +7 -6
@@ -273,13 +273,14 @@ enum tpm2_cc_attrs {#define TPM_VID_ATML 0x1114enum tpm_chip_flags { -TPM_CHIP_FLAG_TPM2 =BIT (1 ), -TPM_CHIP_FLAG_IRQ =BIT (2 ), -TPM_CHIP_FLAG_VIRTUAL =BIT (3 ), -TPM_CHIP_FLAG_HAVE_TIMEOUTS =BIT (4 ), -TPM_CHIP_FLAG_ALWAYS_POWERED =BIT (5 ), +TPM_CHIP_FLAG_BOOTSTRAPPED =BIT (0 ), +TPM_CHIP_FLAG_TPM2 =BIT (1 ), +TPM_CHIP_FLAG_IRQ =BIT (2 ), +TPM_CHIP_FLAG_VIRTUAL =BIT (3 ), +TPM_CHIP_FLAG_HAVE_TIMEOUTS =BIT (4 ), +TPM_CHIP_FLAG_ALWAYS_POWERED =BIT (5 ),TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED =BIT (6 ), -TPM_CHIP_FLAG_FIRMWARE_UPGRADE =BIT (7 ), +TPM_CHIP_FLAG_FIRMWARE_UPGRADE =BIT (7 ), };#define to_tpm_chip (d) container_of(d, struct tpm_chip, dev)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 7/119 tpm: Prevent hwrng from activating during resume
In reply to Greg Kroah-HartmanFrom: Jarkko Sakkinen <[email protected]>
[ Upstream commit 99d46450625590d410f86fe4660a5eff7d3b8343 ]
Set TPM_CHIP_FLAG_SUSPENDED in tpm_pm_suspend() and reset in tpm_pm_resume(). While the flag is set, tpm_hwrng() gives back zero bytes. This prevents hwrng from racing during resume.
--- drivers/char/tpm/tpm-chip.c | 4 ++++ drivers/char/tpm/tpm-interface.c | 10 ++++++++++ include/linux/tpm.h | 1 + 3 files changed, 15 insertions(+)
drivers/char/tpm/tpm-chip.c +4 -0
@@ -568,6 +568,10 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) { struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng); +/* Give back zero bytes, as TPM chip has not yet fully resumed: */ +if (chip->flags &TPM_CHIP_FLAG_SUSPENDED ) +return 0 ; +return tpm_get_random (chip, data, max); }
drivers/char/tpm/tpm-interface.c +10 -0
@@ -412,6 +412,8 @@ int tpm_pm_suspend(struct device *dev) } suspended: + chip->flags |=TPM_CHIP_FLAG_SUSPENDED ; +if (rc)dev_err (dev,"Ignoring error %d while suspending\n" , rc);return 0 ;
@@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev)if (chip ==NULL )return -ENODEV ; + chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED ; + +/* +* Guarantee that SUSPENDED is written last, so that hwrng does not +* activate before the chip has been fully resumed. +*/ +wmb (); +return 0 ; }EXPORT_SYMBOL_GPL (tpm_pm_resume);
include/linux/tpm.h +1 -0
@@ -281,6 +281,7 @@ enum tpm_chip_flags {TPM_CHIP_FLAG_ALWAYS_POWERED =BIT (5 ),TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED =BIT (6 ),TPM_CHIP_FLAG_FIRMWARE_UPGRADE =BIT (7 ), + TPM_CHIP_FLAG_SUSPENDED = BIT(8), };#define to_tpm_chip (d) container_of(d, struct tpm_chip, dev)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 8/119 watchdog: sp5100_tco: Immediately trigger upon starting.
In reply to Greg Kroah-HartmanFrom: Gregory Oakes <[email protected]>
commit 4eda19cc8a29cde3580ed73bf11dc73b4e757697 upstream.
The watchdog countdown is supposed to begin when the device file is opened. Instead, it would begin countdown upon the first write to or close of the device file. Now, the ping operation is called within the start operation which ensures the countdown begins. From experimenation, it does not appear possible to do this with a single write including both the start bit and the trigger bit. So, it is done as two distinct writes.
--- drivers/watchdog/sp5100_tco.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/watchdog/sp5100_tco.c +4 -0
@@ -115,6 +115,10 @@ static int tco_timer_start(struct watchd val |=SP5100_WDT_START_STOP_BIT ;writel (val,SP5100_WDT_CONTROL (tco->tcobase)); +/* This must be a distinct write. */ + val |=SP5100_WDT_TRIGGER_BIT ; +writel (val,SP5100_WDT_CONTROL (tco->tcobase)); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 9/119 drm/amd/amdgpu: update mes11 api def
In reply to Greg Kroah-HartmanFrom: Jack Xiao <[email protected]>
commit 1e7bbdba68baf6af7500dd636f18b6fcce58e945 upstream.
Update the api def of mes11.
--- drivers/gpu/drm/amd/include/mes_v11_api_def.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/include/mes_v11_api_def.h +5 -1
@@ -222,7 +222,11 @@ union MESAPI_SET_HW_RESOURCES { uint32_t apply_grbm_remote_register_dummy_read_wa : 1; uint32_t second_gfx_pipe_enabled : 1; uint32_t enable_level_process_quantum_check : 1; - uint32_t reserved : 25; + uint32_t legacy_sch_mode : 1; + uint32_t disable_add_queue_wptr_mc_addr : 1; + uint32_t enable_mes_event_int_logging : 1; + uint32_t enable_reg_active_poll : 1; + uint32_t reserved : 21; };uint32_t uint32_t_all; };
Greg Kroah-Hartman
maintainerPATCH 10/119 drm/amdgpu/mes11: enable reg active poll
In reply to Greg Kroah-HartmanFrom: Jack Xiao <[email protected]>
commit a6b3b618c0f7abc3f543dd0c57b2b19a770bffec upstream.
Enable reg active poll in mes11.
--- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +1 -0
@@ -390,6 +390,7 @@ static int mes_v11_0_set_hw_resources(st mes_set_hw_res_pkt.disable_reset =1 ; mes_set_hw_res_pkt.disable_mes_log =1 ; mes_set_hw_res_pkt.use_different_vmid_compute =1 ; + mes_set_hw_res_pkt.enable_reg_active_poll =1 ; mes_set_hw_res_pkt.oversubscription_timer =50 ; return mes_v11_0_submit_pkt_and_poll_completion(mes,
Greg Kroah-Hartman
maintainerPATCH 11/119 skbuff: Proactively round up to kmalloc bucket size
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
commit 12d6c1d3a2ad0c199ec57c201cdc71e8e157a232 upstream.
Instead of discovering the kmalloc bucket size _after_ allocation, round up proactively so the allocation is explicitly made for the full size, allowing the compiler to correctly reason about the resulting size of the buffer through the existing __alloc_size() hint.
This will allow for kernels built with CONFIG_UBSAN_BOUNDS or the coming dynamic bounds checking under CONFIG_FORTIFY_SOURCE to gain back the __alloc_size() hints that were temporarily reverted in commit 93dd04ab0b2b ("slab: remove __alloc_size attribute from __kmalloc_track_caller")
--- net/core/skbuff.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-)
net/core/skbuff.c +26 -26
@@ -506,14 +506,14 @@ struct sk_buff *__alloc_skb(unsigned int*/ size =SKB_DATA_ALIGN (size); size +=SKB_DATA_ALIGN (sizeof (struct skb_shared_info )); - data =kmalloc_reserve (size, gfp_mask, node, &pfmemalloc); + osize =kmalloc_size_roundup (size); + data =kmalloc_reserve (osize, gfp_mask, node, &pfmemalloc);if (unlikely (!data)) goto nodata; -/* kmalloc(size) might give us more room than requested. +/* kmalloc_size_roundup() might give us more room than requested. * Put skb_shared_info exactly at the end of allocated zone, * to allow max possible filling before reallocation. */ - osize =ksize (data); size =SKB_WITH_OVERHEAD (osize);prefetchw (data + size);
@@ -1822,10 +1822,11 @@ EXPORT_SYMBOL(__pskb_copy_fclone);int pskb_expand_head (struct sk_buff *skb,int nhead,int ntail,gfp_t gfp_mask) { -int i, osize =skb_end_offset (skb); -int size = osize + nhead + ntail; +unsigned int osize =skb_end_offset (skb); +unsigned int size = osize + nhead + ntail;long off;u8 *data; +int i;BUG_ON (nhead <0 );
@@ -1833,15 +1834,16 @@ int pskb_expand_head(struct sk_buff *skbskb_zcopy_downgrade_managed (skb); - size =SKB_DATA_ALIGN (size); -if (skb_pfmemalloc (skb)) gfp_mask |= __GFP_MEMALLOC; - data =kmalloc_reserve (size +SKB_DATA_ALIGN (sizeof (struct skb_shared_info )), - gfp_mask,NUMA_NO_NODE ,NULL ); + + size =SKB_DATA_ALIGN (size); + size +=SKB_DATA_ALIGN (sizeof (struct skb_shared_info )); + size =kmalloc_size_roundup (size); + data =kmalloc_reserve (size, gfp_mask,NUMA_NO_NODE ,NULL );if (!data) goto nodata; - size =SKB_WITH_OVERHEAD (ksize (data)); + size =SKB_WITH_OVERHEAD (size);/* Copy only real data... and, alas, header. This should be * optimized for the cases when header is void.
@@ -6182,21 +6184,20 @@ static int pskb_carve_inside_header(stru const int headlen, gfp_t gfp_mask) { int i; -int size =skb_end_offset (skb); +unsigned int size =skb_end_offset (skb);int new_hlen = headlen - off;u8 *data; - size =SKB_DATA_ALIGN (size); -if (skb_pfmemalloc (skb)) gfp_mask |= __GFP_MEMALLOC; - data =kmalloc_reserve (size + -SKB_DATA_ALIGN (sizeof (struct skb_shared_info )), - gfp_mask,NUMA_NO_NODE ,NULL ); + + size =SKB_DATA_ALIGN (size); + size +=SKB_DATA_ALIGN (sizeof (struct skb_shared_info )); + size =kmalloc_size_roundup (size); + data =kmalloc_reserve (size, gfp_mask,NUMA_NO_NODE ,NULL );if (!data)return -ENOMEM ; - - size =SKB_WITH_OVERHEAD (ksize (data)); + size =SKB_WITH_OVERHEAD (size);/* Copy real data, and all frags */ skb_copy_from_linear_data_offset (skb, off, data, new_hlen);
@@ -6301,22 +6302,21 @@ static int pskb_carve_inside_nonlinear(s int pos, gfp_t gfp_mask) { int i, k = 0; -int size =skb_end_offset (skb); +unsigned int size =skb_end_offset (skb);u8 *data;const int nfrags =skb_shinfo (skb)->nr_frags;struct skb_shared_info *shinfo; - size =SKB_DATA_ALIGN (size); -if (skb_pfmemalloc (skb)) gfp_mask |= __GFP_MEMALLOC; - data =kmalloc_reserve (size + -SKB_DATA_ALIGN (sizeof (struct skb_shared_info )), - gfp_mask,NUMA_NO_NODE ,NULL ); + + size =SKB_DATA_ALIGN (size); + size +=SKB_DATA_ALIGN (sizeof (struct skb_shared_info )); + size =kmalloc_size_roundup (size); + data =kmalloc_reserve (size, gfp_mask,NUMA_NO_NODE ,NULL );if (!data)return -ENOMEM ; - - size =SKB_WITH_OVERHEAD (ksize (data)); + size =SKB_WITH_OVERHEAD (size);memcpy ((struct skb_shared_info *)(data + size), skb_shinfo(skb), offsetof(struct skb_shared_info, frags[0]));
Greg Kroah-Hartman
maintainerPATCH 12/119 platform/x86: hp-wmi: Fix cast to smaller integer type warning
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit ce95010ef62d4bf470928969bafc9070ae98cbb1 upstream.
Fix the following compiler warning:
drivers/platform/x86/hp/hp-wmi.c:551:24: warning: cast to smaller integer
type 'enum hp_wmi_radio' from 'void *' [-Wvoid-pointer-to-enum-cast]
--- drivers/platform/x86/hp/hp-wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/hp/hp-wmi.c +1 -1
@@ -552,7 +552,7 @@ static int __init hp_wmi_enable_hotkeys(static int hp_wmi_set_block (void *data,bool blocked) { -enum hp_wmi_radio r = (enum hp_wmi_radio ) data; +enum hp_wmi_radio r = (long )data;int query =BIT (r +8 ) | ((!blocked) << r);int ret;
Greg Kroah-Hartman
maintainerPATCH 13/119 net: dsa: mv88e6xxx: Add RGMII delay to 88E6320
In reply to Greg Kroah-HartmanFrom: Steffen Bätz <[email protected]>
commit 91e87045a5ef6f7003e9a2cb7dfa435b9b002dbe upstream.
Currently, the .port_set_rgmii_delay hook is missing for the 88E6320 family, which causes failure to retrieve an IP address via DHCP.
Add mv88e6320_port_set_rgmii_delay() that allows applying the RGMII delay for ports 2, 5, and 6, which are the only ports that can be used in RGMII mode.
Tested on a custom i.MX8MN board connected to an 88E6320 switch.
This change also applies safely to the 88E6321 variant.
The only difference between 88E6320 versus 88E6321 is the temperature grade and pinout.
They share exactly the same MDIO register map for ports 2, 5, and 6, which are the only ports that can be used in RGMII mode.
--- drivers/net/dsa/mv88e6xxx/chip.c | 2 ++ drivers/net/dsa/mv88e6xxx/port.c | 9 +++++++++ drivers/net/dsa/mv88e6xxx/port.h | 2 ++ 3 files changed, 13 insertions(+)
drivers/net/dsa/mv88e6xxx/chip.c +2 -0
@@ -5044,6 +5044,7 @@ static const struct mv88e6xxx_ops mv88e6 .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, .port_sync_link = mv88e6xxx_port_sync_link, + .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay, .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
@@ -5088,6 +5089,7 @@ static const struct mv88e6xxx_ops mv88e6 .phy_write = mv88e6xxx_g2_smi_phy_write, .port_set_link = mv88e6xxx_port_set_link, .port_sync_link = mv88e6xxx_port_sync_link, + .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay, .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, .port_set_frame_mode = mv88e6351_port_set_frame_mode,
drivers/net/dsa/mv88e6xxx/port.c +9 -0
@@ -133,6 +133,15 @@ int mv88e6390_port_set_rgmii_delay(strucreturn mv88e6xxx_port_set_rgmii_delay (chip, port, mode); } +int mv88e6320_port_set_rgmii_delay (struct mv88e6xxx_chip *chip,int port, +phy_interface_t mode) +{ +if (port !=2 && port !=5 && port !=6 ) +return -EOPNOTSUPP ; + +return mv88e6xxx_port_set_rgmii_delay (chip, port, mode); +} +int mv88e6xxx_port_set_link (struct mv88e6xxx_chip *chip,int port,int link) {u16 reg;
drivers/net/dsa/mv88e6xxx/port.h +2 -0
@@ -332,6 +332,8 @@ int mv88e6xxx_port_wait_bit(struct mv88eint mv88e6185_port_set_pause (struct mv88e6xxx_chip *chip,int port,int pause); +int mv88e6320_port_set_rgmii_delay (struct mv88e6xxx_chip *chip,int port, +phy_interface_t mode);int mv88e6352_port_set_rgmii_delay (struct mv88e6xxx_chip *chip,int port,phy_interface_t mode); int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
Greg Kroah-Hartman
maintainerPATCH 14/119 drm/amd/display: hpd rx irq not working with eDP interface
In reply to Greg Kroah-HartmanFrom: Robin Chen <[email protected]>
commit eeefe7c4820b6baa0462a8b723ea0a3b5846ccae upstream.
[Why]
This is the fix for the defect of commit ab144f0b4ad6 ("drm/amd/display: Allow individual control of eDP hotplug support").
[How]
To revise the default eDP hotplug setting and use the enum to git rid of the magic number for different options.
Hand modified for missing file rename changes and symbol moves in 6.1.y.
--- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 9 +++++++-- drivers/gpu/drm/amd/display/dc/dc_types.h | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc_link.c +7 -2
@@ -1634,14 +1634,18 @@ static bool dc_link_construct_legacy(str link->irq_source_hpd =DC_IRQ_SOURCE_INVALID ;switch (link->dc->config.allow_edp_hotplug_detection) { -case 1 :// only the 1st eDP handles hotplug +case HPD_EN_FOR_ALL_EDP : + link->irq_source_hpd_rx = +dal_irq_get_rx_source (link->hpd_gpio); +break ; +case HPD_EN_FOR_PRIMARY_EDP_ONLY :if (link->link_index ==0 ) link->irq_source_hpd_rx =dal_irq_get_rx_source (link->hpd_gpio);else link->irq_source_hpd =DC_IRQ_SOURCE_INVALID ;break ; -case 2 :// only the 2nd eDP handles hotplug +case HPD_EN_FOR_SECONDARY_EDP_ONLY :if (link->link_index ==1 ) link->irq_source_hpd_rx =dal_irq_get_rx_source (link->hpd_gpio);
@@ -1649,6 +1653,7 @@ static bool dc_link_construct_legacy(str link->irq_source_hpd =DC_IRQ_SOURCE_INVALID ;break ;default : + link->irq_source_hpd =DC_IRQ_SOURCE_INVALID ;break ; } }
drivers/gpu/drm/amd/display/dc/dc_types.h +6 -0
@@ -993,4 +993,10 @@ struct display_endpoint_id { enum display_endpoint_type ep_type; }; +enum dc_hpd_enable_select { +HPD_EN_FOR_ALL_EDP =0 , +HPD_EN_FOR_PRIMARY_EDP_ONLY , +HPD_EN_FOR_SECONDARY_EDP_ONLY , +}; +#endif /* DC_TYPES_H_ */
Greg Kroah-Hartman
maintainerPATCH 15/119 ocfs2: Switch to security_inode_init_security()
In reply to Greg Kroah-HartmanFrom: Roberto Sassu <[email protected]>
commit de3004c874e740304cc4f4a83d6200acb511bbda upstream.
In preparation for removing security_old_inode_init_security(), switch to security_inode_init_security().
Extend the existing ocfs2_initxattrs() to take the ocfs2_security_xattr_info structure from fs_info, and populate the name/value/len triple with the first xattr provided by LSMs.
As fs_info was not used before, ocfs2_initxattrs() can now handle the case of replicating the behavior of security_old_inode_init_security(), i.e. just obtaining the xattr, in addition to setting all xattrs provided by LSMs.
Supporting multiple xattrs is not currently supported where security_old_inode_init_security() was called (mknod, symlink), as it requires non-trivial changes that can be done at a later time. Like for reiserfs, even if EVM is invoked, it will not provide an xattr (if it is not the first to set it, its xattr will be discarded; if it is the first, it does not have xattrs to calculate the HMAC on).
Finally, since security_inode_init_security(), unlike security_old_inode_init_security(), returns zero instead of -EOPNOTSUPP if no xattrs were provided by LSMs or if inodes are private, additionally check in ocfs2_init_security_get() if the xattr name is set.
If not, act as if security_old_inode_init_security() returned -EOPNOTSUPP, and set si->enable to zero to notify to the functions following ocfs2_init_security_get() that no xattrs are available.
--- fs/ocfs2/namei.c | 2 ++ fs/ocfs2/xattr.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-)
fs/ocfs2/namei.c +2 -0
@@ -242,6 +242,7 @@ static int ocfs2_mknod(struct user_namesint want_meta =0 ;int xattr_credits =0 ;struct ocfs2_security_xattr_info si = { + .name =NULL , .enable =1 , };int did_quota_inode =0 ;
@@ -1805,6 +1806,7 @@ static int ocfs2_symlink(struct user_namint want_clusters =0 ;int xattr_credits =0 ;struct ocfs2_security_xattr_info si = { + .name =NULL , .enable =1 , };int did_quota =0 , did_quota_inode =0 ;
fs/ocfs2/xattr.c +26 -4
@@ -7259,9 +7259,21 @@ static int ocfs2_xattr_security_set(consstatic int ocfs2_initxattrs (struct inode *inode,const struct xattr *xattr_array,void *fs_info) { +struct ocfs2_security_xattr_info *si = fs_info;const struct xattr *xattr;int err =0 ; +if (si) { + si->value =kmemdup (xattr_array->value, xattr_array->value_len, +GFP_KERNEL ); +if (!si->value) +return -ENOMEM ; + + si->name = xattr_array->name; + si->value_len = xattr_array->value_len; +return 0 ; + } +for (xattr = xattr_array; xattr->name !=NULL ; xattr++) { err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, xattr->name, xattr->value,
@@ -7277,13 +7289,23 @@ int ocfs2_init_security_get(struct inodeconst struct qstr *qstr, struct ocfs2_security_xattr_info *si) { + int ret; +/* check whether ocfs2 support feature xattr */ if (!ocfs2_supports_xattr (OCFS2_SB (dir->i_sb)))return -EOPNOTSUPP ; -if (si) -return security_old_inode_init_security (inode, dir, qstr, - &si->name, &si->value, - &si->value_len); +if (si) { + ret =security_inode_init_security (inode, dir, qstr, + &ocfs2_initxattrs, si); +/* +* security_inode_init_security() does not return -EOPNOTSUPP, +* we have to check the xattr ourselves. +*/ +if (!ret && !si->name) + si->enable =0 ; + +return ret; + }return security_inode_init_security (inode, dir, qstr, &ocfs2_initxattrs,NULL );
Greg Kroah-Hartman
maintainerPATCH 16/119 arm64: Also reset KASAN tag if page is not PG_mte_tagged
In reply to Greg Kroah-HartmanFrom: Peter Collingbourne <[email protected]>
commit 2efbafb91e12ff5a16cbafb0085e4c10c3fca493 upstream.
Consider the following sequence of events:
1) A page in a PROT_READ|PROT_WRITE VMA is faulted.
2) Page migration allocates a page with the KASAN allocator, causing it to receive a non-match-all tag, and uses it
to replace the page faulted in 1.
3) The program uses mprotect() to enable PROT_MTE on the page faulted in 1.
As a result of step 3, we are left with a non-match-all tag for a page with tags accessible to userspace, which can lead to the same kind of tag check faults that commit e74a68468062 ("arm64: Reset KASAN tag in copy_highpage with HW tags only") intended to fix.
The general invariant that we have for pages in a VMA with VM_MTE_ALLOWED is that they cannot have a non-match-all tag. As a result of step 2, the invariant is broken. This means that the fix in the referenced commit was incomplete and we also need to reset the tag for pages without PG_mte_tagged.
--- arch/arm64/mm/copypage.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/arm64/mm/copypage.c +3 -2
@@ -21,9 +21,10 @@ void copy_highpage(struct page *to, strucopy_page (kto, kfrom); +if (kasan_hw_tags_enabled ()) +page_kasan_tag_reset (to); +if (system_supports_mte () &&page_mte_tagged (from)) { -if (kasan_hw_tags_enabled ()) -page_kasan_tag_reset (to);mte_copy_page_tags (kto, kfrom);set_page_mte_tagged (to); }
Greg Kroah-Hartman
maintainerPATCH 17/119 x86/mm: Avoid incomplete Global INVLPG flushes
In reply to Greg Kroah-HartmanFrom: Dave Hansen <[email protected]>
commit ce0b15d11ad837fbacc5356941712218e38a0a83 upstream.
The INVLPG instruction is used to invalidate TLB entries for a specified virtual address. When PCIDs are enabled, INVLPG is supposed to invalidate TLB entries for the specified address for both the current PCID *and* Global entries. (Note: Only kernel mappings set Global=1.)
Unfortunately, some INVLPG implementations can leave Global translations unflushed when PCIDs are enabled.
As a workaround, never enable PCIDs on affected processors.
I expect there to eventually be microcode mitigations to replace this software workaround. However, the exact version numbers where that will happen are not known today. Once the version numbers are set in stone, the processor list can be tweaked to only disable PCIDs on affected processors with affected microcode.
Note: if anyone wants a quick fix that doesn't require patching, just stick 'nopcid' on your kernel command-line.
--- arch/x86/mm/init.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
arch/x86/mm/init.c +25 -0
@@ -9,6 +9,7 @@#include <linux/sched/task.h> #include <asm/set_memory.h> +#include <asm/cpu_device_id.h> #include <asm/e820/api.h> #include <asm/init.h> #include <asm/page.h>
@@ -260,6 +261,24 @@ static void __init probe_page_size_mask( } } +#define INTEL_MATCH (_model) { .vendor = X86_VENDOR_INTEL, \ + .family = 6, \ + .model = _model, \ + } +/* +* INVLPG may not properly flush Global entries +* on these CPUs when PCIDs are enabled. +*/ +static const struct x86_cpu_id invlpg_miss_ids[] = { +INTEL_MATCH (INTEL_FAM6_ALDERLAKE ), +INTEL_MATCH (INTEL_FAM6_ALDERLAKE_L ), +INTEL_MATCH (INTEL_FAM6_ALDERLAKE_N ), +INTEL_MATCH (INTEL_FAM6_RAPTORLAKE ), +INTEL_MATCH (INTEL_FAM6_RAPTORLAKE_P ), +INTEL_MATCH (INTEL_FAM6_RAPTORLAKE_S ), + {} +}; +static void setup_pcid (void ) {if (!IS_ENABLED (CONFIG_X86_64 ))
@@ -268,6 +287,12 @@ static void setup_pcid(void)if (!boot_cpu_has (X86_FEATURE_PCID ))return ; +if (x86_match_cpu (invlpg_miss_ids)) { +pr_info ("Incomplete global flushes, disabling PCID" ); +setup_clear_cpu_cap (X86_FEATURE_PCID ); +return ; + } +if (boot_cpu_has (X86_FEATURE_PGE )) {/* * This can't be cr4_set_bits_and_update_boot() -- the
Greg Kroah-Hartman
maintainerPATCH 18/119 platform/x86/intel/ifs: Annotate work queue on stack so object debug does not complain
In reply to Greg Kroah-HartmanFrom: David Arcari <[email protected]>
commit 3279decb2c3c8d58cb0b70ed5235c480735a36ee upstream.
Object Debug results in the following warning while attempting to load ifs firmware:
[ 220.007422] ODEBUG: object 000000003bf952db is on stack 00000000e843994b, but NOT annotated. [ 220.007459] ------------[ cut here ]------------ [ 220.007461] WARNING: CPU: 0 PID: 11774 at lib/debugobjects.c:548 __debug_object_init.cold+0x22e/0x2d5 [ 220.137476] RIP: 0010:__debug_object_init.cold+0x22e/0x2d5 [ 220.254774] Call Trace: [ 220.257641] <TASK> [ 220.265606] scan_chunks_sanity_check+0x368/0x5f0 [intel_ifs] [ 220.288292] ifs_load_firmware+0x2a3/0x400 [intel_ifs] [ 220.332793] current_batch_store+0xea/0x160 [intel_ifs] [ 220.357947] kernfs_fop_write_iter+0x355/0x530 [ 220.363048] new_sync_write+0x28e/0x4a0 [ 220.381226] vfs_write+0x62a/0x920 [ 220.385160] ksys_write+0xf9/0x1d0 [ 220.399421] do_syscall_64+0x59/0x90 [ 220.440635] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 220.566845] ---[ end trace 3a01b299db142b41 ]---
Correct this by calling INIT_WORK_ONSTACK instead of INIT_WORK.
--- drivers/platform/x86/intel/ifs/load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/platform/x86/intel/ifs/load.c +1 -1
@@ -154,7 +154,7 @@ static int scan_chunks_sanity_check(strucontinue ;reinit_completion (&ifs_done); local_work.dev = dev; -INIT_WORK (&local_work.w, copy_hashes_authenticate_chunks); +INIT_WORK_ONSTACK (&local_work.w, copy_hashes_authenticate_chunks);schedule_work_on (cpu, &local_work.w);wait_for_completion (&ifs_done);if (ifsd->loading_error)
Greg Kroah-Hartman
maintainerPATCH 19/119 ALSA: hda/ca0132: add quirk for EVGA X299 DARK
In reply to Greg Kroah-HartmanFrom: Adam Stylinski <[email protected]>
commit 7843380d07bbeffd3ce6504e73cf61f840ae76ca upstream.
This quirk is necessary for surround and other DSP effects to work with the onboard ca0132 based audio chipset for the EVGA X299 dark mainboard.
--- sound/pci/hda/patch_ca0132.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_ca0132.c +1 -0
@@ -1306,6 +1306,7 @@ static const struct snd_pci_quirk ca0132SND_PCI_QUIRK (0x1458 ,0xA026 ,"Gigabyte G1.Sniper Z97" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x1458 ,0xA036 ,"Gigabyte GA-Z170X-Gaming 7" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x3842 ,0x1038 ,"EVGA X99 Classified" ,QUIRK_R3DI ), +SND_PCI_QUIRK (0x3842 ,0x104b ,"EVGA X299 Dark" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x3842 ,0x1055 ,"EVGA Z390 DARK" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x1102 ,0x0013 ,"Recon3D" ,QUIRK_R3D ), SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
Greg Kroah-Hartman
maintainerPATCH 20/119 ALSA: hda: Fix unhandled register update during auto-suspend period
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 81302b1c7c997e8a56c1c2fc63a296ebeb0cd2d0 upstream.
It's reported that the recording started right after the driver probe doesn't work properly, and it turned out that this is related with the codec auto-suspend. Namely, after the probe phase, the usage count goes zero, and the auto-suspend is programmed, but the codec is kept still active until the auto-suspend expiration. When an application (e.g. alsactl) updates the mixer values at this moment, the values are cached but not actually written. Then, starting arecord thereafter also results in the silence because of the missing unmute.
The root cause is the handling of "lazy update" mode; when a mixer value is updated *after* the suspend, it should update only the cache and exits. At the resume, the cached value is written to the device, in turn. The problem is that the current code misinterprets the state of auto-suspend as if it were already suspended.
Although we can add the check of the actual device state after pm_runtime_get_if_in_use() for catching the missing state, this won't suffice; the second call of regmap_update_bits_check() will skip writing the register because the cache has been already updated by the first call. So we'd need fixes in two different places.
OTOH, a simpler fix is to replace pm_runtime_get_if_in_use() with pm_runtime_get_if_active() (with ign_usage_count=true). This change implies that the driver takes the pm refcount if the device is still in ACTIVE state and continues the processing. A small caveat is that this will leave the auto-suspend timer. But, since the timer callback itself checks the device state and aborts gracefully when it's active, this won't be any substantial problem.
Long story short: we address the missing register-write problem just by replacing the pm_runtime_*() call in snd_hda_keep_power_up().
--- sound/hda/hdac_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/hda/hdac_device.c +1 -1
@@ -611,7 +611,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);int snd_hdac_keep_power_up (struct hdac_device *codec) {if (!atomic_inc_not_zero (&codec->in_pm)) { -int ret =pm_runtime_get_if_in_use (&codec->dev); +int ret =pm_runtime_get_if_active (&codec->dev, true);if (!ret)return -1 ;if (ret <0 )
Greg Kroah-Hartman
maintainerPATCH 21/119 ALSA: hda/realtek: Enable headset onLenovo M70/M90
In reply to Greg Kroah-HartmanFrom: Bin Li <[email protected]>
commit 4ca110cab46561cd74a2acd9b447435acb4bec5f upstream.
Lenovo M70/M90 Gen4 are equipped with ALC897, and they need ALC897_FIXUP_HEADSET_MIC_PIN quirk to make its headset mic work. The previous quirk for M70/M90 is for Gen3.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -11699,6 +11699,8 @@ static const struct snd_pci_quirk alc662SND_PCI_QUIRK (0x17aa ,0x32cb ,"Lenovo ThinkCentre M70" ,ALC897_FIXUP_HEADSET_MIC_PIN ),SND_PCI_QUIRK (0x17aa ,0x32cf ,"Lenovo ThinkCentre M950" ,ALC897_FIXUP_HEADSET_MIC_PIN ),SND_PCI_QUIRK (0x17aa ,0x32f7 ,"Lenovo ThinkCentre M90" ,ALC897_FIXUP_HEADSET_MIC_PIN ), +SND_PCI_QUIRK (0x17aa ,0x3321 ,"Lenovo ThinkCentre M70 Gen4" ,ALC897_FIXUP_HEADSET_MIC_PIN ), +SND_PCI_QUIRK (0x17aa ,0x331b ,"Lenovo ThinkCentre M90 Gen4" ,ALC897_FIXUP_HEADSET_MIC_PIN ),SND_PCI_QUIRK (0x17aa ,0x3742 ,"Lenovo TianYi510Pro-14IOB" ,ALC897_FIXUP_HEADSET_MIC_PIN2 ),SND_PCI_QUIRK (0x17aa ,0x38af ,"Lenovo Ideapad Y550P" ,ALC662_FIXUP_IDEAPAD ), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Greg Kroah-Hartman
maintainerPATCH 22/119 SUNRPC: Dont change task->tk_status after the call to rpc_exit_task
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
commit d180891fba995bd54e25b089b1ec98d134873586 upstream.
Some calls to rpc_exit_task() may deliberately change the value of task->tk_status, for instance because it gets checked by the RPC call's rpc_release() callback. That makes it wrong to reset the value to task->tk_rpc_status.
In particular this causes a bug where the rpc_call_done() callback tries to fail over a set of pNFS/flexfiles writes to a different IP address, but the reset of task->tk_status causes nfs_commit_release_pages() to immediately mark the file as having a fatal error.
--- net/sunrpc/sched.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
net/sunrpc/sched.c +2 -3
@@ -927,11 +927,10 @@ static void __rpc_execute(struct rpc_task *task)*/ do_action = task->tk_action;/* Tasks with an RPC error status should exit */ -if (do_action != rpc_exit_task && +if (do_action && do_action != rpc_exit_task && (status =READ_ONCE (task->tk_rpc_status)) !=0 ) { task->tk_status = status; -if (do_action !=NULL ) - do_action = rpc_exit_task; + do_action = rpc_exit_task; }/* Callbacks override all actions */ if (task->tk_callback) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 23/119 mmc: sdhci-esdhc-imx: make "no-mmc-hs400" works
In reply to Greg Kroah-HartmanFrom: Haibo Chen <[email protected]>
commit 81dce1490e28439c3cd8a8650b862a712f3061ba upstream.
After commit 1ed5c3b22fc7 ("mmc: sdhci-esdhc-imx: Propagate ESDHC_FLAG_HS400* only on 8bit bus"), the property "no-mmc-hs400" from device tree file do not work any more.
This patch reorder the code, which can avoid the warning message "drop HS400 support since no 8-bit bus" and also make the property "no-mmc-hs400" from dts file works.
--- drivers/mmc/host/sdhci-esdhc-imx.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/mmc/host/sdhci-esdhc-imx.c +10 -8
@@ -1585,6 +1585,10 @@ sdhci_esdhc_imx_probe_dt(struct platformif (ret)return ret; +/* HS400/HS400ES require 8 bit bus */ +if (!(host->mmc->caps &MMC_CAP_8_BIT_DATA )) + host->mmc->caps2 &= ~(MMC_CAP2_HS400 |MMC_CAP2_HS400_ES ); +if (mmc_gpio_get_cd (host->mmc) >=0 ) host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION ;
@@ -1669,10 +1673,6 @@ static int sdhci_esdhc_imx_probe(struct host->mmc_host_ops.execute_tuning = usdhc_execute_tuning; } - err =sdhci_esdhc_imx_probe_dt (pdev, host, imx_data); -if (err) - goto disable_ahb_clk; -if (imx_data->socdata->flags &ESDHC_FLAG_MAN_TUNING ) sdhci_esdhc_ops.platform_execute_tuning = esdhc_executing_tuning;
@@ -1680,15 +1680,13 @@ static int sdhci_esdhc_imx_probe(structif (imx_data->socdata->flags &ESDHC_FLAG_ERR004536 ) host->quirks |=SDHCI_QUIRK_BROKEN_ADMA ; -if (host->mmc->caps &MMC_CAP_8_BIT_DATA && - imx_data->socdata->flags &ESDHC_FLAG_HS400 ) +if (imx_data->socdata->flags &ESDHC_FLAG_HS400 ) host->mmc->caps2 |=MMC_CAP2_HS400 ;if (imx_data->socdata->flags &ESDHC_FLAG_BROKEN_AUTO_CMD23 ) host->quirks2 |=SDHCI_QUIRK2_ACMD23_BROKEN ; -if (host->mmc->caps &MMC_CAP_8_BIT_DATA && - imx_data->socdata->flags &ESDHC_FLAG_HS400_ES ) { +if (imx_data->socdata->flags &ESDHC_FLAG_HS400_ES ) { host->mmc->caps2 |=MMC_CAP2_HS400_ES ; host->mmc_host_ops.hs400_enhanced_strobe = esdhc_hs400_enhanced_strobe;
@@ -1710,6 +1708,10 @@ static int sdhci_esdhc_imx_probe(struct goto disable_ahb_clk; } + err =sdhci_esdhc_imx_probe_dt (pdev, host, imx_data); +if (err) + goto disable_ahb_clk; +sdhci_esdhc_imx_hwinit (host); err =sdhci_add_host (host);
Greg Kroah-Hartman
maintainerPATCH 24/119 mmc: block: ensure error propagation for non-blk
In reply to Greg Kroah-HartmanFrom: Christian Loehle <[email protected]>
commit 003fb0a51162d940f25fc35e70b0996a12c9e08a upstream.
Requests to the mmc layer usually come through a block device IO. The exceptions are the ioctl interface, RPMB chardev ioctl and debugfs, which issue their own blk_mq requests through blk_execute_rq and do not query the BLK_STS error but the mmcblk-internal drv_op_result. This patch ensures that drv_op_result defaults to an error and has to be overwritten by the operation to be considered successful.
The behavior leads to a bug where the request never propagates the error, e.g. by directly erroring out at mmc_blk_mq_issue_rq if mmc_blk_part_switch fails. The ioctl caller of the rpmb chardev then can never see an error (BLK_STS_IOERR, but drv_op_result is unchanged) and thus may assume that their call executed successfully when it did not.
While always checking the blk_execute_rq return value would be advised, let's eliminate the error by always setting drv_op_result as -EIO to be overwritten on success (or other error)
--- drivers/mmc/core/block.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/mmc/core/block.c +5 -0
@@ -266,6 +266,7 @@ static ssize_t power_ro_lock_store(struc goto out_put; }req_to_mmc_queue_req (req)->drv_op =MMC_DRV_OP_BOOT_WP ; +req_to_mmc_queue_req (req)->drv_op_result = -EIO ;blk_execute_rq (req, false); ret =req_to_mmc_queue_req (req)->drv_op_result;blk_mq_free_request (req);
@@ -657,6 +658,7 @@ static int mmc_blk_ioctl_cmd(struct mmc_ idatas[0 ] = idata;req_to_mmc_queue_req (req)->drv_op = rpmb ?MMC_DRV_OP_IOCTL_RPMB :MMC_DRV_OP_IOCTL ; +req_to_mmc_queue_req (req)->drv_op_result = -EIO ;req_to_mmc_queue_req (req)->drv_op_data = idatas;req_to_mmc_queue_req (req)->ioc_count =1 ;blk_execute_rq (req, false);
@@ -728,6 +730,7 @@ static int mmc_blk_ioctl_multi_cmd(struc }req_to_mmc_queue_req (req)->drv_op = rpmb ?MMC_DRV_OP_IOCTL_RPMB :MMC_DRV_OP_IOCTL ; +req_to_mmc_queue_req (req)->drv_op_result = -EIO ;req_to_mmc_queue_req (req)->drv_op_data = idata;req_to_mmc_queue_req (req)->ioc_count = n;blk_execute_rq (req, false);
@@ -2812,6 +2815,7 @@ static int mmc_dbg_card_status_get(voidif (IS_ERR (req))return PTR_ERR (req);req_to_mmc_queue_req (req)->drv_op =MMC_DRV_OP_GET_CARD_STATUS ; +req_to_mmc_queue_req (req)->drv_op_result = -EIO ;blk_execute_rq (req, false); ret =req_to_mmc_queue_req (req)->drv_op_result;if (ret >=0 ) {
@@ -2850,6 +2854,7 @@ static int mmc_ext_csd_open(struct inode goto out_free; }req_to_mmc_queue_req (req)->drv_op =MMC_DRV_OP_GET_EXT_CSD ; +req_to_mmc_queue_req (req)->drv_op_result = -EIO ;req_to_mmc_queue_req (req)->drv_op_data = &ext_csd;blk_execute_rq (req, false); err =req_to_mmc_queue_req (req)->drv_op_result;
Greg Kroah-Hartman
maintainerPATCH 25/119 power: supply: axp288_fuel_gauge: Fix external_power_changed race
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit f8319774d6f1567d6e7d03653174ab0c82c5c66d upstream.
fuel_gauge_external_power_changed() dereferences info->bat, which gets sets in axp288_fuel_gauge_probe() like this:
info->bat = devm_power_supply_register(dev, &fuel_gauge_desc, &psy_cfg);
As soon as devm_power_supply_register() has called device_add() the external_power_changed callback can get called. So there is a window where fuel_gauge_external_power_changed() may get called while info->bat has not been set yet leading to a NULL pointer dereference.
Fixing this is easy. The external_power_changed callback gets passed the power_supply which will eventually get stored in info->bat, so fuel_gauge_external_power_changed() can simply directly use the passed in psy argument which is always valid.
--- drivers/power/supply/axp288_fuel_gauge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/axp288_fuel_gauge.c +1 -1
@@ -507,7 +507,7 @@ static void fuel_gauge_external_power_changed(struct power_supply *psy)mutex_lock (&info->lock); info->valid =0 ;/* Force updating of the cached registers */ mutex_unlock (&info->lock); -power_supply_changed (info->bat); +power_supply_changed (psy); }static struct power_supply_desc fuel_gauge_desc = {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 26/119 power: supply: bq25890: Fix external_power_changed race
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 029a443b9b6424170f00f6dd5b7682e682cce92e upstream.
bq25890_charger_external_power_changed() dereferences bq->charger, which gets sets in bq25890_power_supply_init() like this:
bq->charger = devm_power_supply_register(bq->dev, &bq->desc, &psy_cfg);
As soon as devm_power_supply_register() has called device_add() the external_power_changed callback can get called. So there is a window where bq25890_charger_external_power_changed() may get called while bq->charger has not been set yet leading to a NULL pointer dereference.
This race hits during boot sometimes on a Lenovo Yoga Book 1 yb1-x90f when the cht_wcove_pwrsrc (extcon) power_supply is done with detecting the connected charger-type which happens to exactly hit the small window:
BUG: kernel NULL pointer dereference, address: 0000000000000018 <snip> RIP: 0010:__power_supply_is_supplied_by+0xb/0xb0 <snip> Call Trace: <TASK> __power_supply_get_supplier_property+0x19/0x50 class_for_each_device+0xb1/0xe0 power_supply_get_property_from_supplier+0x2e/0x50 bq25890_charger_external_power_changed+0x38/0x1b0 [bq25890_charger] __power_supply_changed_work+0x30/0x40 class_for_each_device+0xb1/0xe0 power_supply_changed_work+0x5f/0xe0 <snip>
Fixing this is easy. The external_power_changed callback gets passed the power_supply which will eventually get stored in bq->charger, so bq25890_charger_external_power_changed() can simply directly use the passed in psy argument which is always valid.
--- drivers/power/supply/bq25890_charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/bq25890_charger.c +1 -1
@@ -650,7 +650,7 @@ static void bq25890_charger_external_powif (bq->chip_version !=BQ25892 )return ; - ret =power_supply_get_property_from_supplier (bq->charger, + ret =power_supply_get_property_from_supplier (psy,POWER_SUPPLY_PROP_USB_TYPE , &val);if (ret)
Greg Kroah-Hartman
maintainerPATCH 27/119 ASoC: rt5682: Disable jack detection interrupt during suspend
In reply to Greg Kroah-HartmanFrom: Matthias Kaehlcke <[email protected]>
commit 8b271370e963370703819bd9795a54d658071bed upstream.
The rt5682 driver switches its regmap to cache-only when the device suspends and back to regular mode on resume. When the jack detect interrupt fires rt5682_irq() schedules the jack detect work. This can result in invalid reads from the regmap in cache-only mode if the work runs before the device has resumed:
[ 56.245502] rt5682 9-001a: ASoC: error at soc_component_read_no_lock on rt5682.9-001a for register: [0x000000f0] -16
Disable the jack detection interrupt during suspend and re-enable it on resume. The driver already schedules the jack detection work on resume, so any state change during suspend is still handled.
This is essentially the same as commit f7d00a9be147 ("SoC:
rt5682s: Disable jack detection interrupt during suspend") for the rt5682s.
--- sound/soc/codecs/rt5682-i2c.c | 4 +++- sound/soc/codecs/rt5682.c | 6 ++++++ sound/soc/codecs/rt5682.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-)
sound/soc/codecs/rt5682-i2c.c +3 -1
@@ -267,7 +267,9 @@ static int rt5682_i2c_probe(struct i2c_c ret =devm_request_threaded_irq (&i2c->dev, i2c->irq,NULL , rt5682_irq,IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING |IRQF_ONESHOT ,"rt5682" , rt5682); -if (ret) +if (!ret) + rt5682->irq = i2c->irq; +else dev_err (&i2c->dev,"Failed to reguest IRQ: %d\n" , ret); }
sound/soc/codecs/rt5682.c +6 -0
@@ -2957,6 +2957,9 @@ static int rt5682_suspend(struct snd_socif (rt5682->is_sdw)return 0 ; +if (rt5682->irq) +disable_irq (rt5682->irq); +cancel_delayed_work_sync (&rt5682->jack_detect_work);cancel_delayed_work_sync (&rt5682->jd_check_work);if (rt5682->hs_jack && (rt5682->jack_type &SND_JACK_HEADSET ) ==SND_JACK_HEADSET ) {
@@ -3025,6 +3028,9 @@ static int rt5682_resume(struct snd_soc_mod_delayed_work (system_power_efficient_wq, &rt5682->jack_detect_work,msecs_to_jiffies (0 )); +if (rt5682->irq) +enable_irq (rt5682->irq); + return 0; }#else
sound/soc/codecs/rt5682.h +1 -0
@@ -1462,6 +1462,7 @@ struct rt5682_priv {int pll_out[RT5682_PLLS ];int jack_type; +int irq;int irq_work_delay_time; };
Greg Kroah-Hartman
maintainerPATCH 28/119 net: cdc_ncm: Deal with too low values of dwNtbOutMaxSize
In reply to Greg Kroah-HartmanFrom: Tudor Ambarus <[email protected]>
commit 7e01c7f7046efc2c7c192c3619db43292b98e997 upstream.
Currently in cdc_ncm_check_tx_max(), if dwNtbOutMaxSize is lower than the calculated "min" value, but greater than zero, the logic sets tx_max to dwNtbOutMaxSize. This is then used to allocate a new SKB in cdc_ncm_fill_tx_frame() where all the data is handled.
For small values of dwNtbOutMaxSize the memory allocated during alloc_skb(dwNtbOutMaxSize, GFP_ATOMIC) will have the same size, due to how size is aligned at alloc time:
size = SKB_DATA_ALIGN(size);
size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info));Thus we hit the same bug that we tried to squash with
commit 2be6d4d16a084 ("net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero")
Low values of dwNtbOutMaxSize do not cause an issue presently because at alloc_skb() time more memory (512b) is allocated than required for the SKB headers alone (320b), leaving some space (512b - 320b = 192b) for CDC data (172b).
However, if more elements (for example 3 x u64 = [24b]) were added to one of the SKB header structs, say 'struct skb_shared_info', increasing its original size (320b [320b aligned]) to something larger (344b [384b aligned]), then suddenly the CDC data (172b) no longer fits in the spare SKB data area (512b - 384b = 128b).
Consequently the SKB bounds checking semantics fails and panics:
skbuff: skb_over_panic: text:ffffffff831f755b len:184 put:172 head:ffff88811f1c6c00 data:ffff88811f1c6c00 tail:0xb8 end:0x80 dev:<NULL>
------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:113! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 57 Comm: kworker/0:2 Not tainted 5.15.106-syzkaller-00249-g19c0ed55a470 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/14/2023 Workqueue: mld mld_ifc_work RIP: 0010:skb_panic net/core/skbuff.c:113 [inline] RIP: 0010:skb_over_panic+0x14c/0x150 net/core/skbuff.c:118 [snip] Call Trace: <TASK> skb_put+0x151/0x210 net/core/skbuff.c:2047 skb_put_zero include/linux/skbuff.h:2422 [inline] cdc_ncm_ndp16 drivers/net/usb/cdc_ncm.c:1131 [inline] cdc_ncm_fill_tx_frame+0x11ab/0x3da0 drivers/net/usb/cdc_ncm.c:1308 cdc_ncm_tx_fixup+0xa3/0x100
Deal with too low values of dwNtbOutMaxSize, clamp it in the range [USB_CDC_NCM_NTB_MIN_OUT_SIZE, CDC_NCM_NTB_MAX_SIZE_TX]. We ensure enough data space is allocated to handle CDC data by making sure dwNtbOutMaxSize is not smaller than USB_CDC_NCM_NTB_MIN_OUT_SIZE.
--- drivers/net/usb/cdc_ncm.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
drivers/net/usb/cdc_ncm.c +15 -9
@@ -180,9 +180,12 @@ static u32 cdc_ncm_check_tx_max(struct uelse min = ctx->max_datagram_size + ctx->max_ndp_size +sizeof (struct usb_cdc_ncm_nth32 ); - max =min_t (u32,CDC_NCM_NTB_MAX_SIZE_TX ,le32_to_cpu (ctx->ncm_parm.dwNtbOutMaxSize)); -if (max ==0 ) +if (le32_to_cpu (ctx->ncm_parm.dwNtbOutMaxSize) ==0 ) max =CDC_NCM_NTB_MAX_SIZE_TX ;/* dwNtbOutMaxSize not set */ +else + max =clamp_t (u32,le32_to_cpu (ctx->ncm_parm.dwNtbOutMaxSize), +USB_CDC_NCM_NTB_MIN_OUT_SIZE , +CDC_NCM_NTB_MAX_SIZE_TX );/* some devices set dwNtbOutMaxSize too low for the above default */ min =min (min, max);
@@ -1243,6 +1246,9 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev* further. */ if (skb_out ==NULL ) { +/* If even the smallest allocation fails, abort. */ +if (ctx->tx_curr_size ==USB_CDC_NCM_NTB_MIN_OUT_SIZE ) + goto alloc_failed; ctx->tx_low_mem_max_cnt =min (ctx->tx_low_mem_max_cnt +1 , (unsigned )CDC_NCM_LOW_MEM_MAX_CNT ); ctx->tx_low_mem_val = ctx->tx_low_mem_max_cnt;
@@ -1261,13 +1267,8 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev skb_out =alloc_skb (ctx->tx_curr_size,GFP_ATOMIC );/* No allocation possible so we will abort */ -if (skb_out ==NULL ) { -if (skb !=NULL ) { -dev_kfree_skb_any (skb); - dev->net->stats.tx_dropped++; - } - goto exit_no_skb; - } +if (!skb_out) + goto alloc_failed; ctx->tx_low_mem_val--; }if (ctx->is_ndp16) {
@@ -1460,6 +1461,11 @@ cdc_ncm_fill_tx_frame(struct usbnet *devreturn skb_out; +alloc_failed: +if (skb) { +dev_kfree_skb_any (skb); + dev->net->stats.tx_dropped++; + } exit_no_skb:/* Start timer, if there is a remaining non-empty skb */ if (ctx->tx_curr_skb !=NULL && n >0 )
Greg Kroah-Hartman
maintainerPATCH 29/119 m68k: Move signal frame following exception on 68020/030
In reply to Greg Kroah-HartmanFrom: Finn Thain <[email protected]>
commit b845b574f86dcb6a70dfa698aa87a237b0878d2a upstream.
On 68030/020, an instruction such as, moveml %a2-%a3/%a5,%sp@- may cause a stack page fault during instruction execution (i.e. not at an instruction boundary) and produce a format 0xB exception frame.
In this situation, the value of USP will be unreliable. If a signal is to be delivered following the exception, this USP value is used to calculate the location for a signal frame. This can result in a corrupted user stack.
The corruption was detected in dash (actually in glibc) where it showed up as an intermittent "stack smashing detected" message and crash following signal delivery for SIGCHLD.
It was hard to reproduce that failure because delivery of the signal raced with the page fault and because the kernel places an unpredictable gap of up to 7 bytes between the USP and the signal frame.
A format 0xB exception frame can be produced by a bus error or an address error. The 68030 Users Manual says that address errors occur immediately upon detection during instruction prefetch. The instruction pipeline allows prefetch to overlap with other instructions, which means an address error can arise during the execution of a different instruction. So it seems likely that this patch may help in the address error case also.
--- arch/m68k/kernel/signal.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
arch/m68k/kernel/signal.c +10 -4
@@ -858,11 +858,17 @@ static inline int rt_setup_ucontext(stru }static inline void __user * -get_sigframe (struct ksignal *ksig,size_t frame_size) +get_sigframe (struct ksignal *ksig,struct pt_regs *tregs,size_t frame_size) {unsigned long usp =sigsp (rdusp (), ksig); +unsigned long gap =0 ; -return (void __user *)((usp - frame_size) &-8UL ); +if (CPU_IS_020_OR_030 && tregs->format ==0xb ) { +/* USP is unreliable so use worst-case value */ + gap =256 ; + } + +return (void __user *)((usp - gap - frame_size) &-8UL ); } static int setup_frame(struct ksignal *ksig, sigset_t *set,
@@ -880,7 +886,7 @@ static int setup_frame(struct ksignal *kreturn -EFAULT ; } - frame =get_sigframe (ksig,sizeof (*frame) + fsize); + frame =get_sigframe (ksig, tregs,sizeof (*frame) + fsize);if (fsize) err |=copy_to_user (frame +1 , regs +1 , fsize);
@@ -952,7 +958,7 @@ static int setup_rt_frame(struct ksignalreturn -EFAULT ; } - frame =get_sigframe (ksig,sizeof (*frame)); + frame =get_sigframe (ksig, tregs,sizeof (*frame));if (fsize) err |=copy_to_user (&frame->uc.uc_extra, regs +1 , fsize);
Greg Kroah-Hartman
maintainerPATCH 30/119 xtensa: fix signal delivery to FDPIC process
In reply to Greg Kroah-HartmanFrom: Max Filippov <[email protected]>
commit 9c2cc74fb31ec76b8b118c97041a6a154a3ff219 upstream.
Fetch function descriptor pointed to by the signal handler pointer from userspace on signal delivery and function pointer pointed to by the sa_restorer on return from the signal handler.
--- arch/xtensa/kernel/signal.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
arch/xtensa/kernel/signal.c +27 -8
@@ -343,7 +343,19 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,struct rt_sigframe *frame;int err =0 , sig = ksig->sig;unsigned long sp, ra, tp, ps; +unsigned long handler = (unsigned long )ksig->ka.sa.sa_handler; +unsigned long handler_fdpic_GOT =0 ;unsigned int base; +bool fdpic =IS_ENABLED (CONFIG_BINFMT_ELF_FDPIC ) && + (current->personality &FDPIC_FUNCPTRS ); + +if (fdpic) { +unsigned long __user *fdpic_func_desc = + (unsigned long __user *)handler; +if (__get_user (handler, &fdpic_func_desc[0 ]) || +__get_user (handler_fdpic_GOT, &fdpic_func_desc[1 ])) +return -EFAULT ; + } sp = regs->areg[1 ];
@@ -373,20 +385,26 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, err |=__copy_to_user (&frame->uc.uc_sigmask, set,sizeof (*set));if (ksig->ka.sa.sa_flags &SA_RESTORER ) { - ra = (unsigned long )ksig->ka.sa.sa_restorer; +if (fdpic) { +unsigned long __user *fdpic_func_desc = + (unsigned long __user *)ksig->ka.sa.sa_restorer; + + err |=__get_user (ra, fdpic_func_desc); + }else { + ra = (unsigned long )ksig->ka.sa.sa_restorer; + } }else {/* Create sys_rt_sigreturn syscall in stack frame */ err |=gen_return_code (frame->retcode); - -if (err) { -return -EFAULT ; - } ra = (unsigned long ) frame->retcode; } -/* +if (err) +return -EFAULT ; + +/* * Create signal handler execution context. * Return context not modified until this point. */
@@ -394,8 +412,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,/* Set up registers for signal handler; preserve the threadptr */ tp = regs->threadptr; ps = regs->ps; -start_thread (regs, (unsigned long ) ksig->ka.sa.sa_handler, - (unsigned long ) frame); +start_thread (regs, handler, (unsigned long )frame);/* Set up a stack frame for a call4 if userspace uses windowed ABI */ if (ps &PS_WOE_MASK ) {
@@ -413,6 +430,8 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set, regs->areg[base +4 ] = (unsigned long ) &frame->uc; regs->threadptr = tp; regs->ps = ps; +if (fdpic) + regs->areg[base +11 ] = handler_fdpic_GOT;pr_debug ("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08lx\n" , current->comm, current->pid, sig, frame, regs->pc);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 31/119 xtensa: add __bswap{si,di}2 helpers
In reply to Greg Kroah-HartmanFrom: Max Filippov <[email protected]>
commit 034f4a7877c32a8efd6beee4d71ed14e424499a9 upstream.
gcc-13 may generate calls for __bswap{si,di}2. This breaks the kernel build when optimization for size is selected. Add __bswap{si,di}2 helpers to fix that.
--- arch/xtensa/kernel/xtensa_ksyms.c | 4 ++++ arch/xtensa/lib/Makefile | 2 +- arch/xtensa/lib/bswapdi2.S | 21 +++++++++++++++++++++ arch/xtensa/lib/bswapsi2.S | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 arch/xtensa/lib/bswapdi2.S create mode 100644 arch/xtensa/lib/bswapsi2.S
arch/xtensa/kernel/xtensa_ksyms.c +4 -0
@@ -56,6 +56,8 @@ EXPORT_SYMBOL(empty_zero_page);*/ extern long long __ashrdi3 (long long ,int );extern long long __ashldi3 (long long ,int ); +extern long long __bswapdi2 (long long ); +extern int __bswapsi2 (int );extern long long __lshrdi3 (long long ,int );extern int __divsi3 (int ,int );extern int __modsi3 (int ,int );
@@ -66,6 +68,8 @@ extern unsigned long long __umulsidi3(unEXPORT_SYMBOL (__ashldi3);EXPORT_SYMBOL (__ashrdi3); +EXPORT_SYMBOL (__bswapdi2); +EXPORT_SYMBOL (__bswapsi2);EXPORT_SYMBOL (__lshrdi3);EXPORT_SYMBOL (__divsi3);EXPORT_SYMBOL (__modsi3);
arch/xtensa/lib/Makefile +1 -1
@@ -4,7 +4,7 @@ # lib-y += memcopy.o memset.o checksum.o \ - ashldi3.o ashrdi3.o lshrdi3.o \ + ashldi3.o ashrdi3.o bswapdi2.o bswapsi2.o lshrdi3.o \ divsi3.o udivsi3.o modsi3.o umodsi3.o mulsi3.o umulsidi3.o \ usercopy.o strncpy_user.o strnlen_user.o lib-$(CONFIG_PCI) += pci-auto.o
arch/xtensa/lib/bswapdi2.S new file +21 -0
@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 */ +#include <linux/linkage.h> +#include <asm/asmmacro.h> +#include <asm/core.h> + +ENTRY(__bswapdi2) + + abi_entry_default + ssai 8 + srli a4, a2, 16 + src a4, a4, a2 + src a4, a4, a4 + src a4, a2, a4 + srli a2, a3, 16 + src a2, a2, a3 + src a2, a2, a2 + src a2, a3, a2 + mov a3, a4 + abi_ret_default + +ENDPROC(__bswapdi2)
arch/xtensa/lib/bswapsi2.S new file +16 -0
@@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0 */ +#include <linux/linkage.h> +#include <asm/asmmacro.h> +#include <asm/core.h> + +ENTRY(__bswapsi2) + + abi_entry_default + ssai 8 + srli a3, a2, 16 + src a3, a3, a2 + src a3, a3, a3 + src a2, a2, a3 + abi_ret_default + +ENDPROC(__bswapsi2)
Greg Kroah-Hartman
maintainerPATCH 32/119 parisc: Use num_present_cpus() in alternative patching code
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit b6405f0829d7b1dd926ba3ca5f691cab835abfaa upstream.
When patching the kernel code some alternatives depend on SMP vs. !SMP. Use the value of num_present_cpus() instead of num_online_cpus() to decide, otherwise we may run into issues if and additional CPU is enabled after having loaded a module while only one CPU was enabled.
--- arch/parisc/kernel/alternative.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/parisc/kernel/alternative.c +1 -1
@@ -25,7 +25,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start, {struct alt_instr *entry;int index =0 , applied =0 ; -int num_cpus =num_online_cpus (); +int num_cpus =num_present_cpus ();u16 cond_check; cond_check = ALT_COND_ALWAYS |
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 33/119 parisc: Handle kgdb breakpoints only in kernel context
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 6888ff04e37d01295620a73f3f7efbc79f6ef152 upstream.
The kernel kgdb break instructions should only be handled when running in kernel context.
--- arch/parisc/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/kernel/traps.c +2 -2
@@ -302,8 +302,8 @@ static void handle_break(struct pt_regs#endif #ifdef CONFIG_KGDB -if (unlikely (iir ==PARISC_KGDB_COMPILED_BREAK_INSN || - iir ==PARISC_KGDB_BREAK_INSN )) { +if (unlikely ((iir ==PARISC_KGDB_COMPILED_BREAK_INSN || + iir ==PARISC_KGDB_BREAK_INSN )) && !user_mode (regs)) {kgdb_handle_exception (9 ,SIGTRAP ,0 , regs);return ; }
Greg Kroah-Hartman
maintainerPATCH 34/119 parisc: Fix flush_dcache_page() for usage from irq context
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 61e150fb310729c98227a5edf6e4a3619edc3702 upstream.
Since at least kernel 6.1, flush_dcache_page() is called with IRQs disabled, e.g. from aio_complete().
But the current implementation for flush_dcache_page() on parisc unintentionally re-enables IRQs, which may lead to deadlocks.
Fix it by using xa_lock_irqsave() and xa_unlock_irqrestore() for the flush_dcache_mmap_*lock() macros instead.
--- arch/parisc/include/asm/cacheflush.h | 4 ++++ arch/parisc/kernel/cache.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-)
arch/parisc/include/asm/cacheflush.h +4 -0
@@ -48,6 +48,10 @@ void flush_dcache_page(struct page *page);#define flush_dcache_mmap_lock (mapping) xa_lock_irq(&mapping->i_pages)#define flush_dcache_mmap_unlock (mapping) xa_unlock_irq(&mapping->i_pages) +#define flush_dcache_mmap_lock_irqsave (mapping, flags) \ + xa_lock_irqsave(&mapping->i_pages, flags) +#define flush_dcache_mmap_unlock_irqrestore (mapping, flags) \ + xa_unlock_irqrestore(&mapping->i_pages, flags)#define flush_icache_page (vma,page) do { \ flush_kernel_dcache_page_addr(page_address(page)); \
arch/parisc/kernel/cache.c +3 -2
@@ -399,6 +399,7 @@ void flush_dcache_page(struct page *page)unsigned long offset;unsigned long addr, old_addr =0 ;unsigned long count =0 ; +unsigned long flags;pgoff_t pgoff;if (mapping && !mapping_mapped (mapping)) {
@@ -420,7 +421,7 @@ void flush_dcache_page(struct page *page)* to flush one address here for them all to become coherent * on machines that support equivalent aliasing */ -flush_dcache_mmap_lock (mapping); +flush_dcache_mmap_lock_irqsave (mapping, flags); vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { offset = (pgoff - mpnt->vm_pgoff) <<PAGE_SHIFT ; addr = mpnt->vm_start + offset;
@@ -460,7 +461,7 @@ void flush_dcache_page(struct page *page) }WARN_ON (++count ==4096 ); } -flush_dcache_mmap_unlock (mapping); +flush_dcache_mmap_unlock_irqrestore (mapping, flags); }EXPORT_SYMBOL (flush_dcache_page);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 35/119 parisc: Allow to reboot machine after system halt
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 2028315cf59bb899a5ac7e87dc48ecb8fac7ac24 upstream.
In case a machine can't power-off itself on system shutdown, allow the user to reboot it by pressing the RETURN key.
--- arch/parisc/kernel/process.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/parisc/kernel/process.c +8 -3
@@ -122,13 +122,18 @@ void machine_power_off(void)/* It seems we have no way to power the system off via * software. The user has to press the button himself. */ -printk (KERN_EMERG "System shut down completed.\n" -"Please power this system off now." ); +printk ("Power off or press RETURN to reboot.\n" );/* prevent soft lockup/stalled CPU messages for endless loop. */ rcu_sysrq_start ();lockup_detector_soft_poweroff (); -for (;;); +while (1 ) { +/* reboot if user presses RETURN key */ +if (pdc_iodc_getc () ==13 ) { +printk ("Rebooting...\n" ); +machine_restart (NULL ); + } + } }void (*pm_power_off)(void );
Greg Kroah-Hartman
maintainerPATCH 36/119 parisc: Enable LOCKDEP support
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit adf8e96a7ea670d45b5de7594acc67e8f4787ae6 upstream.
--- arch/parisc/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
arch/parisc/Kconfig +4 -0
@@ -129,6 +129,10 @@ config PM config STACKTRACE_SUPPORT def_bool y +config LOCKDEP_SUPPORT + bool + default y + config ISA_DMA_API bool
Greg Kroah-Hartman
maintainerPATCH 37/119 parisc: Handle kprobes breakpoints only in kernel context
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit df419492e428b6a2bce98d0f613c58a13da6666c upstream.
The kernel kprobes break instructions should only be handled when running in kernel context.
--- arch/parisc/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/kernel/traps.c +2 -2
@@ -291,11 +291,11 @@ static void handle_break(struct pt_regs }#ifdef CONFIG_KPROBES -if (unlikely (iir ==PARISC_KPROBES_BREAK_INSN )) { +if (unlikely (iir ==PARISC_KPROBES_BREAK_INSN && !user_mode (regs))) {parisc_kprobe_break_handler (regs);return ; } -if (unlikely (iir ==PARISC_KPROBES_BREAK_INSN2 )) { +if (unlikely (iir ==PARISC_KPROBES_BREAK_INSN2 && !user_mode (regs))) {parisc_kprobe_ss_handler (regs);return ; }
Greg Kroah-Hartman
maintainerPATCH 38/119 gpio: mockup: Fix mode of debugfs files
In reply to Greg Kroah-HartmanFrom: Zev Weiss <[email protected]>
commit 0a1bb16e0fe6650c3841e611de374bfd5578ad70 upstream.
This driver's debugfs files have had a read operation since commit 2a9e27408e12 ("gpio: mockup: rework debugfs interface"), but were still being created with write-only mode bits. Update them to indicate that the files can also be read.
--- drivers/gpio/gpio-mockup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpio-mockup.c +1 -1
@@ -368,7 +368,7 @@ static void gpio_mockup_debugfs_setup(st priv->offset = i; priv->desc =gpiochip_get_desc (gc, i); -debugfs_create_file (name,0200 , chip->dbg_dir, priv, +debugfs_create_file (name,0600 , chip->dbg_dir, priv, &gpio_mockup_debugfs_ops); } }
Greg Kroah-Hartman
maintainerPATCH 39/119 btrfs: use nofs when cleaning up aborted transactions
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 597441b3436a43011f31ce71dc0a6c0bf5ce958a upstream.
Our CI system caught a lockdep splat:
======================================================
WARNING: possible circular locking dependency detected
6.3.0-rc7+ #1167 Not tainted
------------------------------------------------------
kswapd0/46 is trying to acquire lock:
ffff8c6543abd650 (sb_internal#2){++++}-{0:0}, at: btrfs_commit_inode_delayed_inode+0x5f/0x120
but task is already holding lock:
ffffffffabe61b40 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat+0x4aa/0x7a0
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (fs_reclaim){+.+.}-{0:0}:
fs_reclaim_acquire+0xa5/0xe0 kmem_cache_alloc+0x31/0x2c0 alloc_extent_state+0x1d/0xd0 __clear_extent_bit+0x2e0/0x4f0 try_release_extent_mapping+0x216/0x280 btrfs_release_folio+0x2e/0x90 invalidate_inode_pages2_range+0x397/0x470 btrfs_cleanup_dirty_bgs+0x9e/0x210 btrfs_cleanup_one_transaction+0x22/0x760 btrfs_commit_transaction+0x3b7/0x13a0 create_subvol+0x59b/0x970 btrfs_mksubvol+0x435/0x4f0 __btrfs_ioctl_snap_create+0x11e/0x1b0 btrfs_ioctl_snap_create_v2+0xbf/0x140 btrfs_ioctl+0xa45/0x28f0 __x64_sys_ioctl+0x88/0xc0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc
-> #0 (sb_internal#2){++++}-{0:0}:
__lock_acquire+0x1435/0x21a0 lock_acquire+0xc2/0x2b0 start_transaction+0x401/0x730 btrfs_commit_inode_delayed_inode+0x5f/0x120 btrfs_evict_inode+0x292/0x3d0 evict+0xcc/0x1d0 inode_lru_isolate+0x14d/0x1e0 __list_lru_walk_one+0xbe/0x1c0 list_lru_walk_one+0x58/0x80 prune_icache_sb+0x39/0x60 super_cache_scan+0x161/0x1f0 do_shrink_slab+0x163/0x340 shrink_slab+0x1d3/0x290 shrink_node+0x300/0x720 balance_pgdat+0x35c/0x7a0 kswapd+0x205/0x410 kthread+0xf0/0x120 ret_from_fork+0x29/0x50
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(fs_reclaim);
lock(sb_internal#2);
lock(fs_reclaim);
lock(sb_internal#2);*** DEADLOCK ***
3 locks held by kswapd0/46:
#0: ffffffffabe61b40 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat+0x4aa/0x7a0 #1: ffffffffabe50270 (shrinker_rwsem){++++}-{3:3}, at: shrink_slab+0x113/0x290 #2: ffff8c6543abd0e0 (&type->s_umount_key#44){++++}-{3:3}, at: super_cache_scan+0x38/0x1f0
stack backtrace: CPU: 0 PID: 46 Comm: kswapd0 Not tainted 6.3.0-rc7+ #1167 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x58/0x90 check_noncircular+0xd6/0x100 ? save_trace+0x3f/0x310 ? add_lock_to_list+0x97/0x120 __lock_acquire+0x1435/0x21a0 lock_acquire+0xc2/0x2b0 ? btrfs_commit_inode_delayed_inode+0x5f/0x120 start_transaction+0x401/0x730 ? btrfs_commit_inode_delayed_inode+0x5f/0x120 btrfs_commit_inode_delayed_inode+0x5f/0x120 btrfs_evict_inode+0x292/0x3d0 ? lock_release+0x134/0x270 ? __pfx_wake_bit_function+0x10/0x10 evict+0xcc/0x1d0 inode_lru_isolate+0x14d/0x1e0 __list_lru_walk_one+0xbe/0x1c0 ? __pfx_inode_lru_isolate+0x10/0x10 ? __pfx_inode_lru_isolate+0x10/0x10 list_lru_walk_one+0x58/0x80 prune_icache_sb+0x39/0x60 super_cache_scan+0x161/0x1f0 do_shrink_slab+0x163/0x340 shrink_slab+0x1d3/0x290 shrink_node+0x300/0x720 balance_pgdat+0x35c/0x7a0 kswapd+0x205/0x410 ? __pfx_autoremove_wake_function+0x10/0x10 ? __pfx_kswapd+0x10/0x10 kthread+0xf0/0x120 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x29/0x50 </TASK>
This happens because when we abort the transaction in the transaction commit path we call invalidate_inode_pages2_range on our block group cache inodes (if we have space cache v1) and any delalloc inodes we may have. The plain invalidate_inode_pages2_range() call passes through GFP_KERNEL, which makes sense in most cases, but not here. Wrap these two invalidate callees with memalloc_nofs_save/memalloc_nofs_restore to make sure we don't end up with the fs reclaim dependency under the transaction dependency.
--- fs/btrfs/disk-io.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/btrfs/disk-io.c +9 -0
@@ -5035,7 +5035,11 @@ static void btrfs_destroy_delalloc_inode*/ inode =igrab (&btrfs_inode->vfs_inode);if (inode) { +unsigned int nofs_flag; + + nofs_flag =memalloc_nofs_save ();invalidate_inode_pages2 (inode->i_mapping); +memalloc_nofs_restore (nofs_flag);iput (inode); }spin_lock (&root->delalloc_lock);
@@ -5140,7 +5144,12 @@ static void btrfs_cleanup_bg_io(struct b inode = cache->io_ctl.inode;if (inode) { +unsigned int nofs_flag; + + nofs_flag =memalloc_nofs_save ();invalidate_inode_pages2 (inode->i_mapping); +memalloc_nofs_restore (nofs_flag); +BTRFS_I (inode)->generation =0 ; cache->io_ctl.inode =NULL ;iput (inode);
Greg Kroah-Hartman
maintainerPATCH 40/119 dt-binding: cdns,usb3: Fix cdns,on-chip-buff-size type
In reply to Greg Kroah-HartmanFrom: Frank Li <[email protected]>
commit 50a1726b148ff30778cb8a6cf3736130b07c93fd upstream.
In cdns3-gadget.c, 'cdns,on-chip-buff-size' was read using device_property_read_u16(). It resulted in 0 if a 32bit value was used in dts. This commit fixes the dt binding doc to declare it as u16.
--- Documentation/devicetree/bindings/usb/cdns,usb3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/usb/cdns,usb3.yaml +1 -1
@@ -64,7 +64,7 @@ properties: description: size of memory intended as internal memory for endpoints buffers expressed in KB - $ref: /schemas/types.yaml#/definitions/uint32 + $ref: /schemas/types.yaml#/definitions/uint16 cdns,phyrst-a-enable: description: Enable resetting of PHY if Rx fail is detected
Greg Kroah-Hartman
maintainerPATCH 41/119 drm/mgag200: Fix gamma lut not initialized.
In reply to Greg Kroah-HartmanFrom: Jocelyn Falempe <[email protected]>
commit ad81e23426a651eb89a4b306e1c4169e6308c124 upstream.
When mgag200 switched from simple KMS to regular atomic helpers, the initialization of the gamma settings was lost.
This leads to a black screen, if the bios/uefi doesn't use the same pixel color depth.
v2: rebase on top of drm-misc-fixes, and add Cc stable tag.
--- drivers/gpu/drm/mgag200/mgag200_mode.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/mgag200/mgag200_mode.c +5 -0
@@ -640,6 +640,11 @@ void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_if (funcs->pixpllc_atomic_update) funcs->pixpllc_atomic_update (crtc, old_state); +if (crtc_state->gamma_lut) +mgag200_crtc_set_gamma (mdev, format, crtc_state->gamma_lut->data); +else +mgag200_crtc_set_gamma_linear (mdev, format); +mgag200_enable_display (mdev);if (funcs->enable_vidrst)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 42/119 drm/radeon: reintroduce radeon_dp_work_func content
In reply to Greg Kroah-HartmanFrom: Alex Deucher <[email protected]>
commit a34fc1bcd2c4d8b09dcfc0b95ac65bca1e579bd7 upstream.
Put back the radeon_dp_work_func logic. It seems that handling DP RX interrupts is necessary to make some panels work. This was removed with the MST support, but it regresses some systems so add it back. While we are here, add the proper mutex locking.
--- drivers/gpu/drm/radeon/radeon_irq_kms.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/gpu/drm/radeon/radeon_irq_kms.c +10 -0
@@ -100,6 +100,16 @@ static void radeon_hotplug_work_func(strstatic void radeon_dp_work_func (struct work_struct *work) { + struct radeon_device *rdev = container_of(work, struct radeon_device, + dp_work); +struct drm_device *dev = rdev->ddev; +struct drm_mode_config *mode_config = &dev->mode_config; +struct drm_connector *connector; + +mutex_lock (&mode_config->mutex); +list_for_each_entry (connector, &mode_config->connector_list, head) +radeon_connector_hotplug (connector); +mutex_unlock (&mode_config->mutex); }/**
Greg Kroah-Hartman
maintainerPATCH 43/119 drm/amd/pm: add missing NotifyPowerSource message mapping for SMU13.0.7
In reply to Greg Kroah-HartmanFrom: Evan Quan <[email protected]>
commit 0d2dd02d74e6377268f56b90261de0fae8f0d2cb upstream.
Otherwise, the power source switching will fail due to message unavailable.
--- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +1 -0
@@ -125,6 +125,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] =MSG_MAP (ArmD3, PPSMC_MSG_ArmD3,0 ),MSG_MAP (AllowGpo, PPSMC_MSG_SetGpoAllow,0 ),MSG_MAP (GetPptLimit, PPSMC_MSG_GetPptLimit,0 ), + MSG_MAP(NotifyPowerSource, PPSMC_MSG_NotifyPowerSource, 0), }; static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 44/119 drm/amd/pm: Fix output of pp_od_clk_voltage
In reply to Greg Kroah-HartmanFrom: Jonatas Esteves <[email protected]>
commit 40baba5693b9af586dc1063af603d05a79e57a6b upstream.
Printing the other clock types should not be conditioned on being able to print OD_SCLK. Some GPUs currently have limited capability of only printing a subset of these.
Since this condition was introduced in v5.18-rc1, reading from pp_od_clk_voltage has been returning empty on the Asus ROG Strix G15 (2021).
--- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/pm/amdgpu_pm.c +5 -7
@@ -869,13 +869,11 @@ static ssize_t amdgpu_get_pp_od_clk_volt }if (ret == -ENOENT ) { size =amdgpu_dpm_print_clock_levels (adev,OD_SCLK , buf); -if (size >0 ) { - size +=amdgpu_dpm_print_clock_levels (adev,OD_MCLK , buf + size); - size +=amdgpu_dpm_print_clock_levels (adev,OD_VDDC_CURVE , buf + size); - size +=amdgpu_dpm_print_clock_levels (adev,OD_VDDGFX_OFFSET , buf + size); - size +=amdgpu_dpm_print_clock_levels (adev,OD_RANGE , buf + size); - size +=amdgpu_dpm_print_clock_levels (adev,OD_CCLK , buf + size); - } + size +=amdgpu_dpm_print_clock_levels (adev,OD_MCLK , buf + size); + size +=amdgpu_dpm_print_clock_levels (adev,OD_VDDC_CURVE , buf + size); + size +=amdgpu_dpm_print_clock_levels (adev,OD_VDDGFX_OFFSET , buf + size); + size +=amdgpu_dpm_print_clock_levels (adev,OD_RANGE , buf + size); + size +=amdgpu_dpm_print_clock_levels (adev,OD_CCLK , buf + size); }if (size ==0 )
Greg Kroah-Hartman
maintainerPATCH 45/119 Revert "binder_alloc: add missing mmap_lock calls when using the VMA"
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
commit b15655b12ddca7ade09807f790bafb6fab61b50a upstream.
This reverts commit 44e602b4e52f70f04620bbbf4fe46ecb40170bde.
This caused a performance regression particularly when pages are getting reclaimed. We don't need to acquire the mmap_lock to determine when the binder buffer has been fully initialized. A subsequent patch will bring back the lockless approach for this.
[cmllamas: resolved trivial conflicts with renaming of alloc->mm]
--- drivers/android/binder_alloc.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-)
drivers/android/binder_alloc.c +10 -21
@@ -380,15 +380,12 @@ static struct binder_buffer *binder_allosize_t size, data_offsets_size;int ret; -mmap_read_lock (alloc->mm);if (!binder_alloc_get_vma (alloc)) { -mmap_read_unlock (alloc->mm);binder_alloc_debug (BINDER_DEBUG_USER_ERROR ,"%d: binder_alloc_buf, no vma\n" , alloc->pid);return ERR_PTR (-ESRCH ); } -mmap_read_unlock (alloc->mm); data_offsets_size =ALIGN (data_size,sizeof (void *)) +ALIGN (offsets_size,sizeof (void *));
@@ -916,25 +913,17 @@ void binder_alloc_print_pages(struct seq* Make sure the binder_alloc is fully initialized, otherwise we might * read inconsistent state. */ - -mmap_read_lock (alloc->mm); -if (binder_alloc_get_vma (alloc) ==NULL ) { -mmap_read_unlock (alloc->mm); - goto uninitialized; - } - -mmap_read_unlock (alloc->mm); -for (i =0 ; i < alloc->buffer_size /PAGE_SIZE ; i++) { - page = &alloc->pages[i]; -if (!page->page_ptr) - free++; -else if (list_empty (&page->lru)) - active++; -else - lru++; +if (binder_alloc_get_vma (alloc) !=NULL ) { +for (i =0 ; i < alloc->buffer_size /PAGE_SIZE ; i++) { + page = &alloc->pages[i]; +if (!page->page_ptr) + free++; +else if (list_empty (&page->lru)) + active++; +else + lru++; + } } - -uninitialized:mutex_unlock (&alloc->mutex);seq_printf (m," pages: %d:%d:%d\n" , active, lru, free);seq_printf (m," pages high watermark: %zu\n" , alloc->pages_high);
Greg Kroah-Hartman
maintainerPATCH 46/119 Revert "android: binder: stop saving a pointer to the VMA"
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
commit c0fd2101781ef761b636769b2f445351f71c3626 upstream.
This reverts commit a43cfc87caaf46710c8027a8c23b8a55f1078f19.
This patch fixed an issue reported by syzkaller in [1]. However, this turned out to be only a band-aid in binder. The root cause, as bisected by syzkaller, was fixed by commit 5789151e48ac ("mm/mmap: undo ->mmap() when mas_preallocate() fails"). We no longer need the patch for binder.
Reverting such patch allows us to have a lockless access to alloc->vma in specific cases where the mmap_lock is not required. This approach avoids the contention that caused a performance regression.
[1] https://lore.kernel.org/all/[email protected]
[cmllamas: resolved conflicts with rework of alloc->mm and removal of
binder_alloc_set_vma() also fixed comment section]
--- drivers/android/binder_alloc.c | 17 +++++++++-------- drivers/android/binder_alloc.h | 4 ++-- drivers/android/binder_alloc_selftest.c | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-)
drivers/android/binder_alloc.c +9 -8
@@ -213,7 +213,7 @@ static int binder_update_page_range(struif (mm) {mmap_read_lock (mm); - vma =vma_lookup (mm, alloc->vma_addr); + vma = alloc->vma; }if (!vma && need_mm) {
@@ -314,9 +314,11 @@ static inline struct vm_area_struct *bin {struct vm_area_struct *vma =NULL ; -if (alloc->vma_addr) - vma =vma_lookup (alloc->mm, alloc->vma_addr); - +if (alloc->vma) { +/* Look at description in binder_alloc_set_vma */ +smp_rmb (); + vma = alloc->vma; + }return vma; }
@@ -775,7 +777,7 @@ int binder_alloc_mmap_handler(struct bin buffer->free =1 ;binder_insert_free_buffer (alloc, buffer); alloc->free_async_space = alloc->buffer_size /2 ; - alloc->vma_addr = vma->vm_start; + alloc->vma = vma;return 0 ;
@@ -805,8 +807,7 @@ void binder_alloc_deferred_release(struc buffers =0 ;mutex_lock (&alloc->mutex); -BUG_ON (alloc->vma_addr && -vma_lookup (alloc->mm, alloc->vma_addr)); +BUG_ON (alloc->vma);while ((n =rb_first (&alloc->allocated_buffers))) { buffer = rb_entry(n, struct binder_buffer, rb_node);
@@ -958,7 +959,7 @@ int binder_alloc_get_allocated_count(str*/ void binder_alloc_vma_close (struct binder_alloc *alloc) { - alloc->vma_addr =0 ; + alloc->vma =0 ; }/**
drivers/android/binder_alloc.h +2 -2
@@ -75,7 +75,7 @@ struct binder_lru_page {/** * struct binder_alloc - per-binder proc state for binder allocator * @mutex: protects binder_alloc fields -* @vma_addr: vm_area_struct->vm_start passed to mmap_handler +* @vma: vm_area_struct passed to mmap_handler * (invariant after mmap) * @mm: copy of task->mm (invariant after open) * @buffer: base of per-proc address space mapped via mmap
@@ -99,7 +99,7 @@ struct binder_lru_page {*/ struct binder_alloc {struct mutex mutex; -unsigned long vma_addr; +struct vm_area_struct *vma;struct mm_struct *mm;void __user *buffer;struct list_head buffers;
drivers/android/binder_alloc_selftest.c +1 -1
@@ -287,7 +287,7 @@ void binder_selftest_alloc(struct binderif (!binder_selftest_run)return ;mutex_lock (&binder_selftest_lock); -if (!binder_selftest_run || !alloc->vma_addr) +if (!binder_selftest_run || !alloc->vma) goto done;pr_info ("STARTED\n" );binder_selftest_alloc_offset (alloc, end_offset,0 );
Greg Kroah-Hartman
maintainerPATCH 47/119 binder: add lockless binder_alloc_(set|get)_vma()
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
commit 0fa53349c3acba0239369ba4cd133740a408d246 upstream.
Bring back the original lockless design in binder_alloc to determine whether the buffer setup has been completed by the ->mmap() handler. However, this time use smp_load_acquire() and smp_store_release() to wrap all the ordering in a single macro call.
Also, add comments to make it evident that binder uses alloc->vma to determine when the binder_alloc has been fully initialized. In these scenarios acquiring the mmap_lock is not required.
--- drivers/android/binder_alloc.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
drivers/android/binder_alloc.c +14 -10
@@ -309,17 +309,18 @@ err_no_vma:return vma ? -ENOMEM : -ESRCH ; } +static inline void binder_alloc_set_vma (struct binder_alloc *alloc, +struct vm_area_struct *vma) +{ +/* pairs with smp_load_acquire in binder_alloc_get_vma() */ +smp_store_release (&alloc->vma, vma); +} +static inline struct vm_area_struct *binder_alloc_get_vma (struct binder_alloc *alloc) { -struct vm_area_struct *vma =NULL ; - -if (alloc->vma) { -/* Look at description in binder_alloc_set_vma */ -smp_rmb (); - vma = alloc->vma; - } -return vma; +/* pairs with smp_store_release in binder_alloc_set_vma() */ +return smp_load_acquire (&alloc->vma); }static bool debug_low_async_space_locked (struct binder_alloc *alloc,int pid)
@@ -382,6 +383,7 @@ static struct binder_buffer *binder_allosize_t size, data_offsets_size;int ret; +/* Check binder_alloc is fully initialized */ if (!binder_alloc_get_vma (alloc)) { binder_alloc_debug(BINDER_DEBUG_USER_ERROR, "%d: binder_alloc_buf, no vma\n",
@@ -777,7 +779,9 @@ int binder_alloc_mmap_handler(struct bin buffer->free =1 ;binder_insert_free_buffer (alloc, buffer); alloc->free_async_space = alloc->buffer_size /2 ; - alloc->vma = vma; + +/* Signal binder_alloc is fully initialized */ +binder_alloc_set_vma (alloc, vma);return 0 ;
@@ -959,7 +963,7 @@ int binder_alloc_get_allocated_count(str*/ void binder_alloc_vma_close (struct binder_alloc *alloc) { - alloc->vma =0 ; +binder_alloc_set_vma (alloc,NULL ); }/**
Greg Kroah-Hartman
maintainerPATCH 48/119 binder: fix UAF caused by faulty buffer cleanup
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
commit bdc1c5fac982845a58d28690cdb56db8c88a530d upstream.
In binder_transaction_buffer_release() the 'failed_at' offset indicates the number of objects to clean up. However, this function was changed by commit 44d8047f1d87 ("binder: use standard functions to allocate fds"), to release all the objects in the buffer when 'failed_at' is zero.
This introduced an issue when a transaction buffer is released without any objects having been processed so far. In this case, 'failed_at' is indeed zero yet it is misinterpreted as releasing the entire buffer.
This leads to use-after-free errors where nodes are incorrectly freed and subsequently accessed. Such is the case in the following KASAN report:
==================================================================
BUG: KASAN: slab-use-after-free in binder_thread_read+0xc40/0x1f30 Read of size 8 at addr ffff4faf037cfc58 by task poc/474 CPU: 6 PID: 474 Comm: poc Not tainted 6.3.0-12570-g7df047b3f0aa #5 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace+0x94/0xec show_stack+0x18/0x24 dump_stack_lvl+0x48/0x60 print_report+0xf8/0x5b8 kasan_report+0xb8/0xfc __asan_load8+0x9c/0xb8 binder_thread_read+0xc40/0x1f30 binder_ioctl+0xd9c/0x1768 __arm64_sys_ioctl+0xd4/0x118 invoke_syscall+0x60/0x188 [...] Allocated by task 474: kasan_save_stack+0x3c/0x64 kasan_set_track+0x2c/0x40 kasan_save_alloc_info+0x24/0x34 __kasan_kmalloc+0xb8/0xbc kmalloc_trace+0x48/0x5c binder_new_node+0x3c/0x3a4 binder_transaction+0x2b58/0x36f0 binder_thread_write+0x8e0/0x1b78 binder_ioctl+0x14a0/0x1768 __arm64_sys_ioctl+0xd4/0x118 invoke_syscall+0x60/0x188 [...] Freed by task 475: kasan_save_stack+0x3c/0x64 kasan_set_track+0x2c/0x40 kasan_save_free_info+0x38/0x5c __kasan_slab_free+0xe8/0x154 __kmem_cache_free+0x128/0x2bc kfree+0x58/0x70 binder_dec_node_tmpref+0x178/0x1fc binder_transaction_buffer_release+0x430/0x628 binder_transaction+0x1954/0x36f0 binder_thread_write+0x8e0/0x1b78 binder_ioctl+0x14a0/0x1768 __arm64_sys_ioctl+0xd4/0x118 invoke_syscall+0x60/0x188 [...] ==================================================================
In order to avoid these issues, let's always calculate the intended 'failed_at' offset beforehand. This is renamed and wrapped in a helper function to make it clear and convenient.
--- drivers/android/binder.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/android/binder.c +21 -7
@@ -1934,24 +1934,23 @@ static void binder_deferred_fd_close(intstatic void binder_transaction_buffer_release (struct binder_proc *proc,struct binder_thread *thread,struct binder_buffer *buffer, -binder_size_t failed_at, +binder_size_t off_end_offset,bool is_failure) {int debug_id = buffer->debug_id; -binder_size_t off_start_offset, buffer_offset, off_end_offset; +binder_size_t off_start_offset, buffer_offset;binder_debug (BINDER_DEBUG_TRANSACTION ,"%d buffer release %d, size %zd-%zd, failed at %llx\n" , proc->pid, buffer->debug_id, buffer->data_size, buffer->offsets_size, - (unsigned long long )failed_at); + (unsigned long long )off_end_offset);if (buffer->target_node)binder_dec_node (buffer->target_node,1 ,0 ); off_start_offset =ALIGN (buffer->data_size,sizeof (void *)); - off_end_offset = is_failure && failed_at ? failed_at : - off_start_offset + buffer->offsets_size; +for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset +=sizeof (binder_size_t)) {struct binder_object_header *hdr;
@@ -2111,6 +2110,21 @@ static void binder_transaction_buffer_re } } +/* Clean up all the objects in the buffer */ +static inline void binder_release_entire_buffer (struct binder_proc *proc, +struct binder_thread *thread, +struct binder_buffer *buffer, +bool is_failure) +{ +binder_size_t off_end_offset; + + off_end_offset =ALIGN (buffer->data_size,sizeof (void *)); + off_end_offset += buffer->offsets_size; + +binder_transaction_buffer_release (proc, thread, buffer, + off_end_offset, is_failure); +} +static int binder_translate_binder (struct flat_binder_object *fp,struct binder_transaction *t,struct binder_thread *thread)
@@ -2801,7 +2815,7 @@ static int binder_proc_transaction(struc t_outdated->buffer =NULL ; buffer->transaction =NULL ;trace_binder_transaction_update_buffer_release (buffer); -binder_transaction_buffer_release (proc,NULL , buffer,0 ,0 ); +binder_release_entire_buffer (proc,NULL , buffer, false);binder_alloc_free_buf (&proc->alloc, buffer);kfree (t_outdated);binder_stats_deleted (BINDER_STAT_TRANSACTION );
@@ -3759,7 +3773,7 @@ binder_free_buf(struct binder_proc *procbinder_node_inner_unlock (buf_node); }trace_binder_transaction_buffer_release (buffer); -binder_transaction_buffer_release (proc, thread, buffer,0 , is_failure); +binder_release_entire_buffer (proc, thread, buffer, is_failure);binder_alloc_free_buf (&proc->alloc, buffer); }
Greg Kroah-Hartman
maintainerPATCH 49/119 binder: fix UAF of alloc->vma in race with munmap()
In reply to Greg Kroah-HartmanFrom: Carlos Llamas <[email protected]>
commit d1d8875c8c13517f6fd1ff8d4d3e1ac366a17e07 upstream.
[ cmllamas: clean forward port from commit 015ac18be7de ("binder: fix
UAF of alloc->vma in race with munmap()") in 5.10 stable. It is needed in mainline after the revert of commit a43cfc87caaf ("android: binder:
stop saving a pointer to the VMA") as pointed out by Liam. The commit log and tags have been tweaked to reflect this. ]
In commit 720c24192404 ("ANDROID: binder: change down_write to down_read") binder assumed the mmap read lock is sufficient to protect alloc->vma inside binder_update_page_range(). This used to be accurate until commit dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap"), which now downgrades the mmap_lock after detaching the vma from the rbtree in munmap(). Then it proceeds to teardown and free the vma with only the read lock held.
This means that accesses to alloc->vma in binder_update_page_range() now will race with vm_area_free() in munmap() and can cause a UAF as shown in the following KASAN trace:
==================================================================
BUG: KASAN: use-after-free in vm_insert_page+0x7c/0x1f0 Read of size 8 at addr ffff16204ad00600 by task server/558 CPU: 3 PID: 558 Comm: server Not tainted 5.10.150-00001-gdc8dcf942daa #1 Hardware name: linux,dummy-virt (DT) Call trace: dump_backtrace+0x0/0x2a0 show_stack+0x18/0x2c dump_stack+0xf8/0x164 print_address_description.constprop.0+0x9c/0x538 kasan_report+0x120/0x200 __asan_load8+0xa0/0xc4 vm_insert_page+0x7c/0x1f0 binder_update_page_range+0x278/0x50c binder_alloc_new_buf+0x3f0/0xba0 binder_transaction+0x64c/0x3040 binder_thread_write+0x924/0x2020 binder_ioctl+0x1610/0x2e5c __arm64_sys_ioctl+0xd4/0x120 el0_svc_common.constprop.0+0xac/0x270 do_el0_svc+0x38/0xa0 el0_svc+0x1c/0x2c el0_sync_handler+0xe8/0x114 el0_sync+0x180/0x1c0 Allocated by task 559: kasan_save_stack+0x38/0x6c __kasan_kmalloc.constprop.0+0xe4/0xf0 kasan_slab_alloc+0x18/0x2c kmem_cache_alloc+0x1b0/0x2d0 vm_area_alloc+0x28/0x94 mmap_region+0x378/0x920 do_mmap+0x3f0/0x600 vm_mmap_pgoff+0x150/0x17c ksys_mmap_pgoff+0x284/0x2dc __arm64_sys_mmap+0x84/0xa4 el0_svc_common.constprop.0+0xac/0x270 do_el0_svc+0x38/0xa0 el0_svc+0x1c/0x2c el0_sync_handler+0xe8/0x114 el0_sync+0x180/0x1c0 Freed by task 560: kasan_save_stack+0x38/0x6c kasan_set_track+0x28/0x40 kasan_set_free_info+0x24/0x4c __kasan_slab_free+0x100/0x164 kasan_slab_free+0x14/0x20 kmem_cache_free+0xc4/0x34c vm_area_free+0x1c/0x2c remove_vma+0x7c/0x94 __do_munmap+0x358/0x710 __vm_munmap+0xbc/0x130 __arm64_sys_munmap+0x4c/0x64 el0_svc_common.constprop.0+0xac/0x270 do_el0_svc+0x38/0xa0 el0_svc+0x1c/0x2c el0_sync_handler+0xe8/0x114 el0_sync+0x180/0x1c0
[...]
==================================================================
To prevent the race above, revert back to taking the mmap write lock inside binder_update_page_range(). One might expect an increase of mmap lock contention. However, binder already serializes these calls via top level alloc->mutex. Also, there was no performance impact shown when running the binder benchmark tests.
--- drivers/android/binder_alloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/android/binder_alloc.c +3 -3
@@ -212,7 +212,7 @@ static int binder_update_page_range(stru mm = alloc->mm;if (mm) { -mmap_read_lock (mm); +mmap_write_lock (mm); vma = alloc->vma; }
@@ -270,7 +270,7 @@ static int binder_update_page_range(strutrace_binder_alloc_page_end (alloc, index); }if (mm) { -mmap_read_unlock (mm); +mmap_write_unlock (mm);mmput (mm); }return 0 ;
@@ -303,7 +303,7 @@ err_page_ptr_cleared: } err_no_vma:if (mm) { -mmap_read_unlock (mm); +mmap_write_unlock (mm);mmput (mm); }return vma ? -ENOMEM : -ESRCH ;
Greg Kroah-Hartman
maintainerPATCH 50/119 selftests/memfd: Fix unknown type name build failure
In reply to Greg Kroah-HartmanFrom: Hardik Garg <[email protected]>
Partially backport v6.3 commit 11f75a01448f ("selftests/memfd: add tests for MFD_NOEXEC_SEAL MFD_EXEC") to fix an unknown type name build error. In some systems, the __u64 typedef is not present due to differences in system headers, causing compilation errors like this one:
fuse_test.c:64:8: error: unknown type name '__u64'
64 | static __u64 mfd_assert_get_seals(int fd)
This header includes the __u64 typedef which increases the likelihood of successful compilation on a wider variety of systems.
--- tools/testing/selftests/memfd/fuse_test.c | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/memfd/fuse_test.c +1 -0
@@ -22,6 +22,7 @@#include <linux/falloc.h> #include <fcntl.h> #include <linux/memfd.h> +#include <linux/types.h> #include <sched.h> #include <stdio.h> #include <stdlib.h>
Greg Kroah-Hartman
maintainerPATCH 51/119 drm/amd/amdgpu: limit one queue per gang
In reply to Greg Kroah-HartmanFrom: Jack Xiao <[email protected]>
commit 5ee33d905f89c18d4b33da6e5eefdae6060502df upstream.
Limit one queue per gang in mes self test,
due to mes schq fw change.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +3 -6
@@ -1328,12 +1328,9 @@ int amdgpu_mes_self_test(struct amdgpu_dstruct amdgpu_mes_ctx_data ctx_data = {0 };struct amdgpu_ring *added_rings[AMDGPU_MES_CTX_MAX_RINGS ] = {NULL };int gang_ids[3 ] = {0 }; -int queue_types[][2 ] = { {AMDGPU_RING_TYPE_GFX , -AMDGPU_MES_CTX_MAX_GFX_RINGS }, - {AMDGPU_RING_TYPE_COMPUTE , -AMDGPU_MES_CTX_MAX_COMPUTE_RINGS }, - {AMDGPU_RING_TYPE_SDMA , -AMDGPU_MES_CTX_MAX_SDMA_RINGS } }; +int queue_types[][2 ] = { {AMDGPU_RING_TYPE_GFX ,1 }, + {AMDGPU_RING_TYPE_COMPUTE ,1 }, + {AMDGPU_RING_TYPE_SDMA ,1 } };int i, r, pasid, k =0 ; pasid =amdgpu_pasid_alloc (16 );
Greg Kroah-Hartman
maintainerPATCH 52/119 perf/x86/uncore: Correct the number of CHAs on SPR
In reply to Greg Kroah-HartmanFrom: Kan Liang <[email protected]>
commit 38776cc45eb7603df4735a0410f42cffff8e71a1 upstream.
The number of CHAs from the discovery table on some SPR variants is incorrect, because of a firmware issue. An accurate number can be read from the MSR UNC_CBO_CONFIG.
--- arch/x86/events/intel/uncore_snbep.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/x86/events/intel/uncore_snbep.c +11 -0
@@ -5822,6 +5822,7 @@ static struct intel_uncore_type spr_unco };#define UNCORE_SPR_NUM_UNCORE_TYPES 12 +#define UNCORE_SPR_CHA 0#define UNCORE_SPR_IIO 1#define UNCORE_SPR_IMC 6
@@ -6064,12 +6065,22 @@ static int uncore_type_max_boxes(structreturn max +1 ; } +#define SPR_MSR_UNC_CBO_CONFIG 0x2FFE +void spr_uncore_cpu_init (void ) { +struct intel_uncore_type *type; +u64 num_cbo; + uncore_msr_uncores =uncore_get_uncores (UNCORE_ACCESS_MSR ,UNCORE_SPR_MSR_EXTRA_UNCORES , spr_msr_uncores); + type =uncore_find_type_by_id (uncore_msr_uncores,UNCORE_SPR_CHA ); +if (type) { +rdmsrl (SPR_MSR_UNC_CBO_CONFIG , num_cbo); + type->num_boxes = num_cbo; + } spr_uncore_iio_free_running.num_boxes =uncore_type_max_boxes (uncore_msr_uncores,UNCORE_SPR_IIO ); }
Greg Kroah-Hartman
maintainerPATCH 53/119 x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms
In reply to Greg Kroah-HartmanFrom: Zhang Rui <[email protected]>
commit edc0a2b5957652f4685ef3516f519f84807087db upstream.
Traditionally, all CPUs in a system have identical numbers of SMT siblings. That changes with hybrid processors where some logical CPUs have a sibling and others have none.
Today, the CPU boot code sets the global variable smp_num_siblings when every CPU thread is brought up. The last thread to boot will overwrite it with the number of siblings of *that* thread. That last thread to boot will "win". If the thread is a Pcore, smp_num_siblings == 2. If it is an Ecore, smp_num_siblings == 1.
smp_num_siblings describes if the *system* supports SMT. It should specify the maximum number of SMT threads among all cores.
Ensure that smp_num_siblings represents the system-wide maximum number of siblings by always increasing its value. Never allow it to decrease.
On MeteorLake-P platform, this fixes a problem that the Ecore CPUs are not updated in any cpu sibling map because the system is treated as an UP system when probing Ecore CPUs.
Below shows part of the CPU topology information before and after the fix, for both Pcore and Ecore CPU (cpu0 is Pcore, cpu 12 is Ecore).
...
-/sys/devices/system/cpu/cpu0/topology/package_cpus:000fff -/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-11 +/sys/devices/system/cpu/cpu0/topology/package_cpus:3fffff +/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-21
...
-/sys/devices/system/cpu/cpu12/topology/package_cpus:001000 -/sys/devices/system/cpu/cpu12/topology/package_cpus_list:12 +/sys/devices/system/cpu/cpu12/topology/package_cpus:3fffff +/sys/devices/system/cpu/cpu12/topology/package_cpus_list:0-21
Notice that the "before" 'package_cpus_list' has only one CPU. This means that userspace tools like lscpu will see a little laptop like an 11-socket system:
-Core(s) per socket: 1 -Socket(s): 11 +Core(s) per socket: 16 +Socket(s): 1
This is also expected to make the scheduler do rather wonky things too.
[ dhansen: remove CPUID detail from changelog, add end user effects ]
--- arch/x86/kernel/cpu/topology.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/topology.c +3 -2
@@ -79,7 +79,7 @@ int detect_extended_topology_early(struc* initial apic id, which also represents 32-bit extended x2apic id. */ c->initial_apicid = edx; - smp_num_siblings =LEVEL_MAX_SIBLINGS (ebx); + smp_num_siblings =max_t (int, smp_num_siblings,LEVEL_MAX_SIBLINGS (ebx));#endif return 0 ; }
@@ -109,7 +109,8 @@ int detect_extended_topology(struct cpui*/ cpuid_count (leaf,SMT_LEVEL , &eax, &ebx, &ecx, &edx); c->initial_apicid = edx; - core_level_siblings = smp_num_siblings =LEVEL_MAX_SIBLINGS (ebx); + core_level_siblings =LEVEL_MAX_SIBLINGS (ebx); + smp_num_siblings =max_t (int, smp_num_siblings,LEVEL_MAX_SIBLINGS (ebx)); core_plus_mask_width = ht_mask_width =BITS_SHIFT_NEXT_LEVEL (eax); die_level_siblings =LEVEL_MAX_SIBLINGS (ebx); pkg_mask_width = die_plus_mask_width =BITS_SHIFT_NEXT_LEVEL (eax);
Greg Kroah-Hartman
maintainerPATCH 54/119 irqchip/mips-gic: Dont touch vl_map if a local interrupt is not routable
In reply to Greg Kroah-HartmanFrom: Jiaxun Yang <[email protected]>
commit 2c6c9c049510163090b979ea5f92a68ae8d93c45 upstream.
When a GIC local interrupt is not routable, it's vl_map will be used to control some internal states for core (providing IPTI, IPPCI, IPFDC input signal for core). Overriding it will interfere core's intetrupt controller.
Do not touch vl_map if a local interrupt is not routable, we are not going to remap it.
Before dd098a0e0319 (" irqchip/mips-gic: Get rid of the reliance on irq_cpu_online()"), if a local interrupt is not routable, then it won't be requested from GIC Local domain, and thus gic_all_vpes_irq_cpu_online won't be called for that particular interrupt.
--- drivers/irqchip/irq-mips-gic.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/irqchip/irq-mips-gic.c +2 -0
@@ -400,6 +400,8 @@ static void gic_all_vpes_irq_cpu_online(unsigned int intr = local_intrs[i];struct gic_all_vpes_chip_data *cd; +if (!gic_local_irq_is_routable (intr)) +continue ; cd = &gic_all_vpes_chip_data[intr];write_gic_vl_map (mips_gic_vx_map_reg (intr), cd->map);if (cd->mask)
Greg Kroah-Hartman
maintainerPATCH 55/119 irqchip/mips-gic: Use raw spinlock for gic_lock
In reply to Greg Kroah-HartmanFrom: Jiaxun Yang <[email protected]>
commit 3d6a0e4197c04599d75d85a608c8bb16a630a38c upstream.
Since we may hold gic_lock in hardirq context, use raw spinlock makes more sense given that it is for low-level interrupt handling routine and the critical section is small.
Fixes BUG:
[ 0.426106] =============================
[ 0.426257] [ BUG: Invalid wait context ]
[ 0.426422] 6.3.0-rc7-next-20230421-dirty #54 Not tainted
[ 0.426638] -----------------------------
[ 0.426766] swapper/0/1 is trying to lock:
[ 0.426954] ffffffff8104e7b8 (gic_lock){....}-{3:3}, at: gic_set_type+0x30/08--- drivers/irqchip/irq-mips-gic.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
drivers/irqchip/irq-mips-gic.c +15 -15
@@ -50,7 +50,7 @@ void __iomem *mips_gic_base; static DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks); -static DEFINE_SPINLOCK (gic_lock); +static DEFINE_RAW_SPINLOCK (gic_lock);static struct irq_domain *gic_irq_domain;static int gic_shared_intrs;static unsigned int gic_cpu_pin;
@@ -211,7 +211,7 @@ static int gic_set_type(struct irq_data irq =GIC_HWIRQ_TO_SHARED (d->hwirq); -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);switch (type &IRQ_TYPE_SENSE_MASK ) {case IRQ_TYPE_EDGE_FALLING : pol =GIC_POL_FALLING_EDGE ;
@@ -251,7 +251,7 @@ static int gic_set_type(struct irq_dataelse irq_set_chip_handler_name_locked (d, &gic_level_irq_controller, handle_level_irq,NULL ); -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags);return 0 ; }
@@ -269,7 +269,7 @@ static int gic_set_affinity(struct irq_dreturn -EINVAL ;/* Assumption : cpumask refers to a single CPU */ -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);/* Re-route this IRQ */ write_gic_map_vp (irq,BIT (mips_cm_vp_id (cpu)));
@@ -280,7 +280,7 @@ static int gic_set_affinity(struct irq_dset_bit (irq,per_cpu_ptr (pcpu_masks, cpu));irq_data_update_effective_affinity (d,cpumask_of (cpu)); -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags);return IRQ_SET_MASK_OK ; }
@@ -358,12 +358,12 @@ static void gic_mask_local_irq_all_vpes( cd =irq_data_get_irq_chip_data (d); cd->mask = false; -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);for_each_online_cpu (cpu) {write_gic_vl_other (mips_cm_vp_id (cpu));write_gic_vo_rmask (BIT (intr)); } -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags); }static void gic_unmask_local_irq_all_vpes (struct irq_data *d)
@@ -376,12 +376,12 @@ static void gic_unmask_local_irq_all_vpe cd =irq_data_get_irq_chip_data (d); cd->mask = true; -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);for_each_online_cpu (cpu) {write_gic_vl_other (mips_cm_vp_id (cpu));write_gic_vo_smask (BIT (intr)); } -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags); }static void gic_all_vpes_irq_cpu_online (void )
@@ -394,7 +394,7 @@ static void gic_all_vpes_irq_cpu_online(unsigned long flags;int i; -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);for (i =0 ; i <ARRAY_SIZE (local_intrs); i++) {unsigned int intr = local_intrs[i];
@@ -408,7 +408,7 @@ static void gic_all_vpes_irq_cpu_online(write_gic_vl_smask (BIT (intr)); } -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags); }static struct irq_chip gic_all_vpes_local_irq_controller = {
@@ -438,11 +438,11 @@ static int gic_shared_irq_domain_map(str data =irq_get_irq_data (virq); -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);write_gic_map_pin (intr,GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin);write_gic_map_vp (intr,BIT (mips_cm_vp_id (cpu)));irq_data_update_effective_affinity (data,cpumask_of (cpu)); -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags);return 0 ; }
@@ -537,12 +537,12 @@ static int gic_irq_domain_map(struct irqif (!gic_local_irq_is_routable (intr))return -EPERM ; -spin_lock_irqsave (&gic_lock, flags); +raw_spin_lock_irqsave (&gic_lock, flags);for_each_online_cpu (cpu) {write_gic_vl_other (mips_cm_vp_id (cpu));write_gic_vo_map (mips_gic_vx_map_reg (intr), map); } -spin_unlock_irqrestore (&gic_lock, flags); +raw_spin_unlock_irqrestore (&gic_lock, flags);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 56/119 debugobjects: Dont wake up kswapd from fill_pool()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
commit eb799279fb1f9c63c520fe8c1c41cb9154252db6 upstream.
syzbot is reporting a lockdep warning in fill_pool() because the allocation from debugobjects is using GFP_ATOMIC, which is (__GFP_HIGH | __GFP_KSWAPD_RECLAIM) and therefore tries to wake up kswapd, which acquires kswapd_wait::lock.
Since fill_pool() might be called with arbitrary locks held, fill_pool() should not assume that acquiring kswapd_wait::lock is safe.
Use __GFP_HIGH instead and remove __GFP_NORETRY as it is pointless for !__GFP_DIRECT_RECLAIM allocation.
--- lib/debugobjects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/debugobjects.c +1 -1
@@ -126,7 +126,7 @@ static const char *obj_states[ODEBUG_STAstatic void fill_pool (void ) { -gfp_t gfp =GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; +gfp_t gfp = __GFP_HIGH | __GFP_NOWARN;struct debug_obj *obj;unsigned long flags;
Greg Kroah-Hartman
maintainerPATCH 57/119 fbdev: udlfb: Fix endpoint check
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit ed9de4ed39875706607fb08118a58344ae6c5f42 upstream.
The syzbot fuzzer detected a problem in the udlfb driver, caused by an endpoint not having the expected type:
usb 1-1: Read EDID byte 0 failed: -71
usb 1-1: Unable to get valid EDID from device/display
------------[ cut here ]------------ usb 1-1: BOGUS urb xfer, pipe 3 != type 1 WARNING: CPU: 0 PID: 9 at drivers/usb/core/urb.c:504 usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 Modules linked in: CPU: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.4.0-rc1-syzkaller-00016-ga4422ff22142 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/28/2023 Workqueue: usb_hub_wq hub_event RIP: 0010:usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 ... Call Trace: <TASK> dlfb_submit_urb+0x92/0x180 drivers/video/fbdev/udlfb.c:1980 dlfb_set_video_mode+0x21f0/0x2950 drivers/video/fbdev/udlfb.c:315 dlfb_ops_set_par+0x2a7/0x8d0 drivers/video/fbdev/udlfb.c:1111 dlfb_usb_probe+0x149a/0x2710 drivers/video/fbdev/udlfb.c:1743
The current approach for this issue failed to catch the problem because it only checks for the existence of a bulk-OUT endpoint; it doesn't check whether this endpoint is the one that the driver will actually use.
We can fix the problem by instead checking that the endpoint used by the driver does exist and is bulk-OUT.
--- drivers/video/fbdev/udlfb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/video/fbdev/udlfb.c +8 -5
@@ -27,6 +27,8 @@#include <video/udlfb.h> #include "edid.h" +#define OUT_EP_NUM 1/* The endpoint number we will use */ +static const struct fb_fix_screeninfo dlfb_fix = { .id ="udlfb" , .type =FB_TYPE_PACKED_PIXELS ,
@@ -1652,7 +1654,7 @@ static int dlfb_usb_probe(struct usb_intstruct fb_info *info;int retval;struct usb_device *usbdev =interface_to_usbdev (intf); -struct usb_endpoint_descriptor *out; +static u8 out_ep[] = {OUT_EP_NUM +USB_DIR_OUT ,0 };/* usb initialization */ dlfb =kzalloc (sizeof (*dlfb),GFP_KERNEL );
@@ -1666,9 +1668,9 @@ static int dlfb_usb_probe(struct usb_int dlfb->udev =usb_get_dev (usbdev);usb_set_intfdata (intf, dlfb); - retval =usb_find_common_endpoints (intf->cur_altsetting,NULL , &out,NULL ,NULL ); -if (retval) { -dev_err (&intf->dev,"Device should have at lease 1 bulk endpoint!\n" ); +if (!usb_check_bulk_endpoints (intf, out_ep)) { +dev_err (&intf->dev,"Invalid DisplayLink device!\n" ); + retval = -EINVAL ; goto error; }
@@ -1927,7 +1929,8 @@ retry: }/* urb->transfer_buffer_length set to actual before submit */ -usb_fill_bulk_urb (urb, dlfb->udev,usb_sndbulkpipe (dlfb->udev,1 ), +usb_fill_bulk_urb (urb, dlfb->udev, +usb_sndbulkpipe (dlfb->udev,OUT_EP_NUM ), buf, size, dlfb_urb_completion, unode); urb->transfer_flags |=URB_NO_TRANSFER_DMA_MAP ;
Greg Kroah-Hartman
maintainerPATCH 58/119 net: fix stack overflow when LRO is disabled for virtual interfaces
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
commit ae9b15fbe63447bc1d3bba3769f409d17ca6fdf6 upstream.
When the virtual interface's feature is updated, it synchronizes the updated feature for its own lower interface.
This propagation logic should be worked as the iteration, not recursively. But it works recursively due to the netdev notification unexpectedly. This problem occurs when it disables LRO only for the team and bonding interface type.
team0
|
+------+------+-----+-----+
| | | | |
team1 team2 team3 ... team200If team0's LRO feature is updated, it generates the NETDEV_FEAT_CHANGE event to its own lower interfaces(team1 ~ team200).
It is worked by netdev_sync_lower_features().
So, the NETDEV_FEAT_CHANGE notification logic of each lower interface work iteratively.
But generated NETDEV_FEAT_CHANGE event is also sent to the upper interface too.
upper interface(team0) generates the NETDEV_FEAT_CHANGE event for its own lower interfaces again.
lower and upper interfaces receive this event and generate this event again and again.
So, the stack overflow occurs.
But it is not the infinite loop issue.
Because the netdev_sync_lower_features() updates features before generating the NETDEV_FEAT_CHANGE event.
Already synchronized lower interfaces skip notification logic. So, it is just the problem that iteration logic is changed to the recursive unexpectedly due to the notification mechanism.
Reproducer:
ip link add team0 type team
ethtool -K team0 lro on
for i in {1..200}
do
ip link add team$i master team0 type team
ethtool -K team$i lro on
done
ethtool -K team0 lro off
In order to fix it, the notifier_ctx member of bonding/team is introduced.
--- drivers/net/bonding/bond_main.c | 8 +++++++- drivers/net/team/team.c | 7 ++++++- include/linux/if_team.h | 1 + include/net/bonding.h | 1 + 4 files changed, 15 insertions(+), 2 deletions(-)
drivers/net/bonding/bond_main.c +7 -1
@@ -3921,7 +3921,11 @@ static int bond_slave_netdev_event(unsigunblock_netpoll_tx ();break ;case NETDEV_FEAT_CHANGE : -bond_compute_features (bond); +if (!bond->notifier_ctx) { + bond->notifier_ctx = true; +bond_compute_features (bond); + bond->notifier_ctx = false; + }break ;case NETDEV_RESEND_IGMP :/* Propagate to master device */
@@ -6284,6 +6288,8 @@ static int bond_init(struct net_device *if (!bond->wq)return -ENOMEM ; + bond->notifier_ctx = false; +spin_lock_init (&bond->stats_lock);netdev_lockdep_set_classes (bond_dev);
drivers/net/team/team.c +6 -1
@@ -1629,6 +1629,7 @@ static int team_init(struct net_device * team->dev = dev;team_set_no_mode (team); + team->notifier_ctx = false; team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats);if (!team->pcpu_stats)
@@ -3022,7 +3023,11 @@ static int team_device_event(struct notiteam_del_slave (port->team->dev, dev);break ;case NETDEV_FEAT_CHANGE : -team_compute_features (port->team); +if (!port->team->notifier_ctx) { + port->team->notifier_ctx = true; +team_compute_features (port->team); + port->team->notifier_ctx = false; + }break ;case NETDEV_PRECHANGEMTU :/* Forbid to change mtu of underlaying device */
include/linux/if_team.h +1 -0
@@ -208,6 +208,7 @@ struct team {bool queue_override_enabled;struct list_head *qom_lists;/* array of queue override mapping lists */ bool port_mtu_change_allowed; +bool notifier_ctx;struct {unsigned int count;unsigned int interval;/* in ms */
include/net/bonding.h +1 -0
@@ -223,6 +223,7 @@ struct bonding {struct bond_up_slave __rcu *usable_slaves;struct bond_up_slave __rcu *all_slaves;bool force_primary; +bool notifier_ctx;s32 slave_cnt;/* never change this value outside the attach/detach wrappers */ int (*recv_probe)(const struct sk_buff *,struct bonding *,struct slave *);
Greg Kroah-Hartman
maintainerPATCH 59/119 udplite: Fix NULL pointer dereference in __sk_mem_raise_allocated().
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
commit ad42a35bdfc6d3c0fc4cb4027d7b2757ce665665 upstream.
syzbot reported [0] a null-ptr-deref in sk_get_rmem0() while using IPPROTO_UDPLITE (0x88):
14:25:52 executing program 1:
r0 = socket$inet6(0xa, 0x80002, 0x88)
We had a similar report [1] for probably sk_memory_allocated_add() in __sk_mem_raise_allocated(), and commit c915fe13cbaa ("udplite: fix NULL pointer dereference") fixed it by setting .memory_allocated for udplite_prot and udplitev6_prot.
To fix the variant, we need to set either .sysctl_wmem_offset or .sysctl_rmem.
Now UDP and UDPLITE share the same value for .memory_allocated, so we use the same .sysctl_wmem_offset for UDP and UDPLITE.
[0]:
general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 PID: 6829 Comm: syz-executor.1 Not tainted 6.4.0-rc2-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/28/2023 RIP: 0010:sk_get_rmem0 include/net/sock.h:2907 [inline] RIP: 0010:__sk_mem_raise_allocated+0x806/0x17a0 net/core/sock.c:3006 Code: c1 ea 03 80 3c 02 00 0f 85 23 0f 00 00 48 8b 44 24 08 48 8b 98 38 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 da 48 c1 ea 03 <0f> b6 14 02 48 89 d8 83 e0 07 83 c0 03 38 d0 0f 8d 6f 0a 00 00 8b RSP: 0018:ffffc90005d7f450 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc90004d92000 RDX: 0000000000000000 RSI: ffffffff88066482 RDI: ffffffff8e2ccbb8 RBP: ffff8880173f7000 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000030000 R13: 0000000000000001 R14: 0000000000000340 R15: 0000000000000001 FS: 0000000000000000(0000) GS:ffff8880b9800000(0063) knlGS:00000000f7f1cb40 CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 CR2: 000000002e82f000 CR3: 0000000034ff0000 CR4: 00000000003506f0 Call Trace: <TASK> __sk_mem_schedule+0x6c/0xe0 net/core/sock.c:3077 udp_rmem_schedule net/ipv4/udp.c:1539 [inline] __udp_enqueue_schedule_skb+0x776/0xb30 net/ipv4/udp.c:1581 __udpv6_queue_rcv_skb net/ipv6/udp.c:666 [inline] udpv6_queue_rcv_one_skb+0xc39/0x16c0 net/ipv6/udp.c:775 udpv6_queue_rcv_skb+0x194/0xa10 net/ipv6/udp.c:793 __udp6_lib_mcast_deliver net/ipv6/udp.c:906 [inline] __udp6_lib_rcv+0x1bda/0x2bd0 net/ipv6/udp.c:1013 ip6_protocol_deliver_rcu+0x2e7/0x1250 net/ipv6/ip6_input.c:437 ip6_input_finish+0x150/0x2f0 net/ipv6/ip6_input.c:482 NF_HOOK include/linux/netfilter.h:303 [inline] NF_HOOK include/linux/netfilter.h:297 [inline] ip6_input+0xa0/0xd0 net/ipv6/ip6_input.c:491 ip6_mc_input+0x40b/0xf50 net/ipv6/ip6_input.c:585 dst_input include/net/dst.h:468 [inline] ip6_rcv_finish net/ipv6/ip6_input.c:79 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] NF_HOOK include/linux/netfilter.h:297 [inline] ipv6_rcv+0x250/0x380 net/ipv6/ip6_input.c:309 __netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5491 __netif_receive_skb+0x1f/0x1c0 net/core/dev.c:5605 netif_receive_skb_internal net/core/dev.c:5691 [inline] netif_receive_skb+0x133/0x7a0 net/core/dev.c:5750 tun_rx_batched+0x4b3/0x7a0 drivers/net/tun.c:1553 tun_get_user+0x2452/0x39c0 drivers/net/tun.c:1989 tun_chr_write_iter+0xdf/0x200 drivers/net/tun.c:2035 call_write_iter include/linux/fs.h:1868 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x945/0xd50 fs/read_write.c:584 ksys_write+0x12b/0x250 fs/read_write.c:637 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0x65/0xf0 arch/x86/entry/common.c:178 do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203 entry_SYSENTER_compat_after_hwframe+0x70/0x82 RIP: 0023:0xf7f21579 Code: b8 01 10 06 03 74 b4 01 10 07 03 74 b0 01 10 08 03 74 d8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 8d b4 26 00 00 00 00 8d b4 26 00 00 00 00 RSP: 002b:00000000f7f1c590 EFLAGS: 00000282 ORIG_RAX: 0000000000000004 RAX: ffffffffffffffda RBX: 00000000000000c8 RCX: 0000000020000040 RDX: 0000000000000083 RSI: 00000000f734e000 RDI: 0000000000000000 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000296 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK> Modules linked in:
--- net/ipv4/udplite.c | 2 ++ net/ipv6/udplite.c | 2 ++ 2 files changed, 4 insertions(+)
net/ipv4/udplite.c +2 -0
@@ -64,6 +64,8 @@ struct proto udplite_prot = { .per_cpu_fw_alloc = &udp_memory_per_cpu_fw_alloc, .sysctl_mem = sysctl_udp_mem, + .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), .obj_size = sizeof(struct udp_sock), .h.udp_table = &udplite_table, };
net/ipv6/udplite.c +2 -0
@@ -60,6 +60,8 @@ struct proto udplitev6_prot = { .per_cpu_fw_alloc = &udp_memory_per_cpu_fw_alloc, .sysctl_mem = sysctl_udp_mem, + .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), .obj_size = sizeof(struct udp6_sock), .h.udp_table = &udplite_table, };
Greg Kroah-Hartman
maintainerPATCH 60/119 USB: core: Add routines for endpoint checks in old drivers
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit 13890626501ffda22b18213ddaf7930473da5792 upstream.
Many of the older USB drivers in the Linux USB stack were written based simply on a vendor's device specification. They use the endpoint information in the spec and assume these endpoints will always be present, with the properties listed, in any device matching the given vendor and product IDs.
While that may have been true back then, with spoofing and fuzzing it is not true any more. More and more we are finding that those old drivers need to perform at least a minimum of checking before they try to use any endpoint other than ep0.
To make this checking as simple as possible, we now add a couple of utility routines to the USB core. usb_check_bulk_endpoints() and usb_check_int_endpoints() take an interface pointer together with a list of endpoint addresses (numbers and directions). They check that the interface's current alternate setting includes endpoints with those addresses and that each of these endpoints has the right type:
bulk or interrupt, respectively.
Although we already have usb_find_common_endpoints() and related routines meant for a similar purpose, they are not well suited for this kind of checking. Those routines find endpoints of various kinds, but only one (either the first or the last) of each kind, and they don't verify that the endpoints' addresses agree with what the caller expects.
In theory the new routines could be more general: They could take a particular altsetting as their argument instead of always using the interface's current altsetting. In practice I think this won't matter too much; multiple altsettings tend to be used for transferring media (audio or visual) over isochronous endpoints, not bulk or interrupt. Drivers for such devices will generally require more sophisticated checking than these simplistic routines provide.
--- drivers/usb/core/usb.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb.h | 5 +++ 2 files changed, 81 insertions(+)
drivers/usb/core/usb.c +76 -0
@@ -207,6 +207,82 @@ int usb_find_common_endpoints_reverse(stEXPORT_SYMBOL_GPL (usb_find_common_endpoints_reverse);/** +* usb_find_endpoint() - Given an endpoint address, search for the endpoint's +* usb_host_endpoint structure in an interface's current altsetting. +* @intf: the interface whose current altsetting should be searched +* @ep_addr: the endpoint address (number and direction) to find +* +* Search the altsetting's list of endpoints for one with the specified address. +* +* Return: Pointer to the usb_host_endpoint if found, %NULL otherwise. +*/ +static const struct usb_host_endpoint *usb_find_endpoint ( +const struct usb_interface *intf,unsigned int ep_addr) +{ +int n; +const struct usb_host_endpoint *ep; + + n = intf->cur_altsetting->desc.bNumEndpoints; + ep = intf->cur_altsetting->endpoint; +for (; n >0 ; (--n, ++ep)) { +if (ep->desc.bEndpointAddress == ep_addr) +return ep; + } +return NULL ; +} + +/** +* usb_check_bulk_endpoints - Check whether an interface's current altsetting +* contains a set of bulk endpoints with the given addresses. +* @intf: the interface whose current altsetting should be searched +* @ep_addrs: 0-terminated array of the endpoint addresses (number and +* direction) to look for +* +* Search for endpoints with the specified addresses and check their types. +* +* Return: %true if all the endpoints are found and are bulk, %false otherwise. +*/ +bool usb_check_bulk_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs) +{ +const struct usb_host_endpoint *ep; + +for (; *ep_addrs; ++ep_addrs) { + ep =usb_find_endpoint (intf, *ep_addrs); +if (!ep || !usb_endpoint_xfer_bulk (&ep->desc)) +return false; + } +return true; +} +EXPORT_SYMBOL_GPL (usb_check_bulk_endpoints); + +/** +* usb_check_int_endpoints - Check whether an interface's current altsetting +* contains a set of interrupt endpoints with the given addresses. +* @intf: the interface whose current altsetting should be searched +* @ep_addrs: 0-terminated array of the endpoint addresses (number and +* direction) to look for +* +* Search for endpoints with the specified addresses and check their types. +* +* Return: %true if all the endpoints are found and are interrupt, +* %false otherwise. +*/ +bool usb_check_int_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs) +{ +const struct usb_host_endpoint *ep; + +for (; *ep_addrs; ++ep_addrs) { + ep =usb_find_endpoint (intf, *ep_addrs); +if (!ep || !usb_endpoint_xfer_int (&ep->desc)) +return false; + } +return true; +} +EXPORT_SYMBOL_GPL (usb_check_int_endpoints); + +/** * usb_find_alt_setting() - Given a configuration, find the alternate setting * for the given interface. * @config: the configuration to search (not necessarily the current config).
include/linux/usb.h +5 -0
@@ -279,6 +279,11 @@ void usb_put_intf(struct usb_interface *#define USB_MAXINTERFACES 32#define USB_MAXIADS (USB_MAXINTERFACES/2) +bool usb_check_bulk_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs); +bool usb_check_int_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs); +/* * USB Resume Timer: Every Host controller driver should drive the resume * signalling on the bus for the amount of time defined by this macro.
Greg Kroah-Hartman
maintainerPATCH 61/119 USB: sisusbvga: Add endpoint checks
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit df05a9b05e466a46725564528b277d0c570d0104 upstream.
The syzbot fuzzer was able to provoke a WARNING from the sisusbvga driver:
------------[ cut here ]------------ usb 1-1: BOGUS urb xfer, pipe 3 != type 1 WARNING: CPU: 1 PID: 26 at drivers/usb/core/urb.c:504 usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 Modules linked in: CPU: 1 PID: 26 Comm: kworker/1:1 Not tainted 6.2.0-rc5-syzkaller-00199-g5af6ce704936 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/12/2023 Workqueue: usb_hub_wq hub_event RIP: 0010:usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 Code: 7c 24 18 e8 6c 50 80 fb 48 8b 7c 24 18 e8 62 1a 01 ff 41 89 d8 44 89 e1 4c 89 ea 48 89 c6 48 c7 c7 60 b1 fa 8a e8 84 b0 be 03 <0f> 0b e9 58 f8 ff ff e8 3e 50 80 fb 48 81 c5 c0 05 00 00 e9 84 f7 RSP: 0018:ffffc90000a1ed18 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000 RDX: ffff888012783a80 RSI: ffffffff816680ec RDI: fffff52000143d95 RBP: ffff888079020000 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000080000000 R11: 0000000000000000 R12: 0000000000000003 R13: ffff888017d33370 R14: 0000000000000003 R15: ffff888021213600 FS: 0000000000000000(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00005592753a60b0 CR3: 0000000022899000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> sisusb_bulkout_msg drivers/usb/misc/sisusbvga/sisusbvga.c:224 [inline] sisusb_send_bulk_msg.constprop.0+0x904/0x1230 drivers/usb/misc/sisusbvga/sisusbvga.c:379 sisusb_send_bridge_packet drivers/usb/misc/sisusbvga/sisusbvga.c:567 [inline] sisusb_do_init_gfxdevice drivers/usb/misc/sisusbvga/sisusbvga.c:2077 [inline] sisusb_init_gfxdevice+0x87b/0x4000 drivers/usb/misc/sisusbvga/sisusbvga.c:2177 sisusb_probe+0x9cd/0xbe2 drivers/usb/misc/sisusbvga/sisusbvga.c:2869
...
The problem was caused by the fact that the driver does not check whether the endpoints it uses are actually present and have the appropriate types. This can be fixed by adding a simple check of the endpoints.
--- drivers/usb/misc/sisusbvga/sisusb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/usb/misc/sisusbvga/sisusb.c +14 -0
@@ -3014,6 +3014,20 @@ static int sisusb_probe(struct usb_interstruct usb_device *dev =interface_to_usbdev (intf);struct sisusb_usb_data *sisusb;int retval =0 , i; +static const u8 ep_addresses[] = { +SISUSB_EP_GFX_IN |USB_DIR_IN , +SISUSB_EP_GFX_OUT |USB_DIR_OUT , +SISUSB_EP_GFX_BULK_OUT |USB_DIR_OUT , +SISUSB_EP_GFX_LBULK_OUT |USB_DIR_OUT , +SISUSB_EP_BRIDGE_IN |USB_DIR_IN , +SISUSB_EP_BRIDGE_OUT |USB_DIR_OUT , +0 }; + +/* Are the expected endpoints present? */ +if (!usb_check_bulk_endpoints (intf, ep_addresses)) { +dev_err (&intf->dev,"Invalid USB2VGA device\n" ); +return -EINVAL ; + }dev_info (&dev->dev,"USB2VGA dongle found at address %d\n" , dev->devnum);
Greg Kroah-Hartman
maintainerPATCH 62/119 media: radio-shark: Add endpoint checks
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit 76e31045ba030e94e72105c01b2e98f543d175ac upstream.
The syzbot fuzzer was able to provoke a WARNING from the radio-shark2 driver:
------------[ cut here ]------------ usb 1-1: BOGUS urb xfer, pipe 1 != type 3 WARNING: CPU: 0 PID: 3271 at drivers/usb/core/urb.c:504 usb_submit_urb+0xed2/0x1880 drivers/usb/core/urb.c:504 Modules linked in: CPU: 0 PID: 3271 Comm: kworker/0:3 Not tainted 6.1.0-rc4-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Workqueue: usb_hub_wq hub_event RIP: 0010:usb_submit_urb+0xed2/0x1880 drivers/usb/core/urb.c:504 Code: 7c 24 18 e8 00 36 ea fb 48 8b 7c 24 18 e8 36 1c 02 ff 41 89 d8 44 89 e1 4c 89 ea 48 89 c6 48 c7 c7 a0 b6 90 8a e8 9a 29 b8 03 <0f> 0b e9 58 f8 ff ff e8 d2 35 ea fb 48 81 c5 c0 05 00 00 e9 84 f7 RSP: 0018:ffffc90003876dd0 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000000000 RDX: ffff8880750b0040 RSI: ffffffff816152b8 RDI: fffff5200070edac RBP: ffff8880172d81e0 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000080000000 R11: 0000000000000000 R12: 0000000000000001 R13: ffff8880285c5040 R14: 0000000000000002 R15: ffff888017158200 FS: 0000000000000000(0000) GS:ffff8880b9a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffe03235b90 CR3: 000000000bc8e000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> usb_start_wait_urb+0x101/0x4b0 drivers/usb/core/message.c:58 usb_bulk_msg+0x226/0x550 drivers/usb/core/message.c:387 shark_write_reg+0x1ff/0x2e0 drivers/media/radio/radio-shark2.c:88
...
The problem was caused by the fact that the driver does not check whether the endpoints it uses are actually present and have the appropriate types. This can be fixed by adding a simple check of these endpoints (and similarly for the radio-shark driver).
--- drivers/media/radio/radio-shark.c | 10 ++++++++++ drivers/media/radio/radio-shark2.c | 10 ++++++++++ 2 files changed, 20 insertions(+)
drivers/media/radio/radio-shark.c +10 -0
@@ -316,6 +316,16 @@ static int usb_shark_probe(struct usb_in {struct shark_device *shark;int retval = -ENOMEM ; +static const u8 ep_addresses[] = { +SHARK_IN_EP |USB_DIR_IN , +SHARK_OUT_EP |USB_DIR_OUT , +0 }; + +/* Are the expected endpoints present? */ +if (!usb_check_int_endpoints (intf, ep_addresses)) { +dev_err (&intf->dev,"Invalid radioSHARK device\n" ); +return -EINVAL ; + } shark =kzalloc (sizeof (struct shark_device ),GFP_KERNEL );if (!shark)
drivers/media/radio/radio-shark2.c +10 -0
@@ -282,6 +282,16 @@ static int usb_shark_probe(struct usb_in {struct shark_device *shark;int retval = -ENOMEM ; +static const u8 ep_addresses[] = { +SHARK_IN_EP |USB_DIR_IN , +SHARK_OUT_EP |USB_DIR_OUT , +0 }; + +/* Are the expected endpoints present? */ +if (!usb_check_int_endpoints (intf, ep_addresses)) { +dev_err (&intf->dev,"Invalid radioSHARK2 device\n" ); +return -EINVAL ; + } shark =kzalloc (sizeof (struct shark_device ),GFP_KERNEL );if (!shark)
Greg Kroah-Hartman
maintainerPATCH 63/119 ASoC: lpass: Fix for KASAN use_after_free out of bounds
In reply to Greg Kroah-HartmanFrom: Ravulapati Vishnu Vardhan Rao <[email protected]>
commit 75e5fab7db0cecb6e16b22c34608f0b40a4c7cd1 upstream.
When we run syzkaller we get below Out of Bounds error.
"KASAN: slab-out-of-bounds Read in regcache_flat_read"
Below is the backtrace of the issue:
BUG: KASAN: slab-out-of-bounds in regcache_flat_read+0x10c/0x110 Read of size 4 at addr ffffff8088fbf714 by task syz-executor.4/14144 CPU: 6 PID: 14144 Comm: syz-executor.4 Tainted: G W Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform (rev5+) (DT) Call trace: dump_backtrace+0x0/0x4ec show_stack+0x34/0x50 dump_stack_lvl+0xdc/0x11c print_address_description+0x30/0x2d8 kasan_report+0x178/0x1e4 __asan_report_load4_noabort+0x44/0x50 regcache_flat_read+0x10c/0x110 regcache_read+0xf8/0x5a0 _regmap_read+0x45c/0x86c _regmap_update_bits+0x128/0x290 regmap_update_bits_base+0xc0/0x15c snd_soc_component_update_bits+0xa8/0x22c snd_soc_component_write_field+0x68/0xd4 tx_macro_put_dec_enum+0x1d0/0x268 snd_ctl_elem_write+0x288/0x474
By Error checking and checking valid values issue gets rectifies.
--- sound/soc/codecs/lpass-tx-macro.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/soc/codecs/lpass-tx-macro.c +5 -0
@@ -745,6 +745,8 @@ static int tx_macro_put_dec_enum(structstruct tx_macro *tx =snd_soc_component_get_drvdata (component); val = ucontrol->value.enumerated.item[0 ]; +if (val >= e->items) +return -EINVAL ;switch (e->reg) {case CDC_TX_INP_MUX_ADC_MUX0_CFG0 :
@@ -771,6 +773,9 @@ static int tx_macro_put_dec_enum(structcase CDC_TX_INP_MUX_ADC_MUX7_CFG0 : mic_sel_reg =CDC_TX7_TX_PATH_CFG0 ;break ; +default : +dev_err (component->dev,"Error in configuration!!\n" ); +return -EINVAL ; }if (val !=0 ) {
Greg Kroah-Hartman
maintainerPATCH 64/119 net: fix skb leak in __skb_tstamp_tx()
In reply to Greg Kroah-HartmanFrom: Pratyush Yadav <[email protected]>
commit 8a02fb71d7192ff1a9a47c9d937624966c6e09af upstream.
Commit 50749f2dd685 ("tcp/udp: Fix memleaks of sk and zerocopy skbs with TX timestamp.") added a call to skb_orphan_frags_rx() to fix leaks with zerocopy skbs. But it ended up adding a leak of its own. When skb_orphan_frags_rx() fails, the function just returns, leaking the skb it just cloned. Free it before returning.
This bug was discovered and resolved using Coverity Static Analysis Security Testing (SAST) by Synopsys, Inc.
--- net/core/skbuff.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/core/skbuff.c +3 -1
@@ -4983,8 +4983,10 @@ void __skb_tstamp_tx(struct sk_buff *ori }else { skb =skb_clone (orig_skb,GFP_ATOMIC ); -if (skb_orphan_frags_rx (skb,GFP_ATOMIC )) +if (skb_orphan_frags_rx (skb,GFP_ATOMIC )) { +kfree_skb (skb);return ; + } }if (!skb)return ;
Greg Kroah-Hartman
maintainerPATCH 65/119 drm: fix drmm_mutex_init()
In reply to Greg Kroah-HartmanFrom: Matthew Auld <[email protected]>
commit c21f11d182c2180d8b90eaff84f574cfa845b250 upstream.
In mutex_init() lockdep identifies a lock by defining a special static key for each lock class. However if we wrap the macro in a function, like in drmm_mutex_init(), we end up generating:
int drmm_mutex_init(struct drm_device *dev, struct mutex *lock)
{
static struct lock_class_key __key;
__mutex_init((lock), "lock", &__key);
....
}The static __key here is what lockdep uses to identify the lock class, however since this is just a normal function the key here will be created once, where all callers then use the same key. In effect the mutex->depmap.key will be the same pointer for different drmm_mutex_init() callers. This then results in impossible lockdep splats since lockdep thinks completely unrelated locks are the same lock class.
To fix this turn drmm_mutex_init() into a macro such that it generates a different "static struct lock_class_key __key" for each invocation, which looks to be inline with what mutex_init() wants.
v2:
- Revamp the commit message with clearer explanation of the issue.
- Rather export __drmm_mutex_release() than static inline.
--- drivers/gpu/drm/drm_managed.c | 22 ++-------------------- include/drm/drm_managed.h | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 21 deletions(-)
drivers/gpu/drm/drm_managed.c +2 -20
@@ -264,28 +264,10 @@ void drmm_kfree(struct drm_device *dev, }EXPORT_SYMBOL (drmm_kfree); -static void drmm_mutex_release (struct drm_device *dev,void *res) +void __drmm_mutex_release (struct drm_device *dev,void *res) {struct mutex *lock = res;mutex_destroy (lock); } - -/** -* drmm_mutex_init - &drm_device-managed mutex_init() -* @dev: DRM device -* @lock: lock to be initialized -* -* Returns: -* 0 on success, or a negative errno code otherwise. -* -* This is a &drm_device-managed version of mutex_init(). The initialized -* lock is automatically destroyed on the final drm_dev_put(). -*/ -int drmm_mutex_init (struct drm_device *dev,struct mutex *lock) -{ -mutex_init (lock); - -return drmm_add_action_or_reset (dev, drmm_mutex_release, lock); -} -EXPORT_SYMBOL (drmm_mutex_init); +EXPORT_SYMBOL (__drmm_mutex_release);
include/drm/drm_managed.h +17 -1
@@ -105,6 +105,22 @@ char *drmm_kstrdup(struct drm_device *devoid drmm_kfree (struct drm_device *dev,void *data); -int drmm_mutex_init (struct drm_device *dev,struct mutex *lock); +void __drmm_mutex_release (struct drm_device *dev,void *res); + +/** +* drmm_mutex_init - &drm_device-managed mutex_init() +* @dev: DRM device +* @lock: lock to be initialized +* +* Returns: +* 0 on success, or a negative errno code otherwise. +* +* This is a &drm_device-managed version of mutex_init(). The initialized +* lock is automatically destroyed on the final drm_dev_put(). +*/ +#define drmm_mutex_init (dev, lock) ({ \ + mutex_init(lock); \ + drmm_add_action_or_reset(dev, __drmm_mutex_release, lock); \ +}) \#endif
Greg Kroah-Hartman
maintainerPATCH 66/119 selftests: fib_tests: mute cleanup error message
In reply to Greg Kroah-HartmanFrom: Po-Hsu Lin <[email protected]>
commit d226b1df361988f885c298737d6019c863a25f26 upstream.
In the end of the test, there will be an error message induced by the ip netns del ns1 command in cleanup()
Tests passed: 201
Tests failed: 0
Cannot remove namespace file "/run/netns/ns1": No such file or directory
This can even be reproduced with just ./fib_tests.sh -h as we're calling cleanup() on exit.
Redirect the error message to /dev/null to mute it.
V2: Update commit message and fixes tag.
V3: resubmit due to missing netdev ML in V2
--- tools/testing/selftests/net/fib_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/fib_tests.sh +1 -1
@@ -68,7 +68,7 @@ setup() cleanup() { $IP link del dev dummy0 &> /dev/null - ip netns del ns1 + ip netns del ns1 &> /dev/null ip netns del ns2 &> /dev/null }
Greg Kroah-Hartman
maintainerPATCH 67/119 octeontx2-pf: Fix TSOv6 offload
In reply to Greg Kroah-HartmanFrom: Sunil Goutham <[email protected]>
commit de678ca38861f2eb58814048076dcf95ed1b5bf9 upstream.
HW adds segment size to the payload length
in the IPv6 header. Fix payload length to
just TCP header length instead of 'TCP header
size + IPv6 header size'.
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +1 -3
@@ -652,9 +652,7 @@ static void otx2_sqe_add_ext(struct otx2htons (ext->lso_sb -skb_network_offset (skb)); }else if (skb_shinfo (skb)->gso_type &SKB_GSO_TCPV6 ) { ext->lso_format = pfvf->hw.lso_tsov6_idx; - -ipv6_hdr (skb)->payload_len = -htons (ext->lso_sb -skb_network_offset (skb)); +ipv6_hdr (skb)->payload_len =htons (tcp_hdrlen (skb)); }else if (skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 ) {__be16 l3_proto =vlan_get_protocol (skb);struct udphdr *udph =udp_hdr (skb);
Greg Kroah-Hartman
maintainerPATCH 68/119 bpf: Fix mask generation for 32-bit narrow loads of 64-bit fields
In reply to Greg Kroah-HartmanFrom: Will Deacon <[email protected]>
commit 0613d8ca9ab382caabe9ed2dceb429e9781e443f upstream.
A narrow load from a 64-bit context field results in a 64-bit load followed potentially by a 64-bit right-shift and then a bitwise AND operation to extract the relevant data.
In the case of a 32-bit access, an immediate mask of 0xffffffff is used to construct a 64-bit BPP_AND operation which then sign-extends the mask value and effectively acts as a glorified no-op. For example:
0: 61 10 00 00 00 00 00 00 r0 = *(u32 *)(r1 + 0)
results in the following code generation for a 64-bit field:
ldr x7, [x7] // 64-bit load mov x10, #0xffffffffffffffff and x7, x7, x10
Fix the mask generation so that narrow loads always perform a 32-bit AND operation:
ldr x7, [x7] // 64-bit load mov w10, #0xffffffff and w7, w7, w10
--- kernel/bpf/verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/verifier.c +1 -1
@@ -13638,7 +13638,7 @@ static int convert_ctx_accesses(struct b insn_buf[cnt++] =BPF_ALU64_IMM (BPF_RSH , insn->dst_reg, shift); - insn_buf[cnt++] =BPF_ALU64_IMM (BPF_AND , insn->dst_reg, + insn_buf[cnt++] =BPF_ALU32_IMM (BPF_AND , insn->dst_reg, (1ULL << size *8 ) -1 ); } }
Greg Kroah-Hartman
maintainerPATCH 69/119 bpf: fix a memory leak in the LRU and LRU_PERCPU hash maps
In reply to Greg Kroah-HartmanFrom: Anton Protopopov <[email protected]>
commit b34ffb0c6d23583830f9327864b9c1f486003305 upstream.
The LRU and LRU_PERCPU maps allocate a new element on update before locking the target hash table bucket. Right after that the maps try to lock the bucket. If this fails, then maps return -EBUSY to the caller without releasing the allocated element. This makes the element untracked: it doesn't belong to either of free lists, and it doesn't belong to the hash table, so can't be re-used; this eventually leads to the permanent -ENOMEM on LRU map updates, which is unexpected. Fix this by returning the element to the local free list if bucket locking fails.
--- kernel/bpf/hashtab.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
kernel/bpf/hashtab.c +4 -2
@@ -1203,7 +1203,7 @@ static int htab_lru_map_update_elem(stru ret =htab_lock_bucket (htab, b, hash, &flags);if (ret) -return ret; + goto err_lock_bucket; l_old =lookup_elem_raw (head, hash, key, key_size);
@@ -1224,6 +1224,7 @@ static int htab_lru_map_update_elem(stru err:htab_unlock_bucket (htab, b, hash, flags); +err_lock_bucket:if (ret)htab_lru_push_free (htab, l_new);else if (l_old)
@@ -1326,7 +1327,7 @@ static int __htab_lru_percpu_map_update_ ret =htab_lock_bucket (htab, b, hash, &flags);if (ret) -return ret; + goto err_lock_bucket; l_old =lookup_elem_raw (head, hash, key, key_size);
@@ -1349,6 +1350,7 @@ static int __htab_lru_percpu_map_update_ ret =0 ; err:htab_unlock_bucket (htab, b, hash, flags); +err_lock_bucket:if (l_new)bpf_lru_push_free (&htab->lru, &l_new->lru_node);return ret;
Greg Kroah-Hartman
maintainerPATCH 70/119 lan966x: Fix unloading/loading of the driver
In reply to Greg Kroah-HartmanFrom: Horatiu Vultur <[email protected]>
commit 600761245952d7f70280add6ce02894f1528992b upstream.
It was noticing that after a while when unloading/loading the driver and sending traffic through the switch, it would stop working. It would stop forwarding any traffic and the only way to get out of this was to do a power cycle of the board. The root cause seems to be that the switch core is initialized twice. Apparently initializing twice the switch core disturbs the pointers in the queue systems in the HW, so after a while it would stop sending the traffic.
Unfortunetly, it is not possible to use a reset of the switch here, because the reset line is connected to multiple devices like MDIO, SGPIO, FAN, etc. So then all the devices will get reseted when the network driver will be loaded.
So the fix is to check if the core is initialized already and if that is the case don't initialize it again.
--- drivers/net/ethernet/microchip/lan966x/lan966x_main.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/ethernet/microchip/lan966x/lan966x_main.c +10 -0
@@ -987,6 +987,16 @@ static int lan966x_reset_switch(struct lreset_control_reset (switch_reset); +/* Don't reinitialize the switch core, if it is already initialized. In +* case it is initialized twice, some pointers inside the queue system +* in HW will get corrupted and then after a while the queue system gets +* full and no traffic is passing through the switch. The issue is seen +* when loading and unloading the driver and sending traffic through the +* switch. +*/ +if (lan_rd (lan966x,SYS_RESET_CFG ) &SYS_RESET_CFG_CORE_ENA ) +return 0 ; +lan_wr (SYS_RESET_CFG_CORE_ENA_SET (0 ), lan966x,SYS_RESET_CFG );lan_wr (SYS_RAM_INIT_RAM_INIT_SET (1 ), lan966x,SYS_RAM_INIT ); ret = readx_poll_timeout(lan966x_ram_init, lan966x,
Greg Kroah-Hartman
maintainerPATCH 71/119 ipv6: Fix out-of-bounds access in ipv6_find_tlv()
In reply to Greg Kroah-HartmanFrom: Gavrilov Ilia <[email protected]>
commit 878ecb0897f4737a4c9401f3523fd49589025671 upstream.
optlen is fetched without checking whether there is more than one byte to parse. It can lead to out-of-bounds access.
Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE.
--- net/ipv6/exthdrs_core.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv6/exthdrs_core.c +2 -0
@@ -143,6 +143,8 @@ int ipv6_find_tlv(const struct sk_buff * optlen =1 ;break ;default : +if (len <2 ) + goto bad; optlen = nh[offset +1 ] +2 ;if (optlen > len) goto bad;
Greg Kroah-Hartman
maintainerPATCH 72/119 cifs: mapchars mount option ignored
In reply to Greg Kroah-HartmanFrom: Steve French <[email protected]>
commit cb8b02fd6343228966324528adf920bfb8b8e681 upstream.
There are two ways that special characters (not allowed in some other operating systems like Windows, but allowed in POSIX) have been mapped in the past ("SFU" and "SFM" mappings) to allow them to be stored in a range reserved for special chars. The default for Linux has been to use "mapposix" (ie the SFM mapping) but the conversion to the new mount API in the 5.11 kernel broke the ability to override the default mapping of the reserved characters (like '?' and '*' and '\') via "mapchars" mount option.
This patch fixes that - so can now mount with "mapchars" mount option to override the default ("mapposix" ie SFM) mapping.
--- fs/cifs/fs_context.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/cifs/fs_context.c +8 -0
@@ -904,6 +904,14 @@ static int smb3_fs_context_parse_param(s ctx->sfu_remap = false;/* disable SFU mapping */ }break ; +case Opt_mapchars: +if (result.negated) + ctx->sfu_remap = false; +else { + ctx->sfu_remap = true; + ctx->remap = false;/* disable SFM (mapposix) mapping */ + } +break ;case Opt_user_xattr:if (result.negated) ctx->no_xattr =1 ;
Greg Kroah-Hartman
maintainerPATCH 73/119 power: supply: leds: Fix blink to LED on transition
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit e4484643991e0f6b89060092563f0dbab9450cbb upstream.
When a battery's status changes from charging to full then the charging-blink-full-solid trigger tries to change the LED from blinking to solid/on.
As is documented in include/linux/leds.h to deactivate blinking / to make the LED solid a LED_OFF must be send:
"""
* Deactivate blinking again when the brightness is set to LED_OFF
* via the brightness_set() callback.
"""
led_set_brighness() calls with a brightness value other then 0 / LED_OFF merely change the brightness of the LED in its on state while it is blinking.
So power_supply_update_bat_leds() must first send a LED_OFF event before the LED_FULL to disable blinking.
--- drivers/power/supply/power_supply_leds.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/power/supply/power_supply_leds.c +3 -2
@@ -34,8 +34,9 @@ static void power_supply_update_bat_ledsled_trigger_event (psy->charging_full_trig,LED_FULL );led_trigger_event (psy->charging_trig,LED_OFF );led_trigger_event (psy->full_trig,LED_FULL ); -led_trigger_event (psy->charging_blink_full_solid_trig, -LED_FULL ); +/* Going from blink to LED on requires a LED_OFF event to stop blink */ +led_trigger_event (psy->charging_blink_full_solid_trig,LED_OFF ); +led_trigger_event (psy->charging_blink_full_solid_trig,LED_FULL );break ;case POWER_SUPPLY_STATUS_CHARGING :led_trigger_event (psy->charging_full_trig,LED_FULL );
Greg Kroah-Hartman
maintainerPATCH 74/119 power: supply: mt6360: add a check of devm_work_autocancel in mt6360_charger_probe
In reply to Greg Kroah-HartmanFrom: Kang Chen <[email protected]>
commit 4cbb0d358883a27e432714b5256f0362946f5e25 upstream.
devm_work_autocancel may fail, add a check and return early.
--- drivers/power/supply/mt6360_charger.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/power/supply/mt6360_charger.c +3 -1
@@ -799,7 +799,9 @@ static int mt6360_charger_probe(struct p mci->vinovp =6500000 ;mutex_init (&mci->chgdet_lock);platform_set_drvdata (pdev, mci); -devm_work_autocancel (&pdev->dev, &mci->chrdet_work, mt6360_chrdet_work); + ret =devm_work_autocancel (&pdev->dev, &mci->chrdet_work, mt6360_chrdet_work); +if (ret) +return dev_err_probe (&pdev->dev, ret,"Failed to set delayed work\n" ); ret =device_property_read_u32 (&pdev->dev,"richtek,vinovp-microvolt" , &mci->vinovp);if (ret)
Greg Kroah-Hartman
maintainerPATCH 75/119 power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 5c34c0aef185dcd10881847b9ebf20046aa77cb4 upstream.
bq27xxx_battery_update() assumes / requires that it is only run once, not multiple times at the same time. But there are 3 possible callers:
1. bq27xxx_battery_poll() delayed_work item handler
2. bq27xxx_battery_irq_handler_thread() I2C IRQ handler
3. bq27xxx_battery_setup()
And there is no protection against these racing with each other, fix this race condition by making all callers take di->lock:
- Rename bq27xxx_battery_update() to bq27xxx_battery_update_unlocked()
- Add new bq27xxx_battery_update() which takes di->lock and then calls bq27xxx_battery_update_unlocked()
- Make stale cache check code in bq27xxx_battery_get_property(), which already takes di->lock directly to check the jiffies, call bq27xxx_battery_update_unlocked() instead of messing with the delayed_work item
- Make bq27xxx_battery_update_unlocked() mod the delayed-work item so that the next poll is delayed to poll_interval milliseconds after the last update independent of the source of the update
--- drivers/power/supply/bq27xxx_battery.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/power/supply/bq27xxx_battery.c +13 -8
@@ -1761,7 +1761,7 @@ static int bq27xxx_battery_read_health(sreturn POWER_SUPPLY_HEALTH_GOOD ; } -void bq27xxx_battery_update (struct bq27xxx_device_info *di) +static void bq27xxx_battery_update_unlocked (struct bq27xxx_device_info *di) {struct bq27xxx_reg_cache cache = {0 , };bool has_singe_flag = di->opts &BQ27XXX_O_ZERO ;
@@ -1800,6 +1800,16 @@ void bq27xxx_battery_update(struct bq27x di->cache = cache; di->last_update = jiffies; + +if (poll_interval >0 ) +mod_delayed_work (system_wq, &di->work, poll_interval *HZ ); +} + +void bq27xxx_battery_update (struct bq27xxx_device_info *di) +{ +mutex_lock (&di->lock); +bq27xxx_battery_update_unlocked (di); +mutex_unlock (&di->lock); }EXPORT_SYMBOL_GPL (bq27xxx_battery_update);
@@ -1810,9 +1820,6 @@ static void bq27xxx_battery_poll(struct work.work);bq27xxx_battery_update (di); - -if (poll_interval >0 ) -schedule_delayed_work (&di->work, poll_interval *HZ ); }static bool bq27xxx_battery_is_full (struct bq27xxx_device_info *di,int flags)
@@ -1985,10 +1992,8 @@ static int bq27xxx_battery_get_property(struct bq27xxx_device_info *di =power_supply_get_drvdata (psy);mutex_lock (&di->lock); -if (time_is_before_jiffies (di->last_update +5 *HZ )) { -cancel_delayed_work_sync (&di->work); -bq27xxx_battery_poll (&di->work.work); - } +if (time_is_before_jiffies (di->last_update +5 *HZ )) +bq27xxx_battery_update_unlocked (di);mutex_unlock (&di->lock);if (psp !=POWER_SUPPLY_PROP_PRESENT && di->cache.flags <0 )
Greg Kroah-Hartman
maintainerPATCH 76/119 power: supply: bq27xxx: Fix I2C IRQ race on remove
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 444ff00734f3878cd54ddd1ed5e2e6dbea9326d5 upstream.
devm_request_threaded_irq() requested IRQs are only free-ed after the driver's remove function has ran. So the IRQ could trigger and call bq27xxx_battery_update() after bq27xxx_battery_teardown() has already run.
Switch to explicitly free-ing the IRQ in bq27xxx_battery_i2c_remove() to fix this.
--- drivers/power/supply/bq27xxx_battery_i2c.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/power/supply/bq27xxx_battery_i2c.c +2 -1
@@ -179,7 +179,7 @@ static int bq27xxx_battery_i2c_probe(stri2c_set_clientdata (client, di);if (client->irq) { - ret =devm_request_threaded_irq (&client->dev, client->irq, + ret =request_threaded_irq (client->irq,NULL , bq27xxx_battery_irq_handler_thread,IRQF_ONESHOT , di->name, di);
@@ -209,6 +209,7 @@ static void bq27xxx_battery_i2c_remove(s {struct bq27xxx_device_info *di =i2c_get_clientdata (client); +free_irq (client->irq, di);bq27xxx_battery_teardown (di);mutex_lock (&battery_mutex);
Greg Kroah-Hartman
maintainerPATCH 77/119 power: supply: bq27xxx: Fix poll_interval handling and races on remove
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit c00bc80462afc7963f449d7f21d896d2f629cacc upstream.
Before this patch bq27xxx_battery_teardown() was setting poll_interval = 0 to avoid bq27xxx_battery_update() requeuing the delayed_work item.
There are 2 problems with this:
1. If the driver is unbound through sysfs, rather then the module being rmmod-ed, this changes poll_interval unexpectedly
2. This is racy, after it being set poll_interval could be changed before bq27xxx_battery_update() checks it through /sys/module/bq27xxx_battery/parameters/poll_interval
Fix this by added a removed attribute to struct bq27xxx_device_info and using that instead of setting poll_interval to 0.
There also is another poll_interval related race on remove(), writing /sys/module/bq27xxx_battery/parameters/poll_interval will requeue the delayed_work item for all devices on the bq27xxx_battery_devices list and the device being removed was only removed from that list after cancelling the delayed_work item.
Fix this by moving the removal from the bq27xxx_battery_devices list to before cancelling the delayed_work item.
--- drivers/power/supply/bq27xxx_battery.c | 22 +++++++++------------- include/linux/power/bq27xxx_battery.h | 1 + 2 files changed, 10 insertions(+), 13 deletions(-)
drivers/power/supply/bq27xxx_battery.c +9 -13
@@ -1801,7 +1801,7 @@ static void bq27xxx_battery_update_unloc di->last_update = jiffies; -if (poll_interval >0 ) +if (!di->removed && poll_interval >0 )mod_delayed_work (system_wq, &di->work, poll_interval *HZ ); }
@@ -2132,22 +2132,18 @@ EXPORT_SYMBOL_GPL(bq27xxx_battery_setup)void bq27xxx_battery_teardown (struct bq27xxx_device_info *di) { -/* -* power_supply_unregister call bq27xxx_battery_get_property which -* call bq27xxx_battery_poll. -* Make sure that bq27xxx_battery_poll will not call -* schedule_delayed_work again after unregister (which cause OOPS). -*/ - poll_interval =0 ; - -cancel_delayed_work_sync (&di->work); - -power_supply_unregister (di->bat); -mutex_lock (&bq27xxx_list_lock);list_del (&di->list);mutex_unlock (&bq27xxx_list_lock); +/* Set removed to avoid bq27xxx_battery_update() re-queuing the work */ +mutex_lock (&di->lock); + di->removed = true; +mutex_unlock (&di->lock); + +cancel_delayed_work_sync (&di->work); + +power_supply_unregister (di->bat);mutex_destroy (&di->lock); }EXPORT_SYMBOL_GPL (bq27xxx_battery_teardown);
include/linux/power/bq27xxx_battery.h +1 -0
@@ -68,6 +68,7 @@ struct bq27xxx_device_info {struct bq27xxx_access_methods bus;struct bq27xxx_reg_cache cache;int charge_design_full; +bool removed;unsigned long last_update;struct delayed_work work;struct power_supply *bat;
Greg Kroah-Hartman
maintainerPATCH 78/119 power: supply: bq27xxx: Add cache parameter to bq27xxx_battery_current_and_status()
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 35092c5819f8c5acc7bafe3fdbb13d6307c4f5e1 upstream.
Add a cache parameter to bq27xxx_battery_current_and_status() so that it can optionally use cached flags instead of re-reading them itself.
This is a preparation patch for making bq27xxx_battery_update() check the status and have it call power_supply_changed() on status changes.
--- drivers/power/supply/bq27xxx_battery.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/power/supply/bq27xxx_battery.c +12 -7
@@ -1840,7 +1840,8 @@ static bool bq27xxx_battery_is_full(strustatic int bq27xxx_battery_current_and_status (struct bq27xxx_device_info *di,union power_supply_propval *val_curr, -union power_supply_propval *val_status) +union power_supply_propval *val_status, +struct bq27xxx_reg_cache *cache) {bool single_flags = (di->opts &BQ27XXX_O_ZERO );int curr;
@@ -1852,10 +1853,14 @@ static int bq27xxx_battery_current_and_sreturn curr; } - flags =bq27xxx_read (di,BQ27XXX_REG_FLAGS , single_flags); -if (flags <0 ) { -dev_err (di->dev,"error reading flags\n" ); -return flags; +if (cache) { + flags = cache->flags; + }else { + flags =bq27xxx_read (di,BQ27XXX_REG_FLAGS , single_flags); +if (flags <0 ) { +dev_err (di->dev,"error reading flags\n" ); +return flags; + } }if (di->opts &BQ27XXX_O_ZERO ) {
@@ -2001,7 +2006,7 @@ static int bq27xxx_battery_get_property(switch (psp) {case POWER_SUPPLY_PROP_STATUS : - ret =bq27xxx_battery_current_and_status (di,NULL , val); + ret =bq27xxx_battery_current_and_status (di,NULL , val,NULL );break ;case POWER_SUPPLY_PROP_VOLTAGE_NOW : ret =bq27xxx_battery_voltage (di, val);
@@ -2010,7 +2015,7 @@ static int bq27xxx_battery_get_property( val->intval = di->cache.flags <0 ?0 :1 ;break ;case POWER_SUPPLY_PROP_CURRENT_NOW : - ret =bq27xxx_battery_current_and_status (di, val,NULL ); + ret =bq27xxx_battery_current_and_status (di, val,NULL ,NULL );break ;case POWER_SUPPLY_PROP_CAPACITY : ret =bq27xxx_simple_value (di->cache.capacity, val);
Greg Kroah-Hartman
maintainerPATCH 79/119 power: supply: bq27xxx: Move bq27xxx_battery_update() down
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit ff4c4a2a4437a6d03787c7aafb2617f20c3ef45f upstream.
Move the bq27xxx_battery_update() functions to below the bq27xxx_battery_current_and_status() function.
This is just moving a block of text, no functional changes.
This is a preparation patch for making bq27xxx_battery_update() check the status and have it call power_supply_changed() on status changes.
--- drivers/power/supply/bq27xxx_battery.c | 122 ++++++++++++++++----------------- 1 file changed, 61 insertions(+), 61 deletions(-)
drivers/power/supply/bq27xxx_battery.c +61 -61
@@ -1761,67 +1761,6 @@ static int bq27xxx_battery_read_health(sreturn POWER_SUPPLY_HEALTH_GOOD ; } -static void bq27xxx_battery_update_unlocked (struct bq27xxx_device_info *di) -{ -struct bq27xxx_reg_cache cache = {0 , }; -bool has_singe_flag = di->opts &BQ27XXX_O_ZERO ; - - cache.flags =bq27xxx_read (di,BQ27XXX_REG_FLAGS , has_singe_flag); -if ((cache.flags &0xff ) ==0xff ) - cache.flags =-1 ;/* read error */ -if (cache.flags >=0 ) { - cache.temperature =bq27xxx_battery_read_temperature (di); -if (di->regs[BQ27XXX_REG_TTE ] !=INVALID_REG_ADDR ) - cache.time_to_empty =bq27xxx_battery_read_time (di,BQ27XXX_REG_TTE ); -if (di->regs[BQ27XXX_REG_TTECP ] !=INVALID_REG_ADDR ) - cache.time_to_empty_avg =bq27xxx_battery_read_time (di,BQ27XXX_REG_TTECP ); -if (di->regs[BQ27XXX_REG_TTF ] !=INVALID_REG_ADDR ) - cache.time_to_full =bq27xxx_battery_read_time (di,BQ27XXX_REG_TTF ); - - cache.charge_full =bq27xxx_battery_read_fcc (di); - cache.capacity =bq27xxx_battery_read_soc (di); -if (di->regs[BQ27XXX_REG_AE ] !=INVALID_REG_ADDR ) - cache.energy =bq27xxx_battery_read_energy (di); - di->cache.flags = cache.flags; - cache.health =bq27xxx_battery_read_health (di); -if (di->regs[BQ27XXX_REG_CYCT ] !=INVALID_REG_ADDR ) - cache.cycle_count =bq27xxx_battery_read_cyct (di); - -/* We only have to read charge design full once */ -if (di->charge_design_full <=0 ) - di->charge_design_full =bq27xxx_battery_read_dcap (di); - } - -if ((di->cache.capacity != cache.capacity) || - (di->cache.flags != cache.flags)) -power_supply_changed (di->bat); - -if (memcmp (&di->cache, &cache,sizeof (cache)) !=0 ) - di->cache = cache; - - di->last_update = jiffies; - -if (!di->removed && poll_interval >0 ) -mod_delayed_work (system_wq, &di->work, poll_interval *HZ ); -} - -void bq27xxx_battery_update (struct bq27xxx_device_info *di) -{ -mutex_lock (&di->lock); -bq27xxx_battery_update_unlocked (di); -mutex_unlock (&di->lock); -} -EXPORT_SYMBOL_GPL (bq27xxx_battery_update); - -static void bq27xxx_battery_poll (struct work_struct *work) -{ -struct bq27xxx_device_info *di = - container_of(work, struct bq27xxx_device_info, - work.work); - -bq27xxx_battery_update (di); -} -static bool bq27xxx_battery_is_full (struct bq27xxx_device_info *di,int flags) {if (di->opts &BQ27XXX_O_ZERO )
@@ -1895,6 +1834,67 @@ static int bq27xxx_battery_current_and_sreturn 0 ; } +static void bq27xxx_battery_update_unlocked (struct bq27xxx_device_info *di) +{ +struct bq27xxx_reg_cache cache = {0 , }; +bool has_singe_flag = di->opts &BQ27XXX_O_ZERO ; + + cache.flags =bq27xxx_read (di,BQ27XXX_REG_FLAGS , has_singe_flag); +if ((cache.flags &0xff ) ==0xff ) + cache.flags =-1 ;/* read error */ +if (cache.flags >=0 ) { + cache.temperature =bq27xxx_battery_read_temperature (di); +if (di->regs[BQ27XXX_REG_TTE ] !=INVALID_REG_ADDR ) + cache.time_to_empty =bq27xxx_battery_read_time (di,BQ27XXX_REG_TTE ); +if (di->regs[BQ27XXX_REG_TTECP ] !=INVALID_REG_ADDR ) + cache.time_to_empty_avg =bq27xxx_battery_read_time (di,BQ27XXX_REG_TTECP ); +if (di->regs[BQ27XXX_REG_TTF ] !=INVALID_REG_ADDR ) + cache.time_to_full =bq27xxx_battery_read_time (di,BQ27XXX_REG_TTF ); + + cache.charge_full =bq27xxx_battery_read_fcc (di); + cache.capacity =bq27xxx_battery_read_soc (di); +if (di->regs[BQ27XXX_REG_AE ] !=INVALID_REG_ADDR ) + cache.energy =bq27xxx_battery_read_energy (di); + di->cache.flags = cache.flags; + cache.health =bq27xxx_battery_read_health (di); +if (di->regs[BQ27XXX_REG_CYCT ] !=INVALID_REG_ADDR ) + cache.cycle_count =bq27xxx_battery_read_cyct (di); + +/* We only have to read charge design full once */ +if (di->charge_design_full <=0 ) + di->charge_design_full =bq27xxx_battery_read_dcap (di); + } + +if ((di->cache.capacity != cache.capacity) || + (di->cache.flags != cache.flags)) +power_supply_changed (di->bat); + +if (memcmp (&di->cache, &cache,sizeof (cache)) !=0 ) + di->cache = cache; + + di->last_update = jiffies; + +if (!di->removed && poll_interval >0 ) +mod_delayed_work (system_wq, &di->work, poll_interval *HZ ); +} + +void bq27xxx_battery_update (struct bq27xxx_device_info *di) +{ +mutex_lock (&di->lock); +bq27xxx_battery_update_unlocked (di); +mutex_unlock (&di->lock); +} +EXPORT_SYMBOL_GPL (bq27xxx_battery_update); + +static void bq27xxx_battery_poll (struct work_struct *work) +{ +struct bq27xxx_device_info *di = + container_of(work, struct bq27xxx_device_info, + work.work); + +bq27xxx_battery_update (di); +} +/* * Get the average power in µW * Return < 0 if something fails.
Greg Kroah-Hartman
maintainerPATCH 80/119 power: supply: bq27xxx: Ensure power_supply_changed() is called on current sign changes
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 939a116142012926e25de0ea6b7e2f8d86a5f1b6 upstream.
On gauges where the current register is signed, there is no charging flag in the flags register. So only checking flags will not result in power_supply_changed() getting called when e.g. a charger is plugged in and the current sign changes from negative (discharging) to positive (charging).
This causes userspace's notion of the status to lag until userspace does a poll.
And when a power_supply_leds.c LED trigger is used to indicate charging status with a LED, this LED will lag until the capacity percentage changes, which may take many minutes (because the LED trigger only is updated on power_supply_changed() calls).
Fix this by calling bq27xxx_battery_current_and_status() on gauges with a signed current register and checking if the status has changed.
--- drivers/power/supply/bq27xxx_battery.c | 13 ++++++++++++- include/linux/power/bq27xxx_battery.h | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-)
drivers/power/supply/bq27xxx_battery.c +12 -1
@@ -1836,6 +1836,7 @@ static int bq27xxx_battery_current_and_sstatic void bq27xxx_battery_update_unlocked (struct bq27xxx_device_info *di) { +union power_supply_propval status = di->last_status;struct bq27xxx_reg_cache cache = {0 , };bool has_singe_flag = di->opts &BQ27XXX_O_ZERO ;
@@ -1860,14 +1861,24 @@ static void bq27xxx_battery_update_unlocif (di->regs[BQ27XXX_REG_CYCT ] !=INVALID_REG_ADDR ) cache.cycle_count =bq27xxx_battery_read_cyct (di); +/* +* On gauges with signed current reporting the current must be +* checked to detect charging <-> discharging status changes. +*/ +if (!(di->opts &BQ27XXX_O_ZERO )) +bq27xxx_battery_current_and_status (di,NULL , &status, &cache); +/* We only have to read charge design full once */ if (di->charge_design_full <=0 ) di->charge_design_full =bq27xxx_battery_read_dcap (di); }if ((di->cache.capacity != cache.capacity) || - (di->cache.flags != cache.flags)) + (di->cache.flags != cache.flags) || + (di->last_status.intval != status.intval)) { + di->last_status.intval = status.intval;power_supply_changed (di->bat); + }if (memcmp (&di->cache, &cache,sizeof (cache)) !=0 ) di->cache = cache;
include/linux/power/bq27xxx_battery.h +3 -0
@@ -2,6 +2,8 @@#ifndef __LINUX_BQ27X00_BATTERY_H__#define __LINUX_BQ27X00_BATTERY_H__ +#include <linux/power_supply.h> +enum bq27xxx_chip {BQ27000 =1 ,/* bq27000, bq27200 */ BQ27010, /* bq27010, bq27210 */
@@ -70,6 +72,7 @@ struct bq27xxx_device_info {int charge_design_full;bool removed;unsigned long last_update; +union power_supply_propval last_status;struct delayed_work work;struct power_supply *bat;struct list_head list;
Greg Kroah-Hartman
maintainerPATCH 81/119 power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to stabilize
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 59a99cd462fbdf71f4e845e09f37783035088b4f upstream.
bq27xxx_external_power_changed() gets called when the charger is plugged in or out. Rather then immediately scheduling an update wait 0.5 seconds for things to stabilize, so that e.g. the (dis)charge current is stable when bq27xxx_battery_update() runs.
--- drivers/power/supply/bq27xxx_battery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/power/supply/bq27xxx_battery.c +2 -2
@@ -2099,8 +2099,8 @@ static void bq27xxx_external_power_chang {struct bq27xxx_device_info *di =power_supply_get_drvdata (psy); -cancel_delayed_work_sync (&di->work); -schedule_delayed_work (&di->work,0 ); +/* After charger plug in/out wait 0.5s for things to stabilize */ +mod_delayed_work (system_wq, &di->work,HZ /2 ); }int bq27xxx_battery_setup (struct bq27xxx_device_info *di)
Greg Kroah-Hartman
maintainerPATCH 82/119 power: supply: bq25890: Call power_supply_changed() after updating input current or voltage
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit ad3d9c779b1f09f3f3a6fefd07af407c7bc7c9a7 upstream.
The bq25892 model relies on external charger-type detection and once that is done the bq25890_charger code will update the input current and if pumpexpress is used also the input voltage.
In this case, when the initial power_supply_changed() call is made from the interrupt handler, the input settings are 5V/0.5A which on many devices is not enough power to charge (while the device is on).
On many devices the fuel-gauge relies in its external_power_changed callback to timely signal userspace about charging <-> discharging status changes. Add a power_supply_changed() call after updating the input current or voltage. This allows the fuel-gauge driver to timely recheck if the battery is charging after the new input settings have been applied and then it can immediately notify userspace about this.
--- drivers/power/supply/bq25890_charger.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/power/supply/bq25890_charger.c +3 -0
@@ -675,6 +675,7 @@ static void bq25890_charger_external_pow }bq25890_field_write (bq,F_IINLIM , input_current_limit); +power_supply_changed (psy); } static int bq25890_get_chip_state(struct bq25890_device *bq,
@@ -973,6 +974,8 @@ static void bq25890_pump_express_work(stdev_info (bq->dev,"Hi-voltage charging requested, input voltage is %d mV\n" , voltage); +power_supply_changed (bq->charger); +return ; error_print:bq25890_field_write (bq,F_PUMPX_EN ,0 );
Greg Kroah-Hartman
maintainerPATCH 83/119 power: supply: bq24190: Call power_supply_changed() after updating input current
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
commit 77c2a3097d7029441e8a91aa0de1b4e5464593da upstream.
The bq24192 model relies on external charger-type detection and once that is done the bq24190_charger code will update the input current.
In this case, when the initial power_supply_changed() call is made from the interrupt handler, the input settings are 5V/0.5A which on many devices is not enough power to charge (while the device is on).
On many devices the fuel-gauge relies in its external_power_changed callback to timely signal userspace about charging <-> discharging status changes. Add a power_supply_changed() call after updating the input current. This allows the fuel-gauge driver to timely recheck if the battery is charging after the new input current has been applied and then it can immediately notify userspace about this.
--- drivers/power/supply/bq24190_charger.c | 1 + 1 file changed, 1 insertion(+)
drivers/power/supply/bq24190_charger.c +1 -0
@@ -1262,6 +1262,7 @@ static void bq24190_input_current_limit_bq24190_charger_set_property (bdi->charger,POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT , &val); +power_supply_changed (bdi->charger); }/* Sync the input-current-limit with our parent supply (if we have one) */
Greg Kroah-Hartman
maintainerPATCH 84/119 power: supply: sbs-charger: Fix INHIBITED bit for Status reg
In reply to Greg Kroah-HartmanFrom: Daisuke Nojiri <[email protected]>
commit b2f2a3c9800208b0db2c2e34b05323757117faa2 upstream.
CHARGE_INHIBITED bit position of the ChargerStatus register is actually 0 not 1. This patch corrects it.
--- drivers/power/supply/sbs-charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/supply/sbs-charger.c +1 -1
@@ -24,7 +24,7 @@#define SBS_CHARGER_REG_STATUS 0x13#define SBS_CHARGER_REG_ALARM_WARNING 0x16 -#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(1) +#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(0)#define SBS_CHARGER_STATUS_RES_COLD BIT(9)#define SBS_CHARGER_STATUS_RES_HOT BIT(10)#define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14)
Greg Kroah-Hartman
maintainerPATCH 85/119 optee: fix uninited async notif value
In reply to Greg Kroah-HartmanFrom: Etienne Carriere <[email protected]>
commit 654d0310007146fae87b0c1a68f81e53ad519b14 upstream.
Fixes an uninitialized variable in irq_handler() that could lead to unpredictable behavior in case OP-TEE fails to handle SMC function ID OPTEE_SMC_GET_ASYNC_NOTIF_VALUE. This change ensures that in that case get_async_notif_value() properly reports there are no notification event.
--- drivers/tee/optee/smc_abi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/tee/optee/smc_abi.c +3 -1
@@ -984,8 +984,10 @@ static u32 get_async_notif_value(optee_invoke_fn *invoke_fn, bool *value_valid,invoke_fn (OPTEE_SMC_GET_ASYNC_NOTIF_VALUE ,0 ,0 ,0 ,0 ,0 ,0 ,0 , &res); -if (res.a0) +if (res.a0) { + *value_valid = false;return 0 ; + } *value_valid = (res.a2 &OPTEE_SMC_ASYNC_NOTIF_VALUE_VALID ); *value_pending = (res.a2 &OPTEE_SMC_ASYNC_NOTIF_VALUE_PENDING );return res.a1;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 86/119 firmware: arm_ffa: Check if ffa_driver remove is present before executing
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
commit b71b55248a580e9c9befc4ae060539f1f8e477da upstream.
Currently ffa_drv->remove() is called unconditionally from ffa_device_remove(). Since the driver registration doesn't check for it and allows it to be registered without .remove callback, we need to check for the presence of it before executing it from ffa_device_remove() to above a NULL pointer dereference like the one below:
| Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 | Mem abort info: | ESR = 0x0000000086000004 | EC = 0x21: IABT (current EL), IL = 32 bits | SET = 0, FnV = 0 | EA = 0, S1PTW = 0 | FSC = 0x04: level 0 translation fault | user pgtable: 4k pages, 48-bit VAs, pgdp=0000000881cc8000 | [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 | Internal error: Oops: 0000000086000004 [#1] PREEMPT SMP | CPU: 3 PID: 130 Comm: rmmod Not tainted 6.3.0-rc7 #6 | Hardware name: FVP Base RevC (DT) | pstate: 63402809 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=-c) | pc : 0x0 | lr : ffa_device_remove+0x20/0x2c | Call trace: | 0x0 | device_release_driver_internal+0x16c/0x260 | driver_detach+0x90/0xd0 | bus_remove_driver+0xdc/0x11c | driver_unregister+0x30/0x54 | ffa_driver_unregister+0x14/0x20 | cleanup_module+0x18/0xeec | __arm64_sys_delete_module+0x234/0x378 | invoke_syscall+0x40/0x108 | el0_svc_common+0xb4/0xf0 | do_el0_svc+0x30/0xa4 | el0_svc+0x2c/0x7c | el0t_64_sync_handler+0x84/0xf0 | el0t_64_sync+0x190/0x194
--- drivers/firmware/arm_ffa/bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/firmware/arm_ffa/bus.c +2 -1
@@ -53,7 +53,8 @@ static void ffa_device_remove(struct dev {struct ffa_driver *ffa_drv =to_ffa_driver (dev->driver); - ffa_drv->remove (to_ffa_dev (dev)); +if (ffa_drv->remove) + ffa_drv->remove (to_ffa_dev (dev)); }static int ffa_device_uevent (struct device *dev,struct kobj_uevent_env *env)
Greg Kroah-Hartman
maintainerPATCH 87/119 firmware: arm_ffa: Fix FFA device names for logical partitions
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
commit 19b8766459c41c6f318f8a548cc1c66dffd18363 upstream.
Each physical partition can provide multiple services each with UUID. Each such service can be presented as logical partition with a unique combination of VM ID and UUID. The number of distinct UUID in a system will be less than or equal to the number of logical partitions.
However, currently it fails to register more than one logical partition or service within a physical partition as the device name contains only VM ID while both VM ID and UUID are maintained in the partition information. The kernel complains with the below message:
| sysfs: cannot create duplicate filename '/devices/arm-ffa-8001' | CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.3.0-rc7 #8 | Hardware name: FVP Base RevC (DT) | Call trace: | dump_backtrace+0xf8/0x118 | show_stack+0x18/0x24 | dump_stack_lvl+0x50/0x68 | dump_stack+0x18/0x24 | sysfs_create_dir_ns+0xe0/0x13c | kobject_add_internal+0x220/0x3d4 | kobject_add+0x94/0x100 | device_add+0x144/0x5d8 | device_register+0x20/0x30 | ffa_device_register+0x88/0xd8 | ffa_setup_partitions+0x108/0x1b8 | ffa_init+0x2ec/0x3a4 | do_one_initcall+0xcc/0x240 | do_initcall_level+0x8c/0xac | do_initcalls+0x54/0x94 | do_basic_setup+0x1c/0x28 | kernel_init_freeable+0x100/0x16c | kernel_init+0x20/0x1a0 | ret_from_fork+0x10/0x20 | kobject_add_internal failed for arm-ffa-8001 with -EEXIST, don't try to | register things with the same name in the same directory. | arm_ffa arm-ffa: unable to register device arm-ffa-8001 err=-17 | ARM FF-A: ffa_setup_partitions: failed to register partition ID 0x8001
By virtue of being random enough to avoid collisions when generated in a distributed system, there is no way to compress UUID keys to the number of bits required to identify each. We can eliminate '-' in the name but it is not worth eliminating 4 bytes and add unnecessary logic for doing that. Also v1.0 doesn't provide the UUID of the partitions which makes it hard to use the same for the device name.
So to keep it simple, let us alloc an ID using ida_alloc() and append the same to "arm-ffa" to make up a unique device name. Also stash the id value in ffa_dev to help freeing the ID later when the device is destroyed.
--- drivers/firmware/arm_ffa/bus.c | 16 +++++++++++++--- include/linux/arm_ffa.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-)
drivers/firmware/arm_ffa/bus.c +13 -3
@@ -15,6 +15,8 @@#include "common.h" +static DEFINE_IDA (ffa_bus_id); +static int ffa_device_match (struct device *dev,struct device_driver *drv) {const struct ffa_device_id *id_table;
@@ -131,6 +133,7 @@ static void ffa_release_device(struct de {struct ffa_device *ffa_dev =to_ffa_dev (dev); +ida_free (&ffa_bus_id, ffa_dev->id);kfree (ffa_dev); }
@@ -171,18 +174,24 @@ bool ffa_device_is_valid(struct ffa_devistruct ffa_device *ffa_device_register (const uuid_t *uuid,int vm_id,const struct ffa_ops *ops) { -int ret; +int id, ret;struct device *dev;struct ffa_device *ffa_dev; + id =ida_alloc_min (&ffa_bus_id,1 ,GFP_KERNEL ); +if (id <0 ) +return NULL ; + ffa_dev =kzalloc (sizeof (*ffa_dev),GFP_KERNEL ); -if (!ffa_dev) +if (!ffa_dev) { +ida_free (&ffa_bus_id, id);return NULL ; + } dev = &ffa_dev->dev; dev->bus = &ffa_bus_type; dev->release = ffa_release_device; -dev_set_name (&ffa_dev->dev,"arm-ffa-%04x" , vm_id); +dev_set_name (&ffa_dev->dev,"arm-ffa-%d" , id); ffa_dev->vm_id = vm_id; ffa_dev->ops = ops;
@@ -218,4 +227,5 @@ void arm_ffa_bus_exit(void) {ffa_devices_unregister ();bus_unregister (&ffa_bus_type); +ida_destroy (&ffa_bus_id); }
include/linux/arm_ffa.h +1 -0
@@ -13,6 +13,7 @@/* FFA Bus/Device/Driver related */ struct ffa_device { +u32 id;int vm_id;bool mode_32bit;uuid_t uuid;
Greg Kroah-Hartman
maintainerPATCH 88/119 fs: fix undefined behavior in bit shift for SB_NOUSER
In reply to Greg Kroah-HartmanFrom: Hao Ge <[email protected]>
commit f15afbd34d8fadbd375f1212e97837e32bc170cc upstream.
Shifting signed 32-bit value by 31 bits is undefined, so changing significant bit to unsigned. It was spotted by UBSAN.
So let's just fix this by using the BIT() helper for all SB_* flags.
Message-Id: <[email protected]>
--- include/linux/fs.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-)
include/linux/fs.h +21 -21
@@ -1380,29 +1380,29 @@ extern int send_sigurg(struct fown_struc* sb->s_flags. Note that these mirror the equivalent MS_* flags where * represented in both. */ -#define SB_RDONLY 1/* Mount read-only */ -#define SB_NOSUID 2/* Ignore suid and sgid bits */ -#define SB_NODEV 4/* Disallow access to device special files */ -#define SB_NOEXEC 8/* Disallow program execution */ -#define SB_SYNCHRONOUS 16/* Writes are synced at once */ -#define SB_MANDLOCK 64/* Allow mandatory locks on an FS */ -#define SB_DIRSYNC 128/* Directory modifications are synchronous */ -#define SB_NOATIME 1024/* Do not update access times. */ -#define SB_NODIRATIME 2048/* Do not update directory access times */ -#define SB_SILENT 32768 -#define SB_POSIXACL (1<<16)/* VFS does not apply the umask */ -#define SB_INLINECRYPT (1<<17)/* Use blk-crypto for encrypted files */ -#define SB_KERNMOUNT (1<<22)/* this is a kern_mount call */ -#define SB_I_VERSION (1<<23)/* Update inode I_version field */ -#define SB_LAZYTIME (1<<25)/* Update the on-disk [acm]times lazily */ +#define SB_RDONLY BIT(0)/* Mount read-only */ +#define SB_NOSUID BIT(1)/* Ignore suid and sgid bits */ +#define SB_NODEV BIT(2)/* Disallow access to device special files */ +#define SB_NOEXEC BIT(3)/* Disallow program execution */ +#define SB_SYNCHRONOUS BIT(4)/* Writes are synced at once */ +#define SB_MANDLOCK BIT(6)/* Allow mandatory locks on an FS */ +#define SB_DIRSYNC BIT(7)/* Directory modifications are synchronous */ +#define SB_NOATIME BIT(10)/* Do not update access times. */ +#define SB_NODIRATIME BIT(11)/* Do not update directory access times */ +#define SB_SILENT BIT(15) +#define SB_POSIXACL BIT(16)/* VFS does not apply the umask */ +#define SB_INLINECRYPT BIT(17)/* Use blk-crypto for encrypted files */ +#define SB_KERNMOUNT BIT(22)/* this is a kern_mount call */ +#define SB_I_VERSION BIT(23)/* Update inode I_version field */ +#define SB_LAZYTIME BIT(25)/* Update the on-disk [acm]times lazily */ /* These sb flags are internal to the kernel */ -#define SB_SUBMOUNT (1<<26) -#define SB_FORCE (1<<27) -#define SB_NOSEC (1<<28) -#define SB_BORN (1<<29) -#define SB_ACTIVE (1<<30) -#define SB_NOUSER (1<<31) +#define SB_SUBMOUNT BIT(26) +#define SB_FORCE BIT(27) +#define SB_NOSEC BIT(28) +#define SB_BORN BIT(29) +#define SB_ACTIVE BIT(30) +#define SB_NOUSER BIT(31)/* These flags relate to encoding and casefolding */ #define SB_ENC_STRICT_MODE_FL (1 << 0)
Greg Kroah-Hartman
maintainerPATCH 89/119 regulator: pca9450: Fix BUCK2 enable_mask
In reply to Greg Kroah-HartmanFrom: Alexander Stein <[email protected]>
commit d67dada3e2524514b09496b9ee1df22d4507a280 upstream.
This fixes a copy & paste error.
No functional change intended, BUCK1_ENMODE_MASK equals BUCK2_ENMODE_MASK.
Originally-from: Robin Gong <[email protected]
--- drivers/regulator/pca9450-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/regulator/pca9450-regulator.c +2 -2
@@ -264,7 +264,7 @@ static const struct pca9450_regulator_de .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0, .vsel_mask = BUCK2OUT_DVS0_MASK, .enable_reg = PCA9450_REG_BUCK2CTRL, - .enable_mask = BUCK1_ENMODE_MASK, + .enable_mask = BUCK2_ENMODE_MASK, .ramp_reg = PCA9450_REG_BUCK2CTRL, .ramp_mask = BUCK2_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table,
@@ -502,7 +502,7 @@ static const struct pca9450_regulator_de .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0, .vsel_mask = BUCK2OUT_DVS0_MASK, .enable_reg = PCA9450_REG_BUCK2CTRL, - .enable_mask = BUCK1_ENMODE_MASK, + .enable_mask = BUCK2_ENMODE_MASK, .ramp_reg = PCA9450_REG_BUCK2CTRL, .ramp_mask = BUCK2_RAMP_MASK, .ramp_delay_table = pca9450_dvs_buck_ramp_table,
Greg Kroah-Hartman
maintainerPATCH 90/119 platform/x86: ISST: Remove 8 socket limit
In reply to Greg Kroah-HartmanFrom: Steve Wahl <[email protected]>
commit bbb320bfe2c3e9740fe89cfa0a7089b4e8bfc4ff upstream.
Stop restricting the PCI search to a range of PCI domains fed to pci_get_domain_bus_and_slot(). Instead, use for_each_pci_dev() and look at all PCI domains in one pass.
On systems with more than 8 sockets, this avoids error messages like "Information: Invalid level, Can't get TDP control information at specified levels on cpu 480" from the intel speed select utility.
--- drivers/platform/x86/intel/speed_select_if/isst_if_common.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/platform/x86/intel/speed_select_if/isst_if_common.c +5 -7
@@ -294,14 +294,13 @@ struct isst_if_pkg_info {static struct isst_if_cpu_info *isst_cpu_info;static struct isst_if_pkg_info *isst_pkg_info; -#define ISST_MAX_PCI_DOMAINS 8 -static struct pci_dev *_isst_if_get_pci_dev (int cpu,int bus_no,int dev,int fn) {struct pci_dev *matched_pci_dev =NULL ;struct pci_dev *pci_dev =NULL ; +struct pci_dev *_pci_dev =NULL ;int no_matches =0 , pkg_id; -int i, bus_number; +int bus_number;if (bus_no <0 || bus_no >=ISST_MAX_BUS_NUMBER || cpu <0 || cpu >= nr_cpu_ids || cpu >=num_possible_cpus ())
@@ -313,12 +312,11 @@ static struct pci_dev *_isst_if_get_pci_if (bus_number <0 )return NULL ; -for (i =0 ; i <ISST_MAX_PCI_DOMAINS ; ++i) { -struct pci_dev *_pci_dev; +for_each_pci_dev (_pci_dev) {int node; - _pci_dev =pci_get_domain_bus_and_slot (i, bus_number,PCI_DEVFN (dev, fn)); -if (!_pci_dev) +if (_pci_dev->bus->number != bus_number || + _pci_dev->devfn !=PCI_DEVFN (dev, fn))continue ; ++no_matches;
Greg Kroah-Hartman
maintainerPATCH 91/119 coresight: Fix signedness bug in tmc_etr_buf_insert_barrier_packet()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit f67bc15e526bb9920683ad6c1891ff9e08981335 upstream.
This code generates a Smatch warning:
drivers/hwtracing/coresight/coresight-tmc-etr.c:947 tmc_etr_buf_insert_barrier_packet()
error: uninitialized symbol 'bufp'.
The problem is that if tmc_sg_table_get_data() returns -EINVAL, then when we test if "len < CORESIGHT_BARRIER_PKT_SIZE", the negative "len" value is type promoted to a high unsigned long value which is greater than CORESIGHT_BARRIER_PKT_SIZE. Fix this bug by adding an explicit check for error codes.
--- drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-tmc-etr.c +1 -1
@@ -942,7 +942,7 @@ tmc_etr_buf_insert_barrier_packet(struct len =tmc_etr_buf_get_data (etr_buf, offset,CORESIGHT_BARRIER_PKT_SIZE , &bufp); -if (WARN_ON (len <CORESIGHT_BARRIER_PKT_SIZE )) +if (WARN_ON (len <0 || len <CORESIGHT_BARRIER_PKT_SIZE ))return -EINVAL ;coresight_insert_barrier_packet (bufp);return offset +CORESIGHT_BARRIER_PKT_SIZE ;
Greg Kroah-Hartman
maintainerPATCH 92/119 ARM: dts: imx6qdl-mba6: Add missing pvcie-supply regulator
In reply to Greg Kroah-HartmanFrom: Alexander Stein <[email protected]>
commit 91aa4b3782448a7a13baa8cbcdfd5fd19defcbd9 upstream.
This worked before by coincidence, as the regulator was probed and enabled before PCI RC probe. But probe order changed since commit 259b93b21a9f ("regulator: Set PROBE_PREFER_ASYNCHRONOUS for drivers that existed in 4.14") and PCIe supply is enabled after RC.
Fix this by adding the regulator to RC node.
The PCIe vaux regulator still needs to be enabled unconditionally for Mini-PCIe USB-only devices.
--- arch/arm/boot/dts/imx6qdl-mba6.dtsi | 1 + 1 file changed, 1 insertion(+)
arch/arm/boot/dts/imx6qdl-mba6.dtsi +1 -0
@@ -209,6 +209,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; reset-gpio = <&gpio6 7 GPIO_ACTIVE_LOW>; + vpcie-supply = <®_pcie>; status = "okay"; };
Greg Kroah-Hartman
maintainerPATCH 93/119 x86/pci/xen: populate MSI sysfs entries
In reply to Greg Kroah-HartmanFrom: Maximilian Heyne <[email protected]>
commit 335b4223466dd75f9f3ea4918187afbadd22e5c8 upstream.
Commit bf5e758f02fc ("genirq/msi: Simplify sysfs handling") reworked the creation of sysfs entries for MSI IRQs. The creation used to be in msi_domain_alloc_irqs_descs_locked after calling ops->domain_alloc_irqs. Then it moved into __msi_domain_alloc_irqs which is an implementation of domain_alloc_irqs. However, Xen comes with the only other implementation of domain_alloc_irqs and hence doesn't run the sysfs population code anymore.
Commit 6c796996ee70 ("x86/pci/xen: Fixup fallout from the PCI/MSI overhaul") set the flag MSI_FLAG_DEV_SYSFS for the xen msi_domain_info but that doesn't actually have an effect because Xen uses it's own domain_alloc_irqs implementation.
Fix this by making use of the fallback functions for sysfs population.
--- arch/x86/pci/xen.c | 8 +++++--- include/linux/msi.h | 9 ++++++++- kernel/irq/msi.c | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-)
arch/x86/pci/xen.c +5 -3
@@ -198,7 +198,7 @@ static int xen_setup_msi_irqs(struct pci i++; }kfree (v); -return 0 ; +return msi_device_populate_sysfs (&dev->dev); error:if (ret == -ENOSYS )
@@ -254,7 +254,7 @@ static int xen_hvm_setup_msi_irqs(structdev_dbg (&dev->dev,"xen: msi --> pirq=%d --> irq=%d\n" , pirq, irq); } -return 0 ; +return msi_device_populate_sysfs (&dev->dev); error: dev_err(&dev->dev, "Failed to create MSI%s! ret=%d!\n",
@@ -346,7 +346,7 @@ static int xen_initdom_setup_msi_irqs(stif (ret <0 ) goto out; } - ret =0 ; + ret =msi_device_populate_sysfs (&dev->dev); out:return ret; }
@@ -393,6 +393,8 @@ static void xen_teardown_msi_irqs(structfor (i =0 ; i < msidesc->nvec_used; i++)xen_destroy_irq (msidesc->irq + i); } + +msi_device_destroy_sysfs (&dev->dev); }static void xen_pv_teardown_msi_irqs (struct pci_dev *dev)
include/linux/msi.h +8 -1
@@ -278,6 +278,13 @@ int arch_setup_msi_irq(struct pci_dev *dvoid arch_teardown_msi_irq (unsigned int irq);int arch_setup_msi_irqs (struct pci_dev *dev,int nvec,int type);void arch_teardown_msi_irqs (struct pci_dev *dev); +#endif /* CONFIG_PCI_MSI_ARCH_FALLBACKS */ + +/* +* Xen uses non-default msi_domain_ops and hence needs a way to populate sysfs +* entries of MSI IRQs. +*/ +#if defined(CONFIG_PCI_XEN ) || defined(CONFIG_PCI_MSI_ARCH_FALLBACKS )#ifdef CONFIG_SYSFS int msi_device_populate_sysfs (struct device *dev);void msi_device_destroy_sysfs (struct device *dev);
@@ -285,7 +292,7 @@ void msi_device_destroy_sysfs(struct devstatic inline int msi_device_populate_sysfs (struct device *dev) {return 0 ; }static inline void msi_device_destroy_sysfs (struct device *dev) { }#endif /* !CONFIG_SYSFS */ -#endif /* CONFIG_PCI_MSI_ARCH_FALLBACKS */ +#endif /* CONFIG_PCI_XEN || CONFIG_PCI_MSI_ARCH_FALLBACKS */ /* * The restore hook is still available even for fully irq domain based
kernel/irq/msi.c +2 -2
@@ -420,7 +420,7 @@ fail:return ret; } -#ifdef CONFIG_PCI_MSI_ARCH_FALLBACKS +#if defined(CONFIG_PCI_MSI_ARCH_FALLBACKS ) || defined(CONFIG_PCI_XEN )/** * msi_device_populate_sysfs - Populate msi_irqs sysfs entries for a device * @dev: The device (PCI, platform etc) which will get sysfs entries
@@ -452,7 +452,7 @@ void msi_device_destroy_sysfs(struct devmsi_for_each_desc (desc, dev,MSI_DESC_ALL ) msi_sysfs_remove_desc(dev, desc); } -#endif /* CONFIG_PCI_MSI_ARCH_FALLBACK */ +#endif /* CONFIG_PCI_MSI_ARCH_FALLBACK || CONFIG_PCI_XEN */ #else /* CONFIG_SYSFS */ static inline int msi_sysfs_create_group (struct device *dev) {return 0 ; }static inline int msi_sysfs_populate_desc (struct device *dev,struct msi_desc *desc) {return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 94/119 xen/pvcalls-back: fix double frees with pvcalls_new_active_socket()
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 8fafac202d18230bb9926bda48e563fd2cce2a4f upstream.
In the pvcalls_new_active_socket() function, most error paths call pvcalls_back_release_active(fedata->dev, fedata, map) which calls sock_release() on "sock". The bug is that the caller also frees sock.
Fix this by making every error path in pvcalls_new_active_socket() release the sock, and don't free it in the caller.
--- drivers/xen/pvcalls-back.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/xen/pvcalls-back.c +4 -5
@@ -321,8 +321,10 @@ static struct sock_mapping *pvcalls_new_void *page; map =kzalloc (sizeof (*map),GFP_KERNEL ); -if (map ==NULL ) +if (map ==NULL ) { +sock_release (sock);return NULL ; + } map->fedata = fedata; map->sock = sock;
@@ -414,10 +416,8 @@ static int pvcalls_back_connect(struct x req->u.connect.ref, req->u.connect.evtchn, sock); -if (!map) { +if (!map) ret = -EFAULT ; -sock_release (sock); - } out: rsp =RING_GET_RESPONSE (&fedata->ring, fedata->ring.rsp_prod_pvt++);
@@ -557,7 +557,6 @@ static void __pvcalls_back_accept(struct sock);if (!map) { ret = -EFAULT ; -sock_release (sock); goto out_error; }
Greg Kroah-Hartman
maintainerPATCH 95/119 x86/show_trace_log_lvl: Ensure stack pointer is aligned, again
In reply to Greg Kroah-HartmanFrom: Vernon Lovejoy <[email protected]>
commit 2e4be0d011f21593c6b316806779ba1eba2cd7e0 upstream.
The commit e335bb51cc15 ("x86/unwind: Ensure stack pointer is aligned") tried to align the stack pointer in show_trace_log_lvl(), otherwise the "stack < stack_info.end" check can't guarantee that the last read does not go past the end of the stack.
However, we have the same problem with the initial value of the stack pointer, it can also be unaligned. So without this patch this trivial kernel module
#include <linux/module.h>
static int init(void)
{
asm volatile("sub $0x4,%rsp");
dump_stack();
asm volatile("add $0x4,%rsp");
return -EAGAIN;
}
module_init(init);
MODULE_LICENSE("GPL");crashes the kernel.
--- arch/x86/kernel/dumpstack.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/x86/kernel/dumpstack.c +5 -2
@@ -195,7 +195,6 @@ static void show_trace_log_lvl(struct taprintk ("%sCall Trace:\n" , log_lvl);unwind_start (&state, task, regs, stack); - stack = stack ? :get_stack_pointer (task, regs); regs =unwind_get_entry_regs (&state, &partial);/*
@@ -214,9 +213,13 @@ static void show_trace_log_lvl(struct ta* - hardirq stack * - entry stack */ -for ( ; stack; stack =PTR_ALIGN (stack_info.next_sp,sizeof (long ))) { +for (stack = stack ?:get_stack_pointer (task, regs); + stack; + stack = stack_info.next_sp) {const char *stack_name; + stack =PTR_ALIGN (stack,sizeof (long )); +if (get_stack_info (stack, task, &stack_info, &visit_mask)) {/* * We weren't on a valid stack. It's possible that
Greg Kroah-Hartman
maintainerPATCH 96/119 ASoC: Intel: Skylake: Fix declaration of enum skl_ch_cfg
In reply to Greg Kroah-HartmanFrom: Cezary Rojewski <[email protected]>
commit 95109657471311601b98e71f03d0244f48dc61bb upstream.
Constant 'C4_CHANNEL' does not exist on the firmware side. Value 0xC is reserved for 'C7_1' instead.
--- include/uapi/sound/skl-tplg-interface.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/uapi/sound/skl-tplg-interface.h +2 -1
@@ -66,7 +66,8 @@ enum skl_ch_cfg {SKL_CH_CFG_DUAL_MONO =9 ,SKL_CH_CFG_I2S_DUAL_STEREO_0 =10 ,SKL_CH_CFG_I2S_DUAL_STEREO_1 =11 , -SKL_CH_CFG_4_CHANNEL =12 , +SKL_CH_CFG_7_1 =12 , +SKL_CH_CFG_4_CHANNEL =SKL_CH_CFG_7_1 , SKL_CH_CFG_INVALID };
Greg Kroah-Hartman
maintainerPATCH 97/119 ASoC: Intel: avs: Fix declaration of enum avs_channel_config
In reply to Greg Kroah-HartmanFrom: Cezary Rojewski <[email protected]>
commit 1cf036deebcdec46d6348842bd2f8931202fd4cd upstream.
Constant 'C4_CHANNEL' does not exist on the firmware side. Value 0xC is reserved for 'C7_1' instead.
--- sound/soc/intel/avs/messages.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/intel/avs/messages.h +1 -1
@@ -611,7 +611,7 @@ enum avs_channel_config {AVS_CHANNEL_CONFIG_DUAL_MONO =9 ,AVS_CHANNEL_CONFIG_I2S_DUAL_STEREO_0 =10 ,AVS_CHANNEL_CONFIG_I2S_DUAL_STEREO_1 =11 , -AVS_CHANNEL_CONFIG_4_CHANNEL =12 , +AVS_CHANNEL_CONFIG_7_1 =12 , AVS_CHANNEL_CONFIG_INVALID };
Greg Kroah-Hartman
maintainerPATCH 98/119 ASoC: Intel: avs: Access path components under lock
In reply to Greg Kroah-HartmanFrom: Amadeusz Sławiński <[email protected]>
commit d849996f7458042af803b7d15a181922834c5249 upstream.
Path and its components should be accessed under lock to prevent problems with one thread modifying them while other tries to read.
--- sound/soc/intel/avs/apl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
sound/soc/intel/avs/apl.c +5 -1
@@ -173,6 +173,7 @@ static bool apl_lp_streaming(struct avs_ {struct avs_path *path; +spin_lock (&adev->path_list_lock);/* Any gateway without buffer allocated in LP area disqualifies D0IX. */ list_for_each_entry (path, &adev->path_list, node) {struct avs_path_pipeline *ppl;
@@ -192,11 +193,14 @@ static bool apl_lp_streaming(struct avs_if (cfg->copier.dma_type ==INVALID_OBJECT_ID )continue ; -if (!mod->gtw_attrs.lp_buffer_alloc) +if (!mod->gtw_attrs.lp_buffer_alloc) { +spin_unlock (&adev->path_list_lock);return false; + } } } } +spin_unlock (&adev->path_list_lock);return true; }
Greg Kroah-Hartman
maintainerPATCH 99/119 cxl: Wait Memory_Info_Valid before access memory related info
In reply to Greg Kroah-HartmanFrom: Dave Jiang <[email protected]>
commit ce17ad0d54985e2595a3e615fda31df61808a08c upstream.
The Memory_Info_Valid bit (CXL 3.0 8.1.3.8.2) indicates that the CXL Range Size High and Size Low registers are valid. The bit must be set within 1 second of reset deassertion to the device. Check valid bit before we check the Memory_Active bit when waiting for cxl_await_media_ready() to ensure that the memory info is valid for consumption. Also ensures both DVSEC ranges 1 and 2 are ready if DVSEC Capability indicates they are both supported.
--- drivers/cxl/core/pci.c | 85 +++++++++++++++++++++++++++++++++++++++++++------ drivers/cxl/cxlpci.h | 2 + 2 files changed, 78 insertions(+), 9 deletions(-)
drivers/cxl/core/pci.c +76 -9
@@ -103,23 +103,57 @@ int devm_cxl_port_enumerate_dports(struc }EXPORT_SYMBOL_NS_GPL (devm_cxl_port_enumerate_dports,CXL ); -/* -* Wait up to @media_ready_timeout for the device to report memory -* active. -*/ -int cxl_await_media_ready (struct cxl_dev_state *cxlds) +static int cxl_dvsec_mem_range_valid (struct cxl_dev_state *cxlds,int id) +{ +struct pci_dev *pdev =to_pci_dev (cxlds->dev); +int d = cxlds->cxl_dvsec; +bool valid = false; +int rc, i; +u32 temp; + +if (id >CXL_DVSEC_RANGE_MAX ) +return -EINVAL ; + +/* Check MEM INFO VALID bit first, give up after 1s */ + i =1 ; +do { + rc =pci_read_config_dword (pdev, + d +CXL_DVSEC_RANGE_SIZE_LOW (id), + &temp); +if (rc) +return rc; + + valid =FIELD_GET (CXL_DVSEC_MEM_INFO_VALID , temp); +if (valid) +break ; +msleep (1000 ); + }while (i--); + +if (!valid) { +dev_err (&pdev->dev, +"Timeout awaiting memory range %d valid after 1s.\n" , + id); +return -ETIMEDOUT ; + } + +return 0 ; +} + +static int cxl_dvsec_mem_range_active (struct cxl_dev_state *cxlds,int id) {struct pci_dev *pdev =to_pci_dev (cxlds->dev);int d = cxlds->cxl_dvsec;bool active = false; -u64 md_status;int rc, i; +u32 temp; -for (i = media_ready_timeout; i; i--) { -u32 temp; +if (id >CXL_DVSEC_RANGE_MAX ) +return -EINVAL ; +/* Check MEM ACTIVE bit, up to 60s timeout by default */ +for (i = media_ready_timeout; i; i--) { rc =pci_read_config_dword ( - pdev, d +CXL_DVSEC_RANGE_SIZE_LOW (0 ), &temp); + pdev, d +CXL_DVSEC_RANGE_SIZE_LOW (id), &temp);if (rc)return rc;
@@ -136,6 +170,39 @@ int cxl_await_media_ready(struct cxl_devreturn -ETIMEDOUT ; } +return 0 ; +} + +/* +* Wait up to @media_ready_timeout for the device to report memory +* active. +*/ +int cxl_await_media_ready (struct cxl_dev_state *cxlds) +{ +struct pci_dev *pdev =to_pci_dev (cxlds->dev); +int d = cxlds->cxl_dvsec; +int rc, i, hdm_count; +u64 md_status; +u16 cap; + + rc =pci_read_config_word (pdev, + d +CXL_DVSEC_CAP_OFFSET , &cap); +if (rc) +return rc; + + hdm_count =FIELD_GET (CXL_DVSEC_HDM_COUNT_MASK , cap); +for (i =0 ; i < hdm_count; i++) { + rc =cxl_dvsec_mem_range_valid (cxlds, i); +if (rc) +return rc; + } + +for (i =0 ; i < hdm_count; i++) { + rc =cxl_dvsec_mem_range_active (cxlds, i); +if (rc) +return rc; + } + md_status =readq (cxlds->regs.memdev +CXLMDEV_STATUS_OFFSET );if (!CXLMDEV_READY (md_status))return -EIO ;
drivers/cxl/cxlpci.h +2 -0
@@ -31,6 +31,8 @@#define CXL_DVSEC_RANGE_BASE_LOW (i) (0x24 + (i * 0x10))#define CXL_DVSEC_MEM_BASE_LOW_MASK GENMASK(31, 28) +#define CXL_DVSEC_RANGE_MAX 2 +/* CXL 2.0 8.1.4: Non-CXL Function Map DVSEC */ #define CXL_DVSEC_FUNCTION_MAP 2
Greg Kroah-Hartman
maintainerPATCH 100/119 sctp: fix an issue that plpmtu can never go to complete state
In reply to Greg Kroah-HartmanFrom: Xin Long <[email protected]>
commit 6ca328e985cd995dfd1d5de44046e6074f853fbb upstream.
When doing plpmtu probe, the probe size is growing every time when it receives the ACK during the Search state until the probe fails. When the failure occurs, pl.probe_high is set and it goes to the Complete state.
However, if the link pmtu is huge, like 65535 in loopback_dev, the probe eventually keeps using SCTP_MAX_PLPMTU as the probe size and never fails. Because of that, pl.probe_high can not be set, and the plpmtu probe can never go to the Complete state.
Fix it by setting pl.probe_high to SCTP_MAX_PLPMTU when the probe size grows to SCTP_MAX_PLPMTU in sctp_transport_pl_recv(). Also, not allow the probe size greater than SCTP_MAX_PLPMTU in the Complete state.
--- net/sctp/transport.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
net/sctp/transport.c +7 -4
@@ -324,9 +324,12 @@ bool sctp_transport_pl_recv(struct sctp_ t->pl.probe_size +=SCTP_PL_BIG_STEP ; }else if (t->pl.state ==SCTP_PL_SEARCH ) {if (!t->pl.probe_high) { - t->pl.probe_size =min (t->pl.probe_size +SCTP_PL_BIG_STEP , -SCTP_MAX_PLPMTU ); -return false; +if (t->pl.probe_size <SCTP_MAX_PLPMTU ) { + t->pl.probe_size =min (t->pl.probe_size +SCTP_PL_BIG_STEP , +SCTP_MAX_PLPMTU ); +return false; + } + t->pl.probe_high =SCTP_MAX_PLPMTU ; } t->pl.probe_size +=SCTP_PL_MIN_STEP ;if (t->pl.probe_size >= t->pl.probe_high) {
@@ -341,7 +344,7 @@ bool sctp_transport_pl_recv(struct sctp_ }else if (t->pl.state ==SCTP_PL_COMPLETE ) {/* Raise probe_size again after 30 * interval in Search Complete */ t->pl.state =SCTP_PL_SEARCH ;/* Search Complete -> Search */ - t->pl.probe_size +=SCTP_PL_MIN_STEP ; + t->pl.probe_size =min (t->pl.probe_size +SCTP_PL_MIN_STEP ,SCTP_MAX_PLPMTU ); }return t->pl.state ==SCTP_PL_COMPLETE ;
Greg Kroah-Hartman
maintainerPATCH 101/119 forcedeth: Fix an error handling path in nv_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
commit 5b17a4971d3b2a073f4078dd65331efbe35baa2d upstream.
If an error occures after calling nv_mgmt_acquire_sema(), it should be undone with a corresponding nv_mgmt_release_sema() call.
Add it in the error handling path of the probe as already done in the remove function.
--- drivers/net/ethernet/nvidia/forcedeth.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/nvidia/forcedeth.c +1 -0
@@ -6138,6 +6138,7 @@ static int nv_probe(struct pci_dev *pci_return 0 ; out_error: +nv_mgmt_release_sema (dev);if (phystate_orig)writel (phystate|NVREG_ADAPTCTL_RUNNING , base + NvRegAdapterControl); out_freering:
Greg Kroah-Hartman
maintainerPATCH 102/119 platform/mellanox: mlxbf-pmc: fix sscanf() error checking
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
commit 95e4b25192e9238fd2dbe85d96dd2f8fd1ce9d14 upstream.
The sscanf() function never returns negatives. It returns the number of items successfully read.
--- drivers/platform/mellanox/mlxbf-pmc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/platform/mellanox/mlxbf-pmc.c +2 -3
@@ -1348,9 +1348,8 @@ static int mlxbf_pmc_map_counters(structfor (i =0 ; i < pmc->total_blocks; ++i) {if (strstr (pmc->block_name[i],"tile" )) { - ret =sscanf (pmc->block_name[i],"tile%d" , &tile_num); -if (ret <0 ) -return ret; +if (sscanf (pmc->block_name[i],"tile%d" , &tile_num) !=1 ) +return -EINVAL ;if (tile_num >= pmc->tile_count)continue ;
Greg Kroah-Hartman
maintainerPATCH 103/119 net/mlx5e: Fix SQ wake logic in ptp napi_poll context
In reply to Greg Kroah-HartmanFrom: Rahul Rameshbabu <[email protected]>
commit 7aa50380191635e5897a773f272829cc961a2be5 upstream.
Check in the mlx5e_ptp_poll_ts_cq context if the ptp tx sq should be woken up. Before change, the ptp tx sq may never wake up if the ptp tx ts skb fifo is full when mlx5e_poll_tx_cq checks if the queue should be woken up.
--- drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c | 2 ++ drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h | 2 ++ drivers/net/ethernet/mellanox/mlx5/core/en_tx.c | 19 ++++++++++++------- 3 files changed, 16 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +2 -0
@@ -175,6 +175,8 @@ static bool mlx5e_ptp_poll_ts_cq(struct/* ensure cq space is freed before enabling more cqes */ wmb (); +mlx5e_txqsq_wake (&ptpsq->txqsq); +return work_done == budget; }
drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +2 -0
@@ -177,6 +177,8 @@ static inline u16 mlx5e_txqsq_get_next_preturn pi; } +void mlx5e_txqsq_wake (struct mlx5e_txqsq *sq); +static inline u16 mlx5e_shampo_get_cqe_header_index (struct mlx5e_rq *rq,struct mlx5_cqe64 *cqe) {return be16_to_cpu (cqe->shampo.header_entry_index) & (rq->mpwqe.shampo->hd_per_wq -1 );
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +12 -7
@@ -777,6 +777,17 @@ static void mlx5e_tx_wi_consume_fifo_skb } } +void mlx5e_txqsq_wake (struct mlx5e_txqsq *sq) +{ +if (netif_tx_queue_stopped (sq->txq) && +mlx5e_wqc_has_room_for (&sq->wq, sq->cc, sq->pc, sq->stop_room) && +mlx5e_ptpsq_fifo_has_room (sq) && + !test_bit (MLX5E_SQ_STATE_RECOVERING , &sq->state)) { +netif_tx_wake_queue (sq->txq); + sq->stats->wake++; + } +} +bool mlx5e_poll_tx_cq (struct mlx5e_cq *cq,int napi_budget) {struct mlx5e_sq_stats *stats;
@@ -876,13 +887,7 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cnetdev_tx_completed_queue (sq->txq, npkts, nbytes); -if (netif_tx_queue_stopped (sq->txq) && -mlx5e_wqc_has_room_for (&sq->wq, sq->cc, sq->pc, sq->stop_room) && -mlx5e_ptpsq_fifo_has_room (sq) && - !test_bit (MLX5E_SQ_STATE_RECOVERING , &sq->state)) { -netif_tx_wake_queue (sq->txq); - stats->wake++; - } +mlx5e_txqsq_wake (sq);return (i ==MLX5E_TX_CQ_POLL_BUDGET ); }
Greg Kroah-Hartman
maintainerPATCH 104/119 net/mlx5e: Fix deadlock in tc route query code
In reply to Greg Kroah-HartmanFrom: Vlad Buslov <[email protected]>
commit 691c041bf20899fc13c793f92ba61ab660fa3a30 upstream.
Cited commit causes ABBA deadlock[0] when peer flows are created while holding the devcom rw semaphore. Due to peer flows offload implementation the lock is taken much higher up the call chain and there is no obvious way to easily fix the deadlock. Instead, since tc route query code needs the peer eswitch structure only to perform a lookup in xarray and doesn't perform any sleeping operations with it, refactor the code for lockless execution in following ways:
- RCUify the devcom 'data' pointer. When resetting the pointer synchronously wait for RCU grace period before returning. This is fine since devcom is currently only used for synchronization of pairing/unpairing of eswitches which is rare and already expensive as-is.
- Wrap all usages of 'paired' boolean in {READ|WRITE}_ONCE(). The flag has already been used in some unlocked contexts without proper annotations (e.g. users of mlx5_devcom_is_paired() function), but it wasn't an issue since all relevant code paths checked it again after obtaining the devcom semaphore. Now it is also used by mlx5_devcom_get_peer_data_rcu() as "best effort" check to return NULL when devcom is being unpaired. Note that while RCU read lock doesn't prevent the unpaired flag from being changed concurrently it still guarantees that reader can continue to use 'data'.
- Refactor mlx5e_tc_query_route_vport() function to use new mlx5_devcom_get_peer_data_rcu() API which fixes the deadlock.
[0]:
[ 164.599612] ======================================================
[ 164.600142] WARNING: possible circular locking dependency detected
[ 164.600667] 6.3.0-rc3+ #1 Not tainted
[ 164.601021] ------------------------------------------------------
[ 164.601557] handler1/3456 is trying to acquire lock:
[ 164.601998] ffff88811f1714b0 (&esw->offloads.encap_tbl_lock){+.+.}-{3:3}, at: mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.603078]
but task is already holding lock:
[ 164.603617] ffff88810137fc98 (&comp->sem){++++}-{3:3}, at: mlx5_devcom_get_peer_data+0x37/0x80 [mlx5_core]
[ 164.604459]
which lock already depends on the new lock.[ 164.605190]
the existing dependency chain (in reverse order) is:
[ 164.605848]
-> #1 (&comp->sem){++++}-{3:3}:
[ 164.606380] down_read+0x39/0x50
[ 164.606772] mlx5_devcom_get_peer_data+0x37/0x80 [mlx5_core]
[ 164.607336] mlx5e_tc_query_route_vport+0x86/0xc0 [mlx5_core]
[ 164.607914] mlx5e_tc_tun_route_lookup+0x1a4/0x1d0 [mlx5_core]
[ 164.608495] mlx5e_attach_decap_route+0xc6/0x1e0 [mlx5_core]
[ 164.609063] mlx5e_tc_add_fdb_flow+0x1ea/0x360 [mlx5_core]
[ 164.609627] __mlx5e_add_fdb_flow+0x2d2/0x430 [mlx5_core]
[ 164.610175] mlx5e_configure_flower+0x952/0x1a20 [mlx5_core]
[ 164.610741] tc_setup_cb_add+0xd4/0x200
[ 164.611146] fl_hw_replace_filter+0x14c/0x1f0 [cls_flower]
[ 164.611661] fl_change+0xc95/0x18a0 [cls_flower]
[ 164.612116] tc_new_tfilter+0x3fc/0xd20
[ 164.612516] rtnetlink_rcv_msg+0x418/0x5b0
[ 164.612936] netlink_rcv_skb+0x54/0x100
[ 164.613339] netlink_unicast+0x190/0x250
[ 164.613746] netlink_sendmsg+0x245/0x4a0
[ 164.614150] sock_sendmsg+0x38/0x60
[ 164.614522] ____sys_sendmsg+0x1d0/0x1e0
[ 164.614934] ___sys_sendmsg+0x80/0xc0
[ 164.615320] __sys_sendmsg+0x51/0x90
[ 164.615701] do_syscall_64+0x3d/0x90
[ 164.616083] entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 164.616568]
-> #0 (&esw->offloads.encap_tbl_lock){+.+.}-{3:3}:
[ 164.617210] __lock_acquire+0x159e/0x26e0
[ 164.617638] lock_acquire+0xc2/0x2a0
[ 164.618018] __mutex_lock+0x92/0xcd0
[ 164.618401] mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.618943] post_process_attr+0x153/0x2d0 [mlx5_core]
[ 164.619471] mlx5e_tc_add_fdb_flow+0x164/0x360 [mlx5_core]
[ 164.620021] __mlx5e_add_fdb_flow+0x2d2/0x430 [mlx5_core]
[ 164.620564] mlx5e_configure_flower+0xe33/0x1a20 [mlx5_core]
[ 164.621125] tc_setup_cb_add+0xd4/0x200
[ 164.621531] fl_hw_replace_filter+0x14c/0x1f0 [cls_flower]
[ 164.622047] fl_change+0xc95/0x18a0 [cls_flower]
[ 164.622500] tc_new_tfilter+0x3fc/0xd20
[ 164.622906] rtnetlink_rcv_msg+0x418/0x5b0
[ 164.623324] netlink_rcv_skb+0x54/0x100
[ 164.623727] netlink_unicast+0x190/0x250
[ 164.624138] netlink_sendmsg+0x245/0x4a0
[ 164.624544] sock_sendmsg+0x38/0x60
[ 164.624919] ____sys_sendmsg+0x1d0/0x1e0
[ 164.625340] ___sys_sendmsg+0x80/0xc0
[ 164.625731] __sys_sendmsg+0x51/0x90
[ 164.626117] do_syscall_64+0x3d/0x90
[ 164.626502] entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 164.626995]
other info that might help us debug this:[ 164.627725] Possible unsafe locking scenario:
[ 164.628268] CPU0 CPU1
[ 164.628683] ---- ----
[ 164.629098] lock(&comp->sem);
[ 164.629421] lock(&esw->offloads.encap_tbl_lock);
[ 164.630066] lock(&comp->sem);
[ 164.630555] lock(&esw->offloads.encap_tbl_lock);
[ 164.630993]
*** DEADLOCK ***[ 164.631575] 3 locks held by handler1/3456:
[ 164.631962] #0: ffff888124b75130 (&block->cb_lock){++++}-{3:3}, at: tc_setup_cb_add+0x5b/0x200
[ 164.632703] #1: ffff888116e512b8 (&esw->mode_lock){++++}-{3:3}, at: mlx5_esw_hold+0x39/0x50 [mlx5_core]
[ 164.633552] #2: ffff88810137fc98 (&comp->sem){++++}-{3:3}, at: mlx5_devcom_get_peer_data+0x37/0x80 [mlx5_core]
[ 164.634435]
stack backtrace:
[ 164.634883] CPU: 17 PID: 3456 Comm: handler1 Not tainted 6.3.0-rc3+ #1
[ 164.635431] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
[ 164.636340] Call Trace:
[ 164.636616] <TASK>
[ 164.636863] dump_stack_lvl+0x47/0x70
[ 164.637217] check_noncircular+0xfe/0x110
[ 164.637601] __lock_acquire+0x159e/0x26e0
[ 164.637977] ? mlx5_cmd_set_fte+0x5b0/0x830 [mlx5_core]
[ 164.638472] lock_acquire+0xc2/0x2a0
[ 164.638828] ? mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.639339] ? lock_is_held_type+0x98/0x110
[ 164.639728] __mutex_lock+0x92/0xcd0
[ 164.640074] ? mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.640576] ? __lock_acquire+0x382/0x26e0
[ 164.640958] ? mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.641468] ? mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.641965] mlx5e_attach_encap+0xd8/0x8b0 [mlx5_core]
[ 164.642454] ? lock_release+0xbf/0x240
[ 164.642819] post_process_attr+0x153/0x2d0 [mlx5_core]
[ 164.643318] mlx5e_tc_add_fdb_flow+0x164/0x360 [mlx5_core]
[ 164.643835] __mlx5e_add_fdb_flow+0x2d2/0x430 [mlx5_core]
[ 164.644340] mlx5e_configure_flower+0xe33/0x1a20 [mlx5_core]
[ 164.644862] ? lock_acquire+0xc2/0x2a0
[ 164.645219] tc_setup_cb_add+0xd4/0x200
[ 164.645588] fl_hw_replace_filter+0x14c/0x1f0 [cls_flower]
[ 164.646067] fl_change+0xc95/0x18a0 [cls_flower]
[ 164.646488] tc_new_tfilter+0x3fc/0xd20
[ 164.646861] ? tc_del_tfilter+0x810/0x810
[ 164.647236] rtnetlink_rcv_msg+0x418/0x5b0
[ 164.647621] ? rtnl_setlink+0x160/0x160
[ 164.647982] netlink_rcv_skb+0x54/0x100
[ 164.648348] netlink_unicast+0x190/0x250
[ 164.648722] netlink_sendmsg+0x245/0x4a0
[ 164.649090] sock_sendmsg+0x38/0x60
[ 164.649434] ____sys_sendmsg+0x1d0/0x1e0
[ 164.649804] ? copy_msghdr_from_user+0x6d/0xa0
[ 164.650213] ___sys_sendmsg+0x80/0xc0
[ 164.650563] ? lock_acquire+0xc2/0x2a0
[ 164.650926] ? lock_acquire+0xc2/0x2a0
[ 164.651286] ? __fget_files+0x5/0x190
[ 164.651644] ? find_held_lock+0x2b/0x80
[ 164.652006] ? __fget_files+0xb9/0x190
[ 164.652365] ? lock_release+0xbf/0x240
[ 164.652723] ? __fget_files+0xd3/0x190
[ 164.653079] __sys_sendmsg+0x51/0x90
[ 164.653435] do_syscall_64+0x3d/0x90
[ 164.653784] entry_SYSCALL_64_after_hwframe+0x46/0xb0
[ 164.654229] RIP: 0033:0x7f378054f8bd
[ 164.654577] Code: 28 89 54 24 1c 48 89 74 24 10 89 7c 24 08 e8 6a c3 f4 ff 8b 54 24 1c 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 33 44 89 c7 48 89 44 24 08 e8 be c3 f4 ff 48
[ 164.656041] RSP: 002b:00007f377fa114b0 EFLAGS: 00000293 ORIG_RAX: 000000000000002e
[ 164.656701] RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f378054f8bd
[ 164.657297] RDX: 0000000000000000 RSI: 00007f377fa11540 RDI: 0000000000000014
[ 164.657885] RBP: 00007f377fa12278 R08: 0000000000000000 R09: 000000000000015c
[ 164.658472] R10: 00007f377fa123d0 R11: 0000000000000293 R12: 0000560962d99bd0
[ 164.665317] R13: 0000000000000000 R14: 0000560962d99bd0 R15: 00007f377fa11540--- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 19 +++---- drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c | 48 ++++++++++++++----- drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h | 1 3 files changed, 48 insertions(+), 20 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +10 -9
@@ -1578,11 +1578,9 @@ bool mlx5e_tc_is_vf_tunnel(struct net_deint mlx5e_tc_query_route_vport (struct net_device *out_dev,struct net_device *route_dev,u16 *vport) {struct mlx5e_priv *out_priv, *route_priv; -struct mlx5_devcom *devcom =NULL ;struct mlx5_core_dev *route_mdev;struct mlx5_eswitch *esw;u16 vhca_id; -int err; out_priv =netdev_priv (out_dev); esw = out_priv->mdev->priv.eswitch;
@@ -1591,6 +1589,9 @@ int mlx5e_tc_query_route_vport(struct ne vhca_id =MLX5_CAP_GEN (route_mdev, vhca_id);if (mlx5_lag_is_active (out_priv->mdev)) { +struct mlx5_devcom *devcom; +int err; +/* In lag case we may get devices from different eswitch instances. * If we failed to get vport num, it means, mostly, that we on the wrong * eswitch.
@@ -1599,16 +1600,16 @@ int mlx5e_tc_query_route_vport(struct neif (err != -ENOENT )return err; +rcu_read_lock (); devcom = out_priv->mdev->priv.devcom; - esw =mlx5_devcom_get_peer_data (devcom,MLX5_DEVCOM_ESW_OFFLOADS ); -if (!esw) -return -ENODEV ; + esw =mlx5_devcom_get_peer_data_rcu (devcom,MLX5_DEVCOM_ESW_OFFLOADS ); + err = esw ?mlx5_eswitch_vhca_id_to_vport (esw, vhca_id, vport) : -ENODEV ; +rcu_read_unlock (); + +return err; } - err =mlx5_eswitch_vhca_id_to_vport (esw, vhca_id, vport); -if (devcom) -mlx5_devcom_release_peer_data (devcom,MLX5_DEVCOM_ESW_OFFLOADS ); -return err; +return mlx5_eswitch_vhca_id_to_vport (esw, vhca_id, vport); } int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv,
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +37 -11
99 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h +1 -0
@@ -41,6 +41,7 @@ bool mlx5_devcom_is_paired(struct mlx5_dvoid *mlx5_devcom_get_peer_data (struct mlx5_devcom *devcom,enum mlx5_devcom_components id); +void *mlx5_devcom_get_peer_data_rcu (struct mlx5_devcom *devcom,enum mlx5_devcom_components id);void mlx5_devcom_release_peer_data (struct mlx5_devcom *devcom,enum mlx5_devcom_components id);
Greg Kroah-Hartman
maintainerPATCH 105/119 net/mlx5e: Use correct encap attribute during invalidation
In reply to Greg Kroah-HartmanFrom: Vlad Buslov <[email protected]>
commit be071cdb167fc3e25fe81922166b3d499d23e8ac upstream.
With introduction of post action infrastructure most of the users of encap attribute had been modified in order to obtain the correct attribute by calling mlx5e_tc_get_encap_attr() helper instead of assuming encap action is always on default attribute. However, the cited commit didn't modify mlx5e_invalidate_encap() which prevents it from destroying correct modify header action which leads to a warning [0]. Fix the issue by using correct attribute.
[0]:
Feb 21 09:47:35 c-237-177-40-045 kernel: WARNING: CPU: 17 PID: 654 at drivers/net/ethernet/mellanox/mlx5/core/en_tc.c:684 mlx5e_tc_attach_mod_hdr+0x1cc/0x230 [mlx5_core] Feb 21 09:47:35 c-237-177-40-045 kernel: RIP: 0010:mlx5e_tc_attach_mod_hdr+0x1cc/0x230 [mlx5_core] Feb 21 09:47:35 c-237-177-40-045 kernel: Call Trace: Feb 21 09:47:35 c-237-177-40-045 kernel: <TASK> Feb 21 09:47:35 c-237-177-40-045 kernel: mlx5e_tc_fib_event_work+0x8e3/0x1f60 [mlx5_core] Feb 21 09:47:35 c-237-177-40-045 kernel: ? mlx5e_take_all_encap_flows+0xe0/0xe0 [mlx5_core] Feb 21 09:47:35 c-237-177-40-045 kernel: ? lock_downgrade+0x6d0/0x6d0 Feb 21 09:47:35 c-237-177-40-045 kernel: ? lockdep_hardirqs_on_prepare+0x273/0x3f0 Feb 21 09:47:35 c-237-177-40-045 kernel: ? lockdep_hardirqs_on_prepare+0x273/0x3f0 Feb 21 09:47:35 c-237-177-40-045 kernel: process_one_work+0x7c2/0x1310 Feb 21 09:47:35 c-237-177-40-045 kernel: ? lockdep_hardirqs_on_prepare+0x3f0/0x3f0 Feb 21 09:47:35 c-237-177-40-045 kernel: ? pwq_dec_nr_in_flight+0x230/0x230 Feb 21 09:47:35 c-237-177-40-045 kernel: ? rwlock_bug.part.0+0x90/0x90 Feb 21 09:47:35 c-237-177-40-045 kernel: worker_thread+0x59d/0xec0 Feb 21 09:47:35 c-237-177-40-045 kernel: ? __kthread_parkme+0xd9/0x1d0
--- drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +3 -1
@@ -1338,11 +1338,13 @@ static void mlx5e_invalidate_encap(strucstruct mlx5e_tc_flow *flow;list_for_each_entry (flow, encap_flows, tmp_list) { -struct mlx5_flow_attr *attr = flow->attr;struct mlx5_esw_flow_attr *esw_attr; +struct mlx5_flow_attr *attr;if (!mlx5e_is_offloaded_flow (flow))continue ; + + attr =mlx5e_tc_get_encap_attr (flow); esw_attr = attr->esw_attr;if (flow_flag_test (flow,SLOW ))
Greg Kroah-Hartman
maintainerPATCH 106/119 net/mlx5e: do as little as possible in napi poll when budget is 0
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
commit afbed3f74830163f9559579dee382cac3cff82da upstream.
NAPI gets called with budget of 0 from netpoll, which has interrupts disabled. We should try to free some space on Tx rings and nothing else.
Specifically do not try to handle XDP TX or try to refill Rx buffers - we can't use the page pool from IRQ context. Don't check if IRQs moved, either, that makes no sense in netpoll. Netpoll calls _all_ the rings from whatever CPU it happens to be invoked on.
In general do as little as possible, the work quickly adds up when there's tens of rings to poll.
The immediate stack trace I was seeing is:
__do_softirq+0xd1/0x2c0
__local_bh_enable_ip+0xc7/0x120
</IRQ>
<TASK>
page_pool_put_defragged_page+0x267/0x320
mlx5e_free_xdpsq_desc+0x99/0xd0
mlx5e_poll_xdpsq_cq+0x138/0x3b0
mlx5e_napi_poll+0xc3/0x8b0
netpoll_poll_dev+0xce/0x150AFAIU page pool takes a BH lock, releases it and since BH is now enabled tries to run softirqs.
--- drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c +9 -7
@@ -161,20 +161,22 @@ int mlx5e_napi_poll(struct napi_struct * } } +/* budget=0 means we may be in IRQ context, do as little as possible */ +if (unlikely (!budget)) + goto out; + busy |=mlx5e_poll_xdpsq_cq (&c->xdpsq.cq);if (c->xdp) busy |=mlx5e_poll_xdpsq_cq (&c->rq_xdpsq.cq); -if (likely (budget)) {/* budget=0 means: don't poll rx rings */ -if (xsk_open) - work_done =mlx5e_poll_rx_cq (&xskrq->cq, budget); +if (xsk_open) + work_done =mlx5e_poll_rx_cq (&xskrq->cq, budget); -if (likely (budget - work_done)) - work_done +=mlx5e_poll_rx_cq (&rq->cq, budget - work_done); +if (likely (budget - work_done)) + work_done +=mlx5e_poll_rx_cq (&rq->cq, budget - work_done); - busy |= work_done == budget; - } + busy |= work_done == budget;mlx5e_poll_ico_cq (&c->icosq.cq);if (mlx5e_poll_ico_cq (&c->async_icosq.cq))
Greg Kroah-Hartman
maintainerPATCH 107/119 net/mlx5: DR, Fix crc32 calculation to work on big-endian (BE) CPUs
In reply to Greg Kroah-HartmanFrom: Erez Shitrit <[email protected]>
commit 1e5daf5565b61a96e570865091589afc9156e3d3 upstream.
When calculating crc for hash index we use the function crc32 that calculates for little-endian (LE) arch.
Then we convert it to network endianness using htonl(), but it's wrong to do the conversion in BE archs since the crc32 value is already LE.
The solution is to switch the bytes from the crc result for all types of arc.
--- drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c +2 -1
@@ -15,7 +15,8 @@ static u32 dr_ste_crc32_calc(const void {u32 crc =crc32 (0 , input_data, length); -return (__force u32 )htonl (crc); +return (__force u32)((crc >>24 ) &0xff ) | ((crc <<8 ) &0xff0000 ) | + ((crc >>8 ) &0xff00 ) | ((crc <<24 ) &0xff000000 ); }bool mlx5dr_ste_supp_ttl_cs_recalc (struct mlx5dr_cmd_caps *caps)
Greg Kroah-Hartman
maintainerPATCH 108/119 net/mlx5: Handle pairing of E-switch via uplink un/load APIs
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
commit 2be5bd42a5bba1a05daedc86cf0e248210009669 upstream.
In case user switch a device from switchdev mode to legacy mode, mlx5 first unpair the E-switch and afterwards unload the uplink vport.
Quoted 1 line
From the other hand, in case user remove or reload a device, mlx5
first unload the uplink vport and afterwards unpair the E-switch.
The latter is causing a bug[1], hence, handle pairing of E-switch as part of uplink un/load APIs.
[1]
In case VF_LAG is used, every tc fdb flow is duplicated to the peer esw. However, the original esw keeps a pointer to this duplicated flow, not the peer esw.
e.g.: if user create tc fdb flow over esw0, the flow is duplicated over esw1, in FW/HW, but in SW, esw0 keeps a pointer to the duplicated flow.
During module unload while a peer tc fdb flow is still offloaded, in case the first device to be removed is the peer device (esw1 in the example above), the peer net-dev is destroyed, and so the mlx5e_priv is memset to 0.
Afterwards, the peer device is trying to unpair himself from the original device (esw0 in the example above). Unpair API invoke the original device to clear peer flow from its eswitch (esw0), but the peer flow, which is stored over the original eswitch (esw0), is trying to use the peer mlx5e_priv, which is memset to 0 and result in bellow kernel-oops.
[ 157.964081 ] BUG: unable to handle page fault for address: 000000000002ce60 [ 157.964662 ] #PF: supervisor read access in kernel mode [ 157.965123 ] #PF: error_code(0x0000) - not-present page [ 157.965582 ] PGD 0 P4D 0 [ 157.965866 ] Oops: 0000 [#1] SMP [ 157.967670 ] RIP: 0010:mlx5e_tc_del_fdb_flow+0x48/0x460 [mlx5_core] [ 157.976164 ] Call Trace: [ 157.976437 ] <TASK> [ 157.976690 ] __mlx5e_tc_del_fdb_peer_flow+0xe6/0x100 [mlx5_core] [ 157.977230 ] mlx5e_tc_clean_fdb_peer_flows+0x67/0x90 [mlx5_core] [ 157.977767 ] mlx5_esw_offloads_unpair+0x2d/0x1e0 [mlx5_core] [ 157.984653 ] mlx5_esw_offloads_devcom_event+0xbf/0x130 [mlx5_core] [ 157.985212 ] mlx5_devcom_send_event+0xa3/0xb0 [mlx5_core] [ 157.985714 ] esw_offloads_disable+0x5a/0x110 [mlx5_core] [ 157.986209 ] mlx5_eswitch_disable_locked+0x152/0x170 [mlx5_core] [ 157.986757 ] mlx5_eswitch_disable+0x51/0x80 [mlx5_core] [ 157.987248 ] mlx5_unload+0x2a/0xb0 [mlx5_core] [ 157.987678 ] mlx5_uninit_one+0x5f/0xd0 [mlx5_core] [ 157.988127 ] remove_one+0x64/0xe0 [mlx5_core] [ 157.988549 ] pci_device_remove+0x31/0xa0 [ 157.988933 ] device_release_driver_internal+0x18f/0x1f0 [ 157.989402 ] driver_detach+0x3f/0x80 [ 157.989754 ] bus_remove_driver+0x70/0xf0 [ 157.990129 ] pci_unregister_driver+0x34/0x90 [ 157.990537 ] mlx5_cleanup+0xc/0x1c [mlx5_core] [ 157.990972 ] __x64_sys_delete_module+0x15a/0x250 [ 157.991398 ] ? exit_to_user_mode_prepare+0xea/0x110 [ 157.991840 ] do_syscall_64+0x3d/0x90 [ 157.992198 ] entry_SYSCALL_64_after_hwframe+0x46/0xb0
--- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 4 +++- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 4 ++++ drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 7 ++----- 3 files changed, 9 insertions(+), 6 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +3 -1
@@ -5143,6 +5143,8 @@ int mlx5e_tc_esw_init(struct mlx5_rep_up goto err_register_fib_notifier; } +mlx5_esw_offloads_devcom_init (esw); +return 0 ; err_register_fib_notifier:
@@ -5169,7 +5171,7 @@ void mlx5e_tc_esw_cleanup(struct mlx5_re priv =netdev_priv (rpriv->netdev); esw = priv->mdev->priv.eswitch; -mlx5e_tc_clean_fdb_peer_flows (esw); +mlx5_esw_offloads_devcom_cleanup (esw);mlx5e_tc_tun_cleanup (uplink_priv->encap);
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +4 -0
@@ -368,6 +368,8 @@ int mlx5_eswitch_enable(struct mlx5_eswivoid mlx5_eswitch_disable_sriov (struct mlx5_eswitch *esw,bool clear_vf);void mlx5_eswitch_disable_locked (struct mlx5_eswitch *esw);void mlx5_eswitch_disable (struct mlx5_eswitch *esw); +void mlx5_esw_offloads_devcom_init (struct mlx5_eswitch *esw); +void mlx5_esw_offloads_devcom_cleanup (struct mlx5_eswitch *esw);int mlx5_eswitch_set_vport_mac (struct mlx5_eswitch *esw,u16 vport,const u8 *mac); int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
@@ -757,6 +759,8 @@ static inline void mlx5_eswitch_cleanup(static inline int mlx5_eswitch_enable (struct mlx5_eswitch *esw,int num_vfs) {return 0 ; }static inline void mlx5_eswitch_disable_sriov (struct mlx5_eswitch *esw,bool clear_vf) {}static inline void mlx5_eswitch_disable (struct mlx5_eswitch *esw) {} +static inline void mlx5_esw_offloads_devcom_init (struct mlx5_eswitch *esw) {} +static inline void mlx5_esw_offloads_devcom_cleanup (struct mlx5_eswitch *esw) {}static inline bool mlx5_eswitch_is_funcs_handler (struct mlx5_core_dev *dev) {return false; }static inline int mlx5_eswitch_set_vport_state (struct mlx5_eswitch *esw,u16 vport,int link_state) {return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +2 -5
@@ -2864,7 +2864,7 @@ err_out:return err; } -static void esw_offloads_devcom_init (struct mlx5_eswitch *esw) +void mlx5_esw_offloads_devcom_init (struct mlx5_eswitch *esw) {struct mlx5_devcom *devcom = esw->dev->priv.devcom;
@@ -2887,7 +2887,7 @@ static void esw_offloads_devcom_init(str ESW_OFFLOADS_DEVCOM_PAIR, esw); } -static void esw_offloads_devcom_cleanup (struct mlx5_eswitch *esw) +void mlx5_esw_offloads_devcom_cleanup (struct mlx5_eswitch *esw) {struct mlx5_devcom *devcom = esw->dev->priv.devcom;
@@ -3357,8 +3357,6 @@ int esw_offloads_enable(struct mlx5_eswiif (err) goto err_vports; -esw_offloads_devcom_init (esw); -return 0 ; err_vports:
@@ -3399,7 +3397,6 @@ static int esw_offloads_stop(struct mlx5void esw_offloads_disable (struct mlx5_eswitch *esw) { -esw_offloads_devcom_cleanup (esw);mlx5_eswitch_disable_pf_vf_vports (esw);esw_offloads_unload_rep (esw,MLX5_VPORT_UPLINK );esw_set_passing_vport_metadata (esw, false);
Greg Kroah-Hartman
maintainerPATCH 109/119 net/mlx5: DR, Check force-loopback RC QP capability independently from RoCE
In reply to Greg Kroah-HartmanFrom: Yevgeny Kliteynik <[email protected]>
commit c7dd225bc224726c22db08e680bf787f60ebdee3 upstream.
SW Steering uses RC QP for writing STEs to ICM. This writingis done in LB (loopback), and FL (force-loopback) QP is preferred for performance. FL is available when RoCE is enabled or disabled based on RoCE caps. This patch adds reading of FL capability from HCA caps in addition to the existing reading from RoCE caps, thus fixing the case where we didn't have loopback enabled when RoCE was disabled.
--- drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c | 4 +++- include/linux/mlx5/mlx5_ifc.h | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c +3 -1
@@ -117,6 +117,8 @@ int mlx5dr_cmd_query_device(struct mlx5_ caps->gvmi =MLX5_CAP_GEN (mdev, vhca_id); caps->flex_protocols =MLX5_CAP_GEN (mdev, flex_parser_protocols); caps->sw_format_ver =MLX5_CAP_GEN (mdev, steering_format_version); + caps->roce_caps.fl_rc_qp_when_roce_disabled = +MLX5_CAP_GEN (mdev, fl_rc_qp_when_roce_disabled);if (MLX5_CAP_GEN (mdev, roce)) { err =dr_cmd_query_nic_vport_roce_en (mdev,0 , &roce_en);
@@ -124,7 +126,7 @@ int mlx5dr_cmd_query_device(struct mlx5_return err; caps->roce_caps.roce_en = roce_en; - caps->roce_caps.fl_rc_qp_when_roce_disabled = + caps->roce_caps.fl_rc_qp_when_roce_disabled |=MLX5_CAP_ROCE (mdev, fl_rc_qp_when_roce_disabled); caps->roce_caps.fl_rc_qp_when_roce_enabled =MLX5_CAP_ROCE (mdev, fl_rc_qp_when_roce_enabled);
include/linux/mlx5/mlx5_ifc.h +3 -1
@@ -1639,7 +1639,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {u8 rc[0x1 ];u8 uar_4k[0x1 ]; -u8 reserved_at_241[0x9 ]; +u8 reserved_at_241[0x7 ]; +u8 fl_rc_qp_when_roce_disabled[0x1 ]; +u8 regexp_params[0x1 ];u8 uar_sz[0x6 ];u8 port_selection_cap[0x1 ];u8 reserved_at_248[0x1 ];
Greg Kroah-Hartman
maintainerPATCH 110/119 net/mlx5: Fix error message when failing to allocate device memory
In reply to Greg Kroah-HartmanFrom: Roi Dayan <[email protected]>
commit a65735148e0328f80c0f72f9f8d2f609bfcf4aff upstream.
Fix spacing for the error and also the correct error code pointer.
--- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +1 -1
@@ -1024,7 +1024,7 @@ static int mlx5_init_once(struct mlx5_co dev->dm =mlx5_dm_create (dev);if (IS_ERR (dev->dm)) -mlx5_core_warn (dev,"Failed to init device memory%d\n" , err); +mlx5_core_warn (dev,"Failed to init device memory %ld\n" ,PTR_ERR (dev->dm)); dev->tracer =mlx5_fw_tracer_create (dev); dev->hv_vhca =mlx5_hv_vhca_create (dev);
Greg Kroah-Hartman
maintainerPATCH 111/119 net/mlx5: Collect command failures data only for known commands
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
commit 2a0a935fb64ee8af253b9c6133bb6702fb152ac2 upstream.
DEVX can issue a general command, which is not used by mlx5 driver. In case such command is failed, mlx5 is trying to collect the failure data, However, mlx5 doesn't create a storage for this command, since mlx5 doesn't use it. This lead to array-index-out-of-bounds error.
Fix it by checking whether the command is known before collecting the failure data.
--- drivers/net/ethernet/mellanox/mlx5/core/cmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/cmd.c +2 -1
@@ -1894,9 +1894,10 @@ static void mlx5_cmd_err_trace(struct mlstatic void cmd_status_log (struct mlx5_core_dev *dev,u16 opcode,u8 status,u32 syndrome,int err) { +const char *namep =mlx5_command_str (opcode);struct mlx5_cmd_stats *stats; -if (!err) +if (!err || !(strcmp (namep,"unknown command opcode" )))return ; stats = &dev->cmd.stats[opcode];
Greg Kroah-Hartman
maintainerPATCH 112/119 net/mlx5: Devcom, fix error flow in mlx5_devcom_register_device
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
commit af87194352cad882d787d06fb7efa714acd95427 upstream.
In case devcom allocation is failed, mlx5 is always freeing the priv. However, this priv might have been allocated by a different thread, and freeing it might lead to use-after-free bugs.
Fix it by freeing the priv only in case it was allocated by the running thread.
--- drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +2 -1
@@ -112,7 +112,8 @@ struct mlx5_devcom *mlx5_devcom_register priv->devs[idx] = dev; devcom =mlx5_devcom_alloc (priv, idx);if (!devcom) { -kfree (priv); +if (new_priv) +kfree (priv);return ERR_PTR (-ENOMEM ); }
Greg Kroah-Hartman
maintainerPATCH 113/119 net/mlx5: Devcom, serialize devcom registration
In reply to Greg Kroah-HartmanFrom: Shay Drory <[email protected]>
commit 1f893f57a3bf9fe1f4bcb25b55aea7f7f9712fe7 upstream.
Quoted 2 lines
From one hand, mlx5 driver is allowing to probe PFs in parallel. From the other hand, devcom, which is a share resource between PFs, is
registered without any lock. This might resulted in memory problems.
Hence, use the global mlx5_dev_list_lock in order to serialize devcom registration.
--- drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +14 -5
@@ -3,6 +3,7 @@#include <linux/mlx5/vport.h> #include "lib/devcom.h" +#include "mlx5_core.h" static LIST_HEAD (devcom_list);
@@ -77,6 +78,7 @@ struct mlx5_devcom *mlx5_devcom_registerif (MLX5_CAP_GEN (dev, num_lag_ports) !=MLX5_DEVCOM_PORTS_SUPPORTED )return NULL ; +mlx5_dev_list_lock (); sguid0 =mlx5_query_nic_system_image_guid (dev);list_for_each_entry (iter, &devcom_list, list) {struct mlx5_core_dev *tmp_dev =NULL ;
@@ -102,8 +104,10 @@ struct mlx5_devcom *mlx5_devcom_registerif (!priv) { priv =mlx5_devcom_list_alloc (); -if (!priv) -return ERR_PTR (-ENOMEM ); +if (!priv) { + devcom =ERR_PTR (-ENOMEM ); + goto out; + } idx =0 ; new_priv = true;
@@ -114,12 +118,14 @@ struct mlx5_devcom *mlx5_devcom_registerif (!devcom) {if (new_priv)kfree (priv); -return ERR_PTR (-ENOMEM ); + devcom =ERR_PTR (-ENOMEM ); + goto out; }if (new_priv)list_add (&priv->list, &devcom_list); - +out: +mlx5_dev_list_unlock ();return devcom; }
@@ -132,6 +138,7 @@ void mlx5_devcom_unregister_device(strucif (IS_ERR_OR_NULL (devcom))return ; +mlx5_dev_list_lock (); priv = devcom->priv; priv->devs[devcom->idx] =NULL ;
@@ -142,10 +149,12 @@ void mlx5_devcom_unregister_device(strucbreak ;if (i !=MLX5_DEVCOM_PORTS_SUPPORTED ) -return ; + goto out;list_del (&priv->list);kfree (priv); +out: +mlx5_dev_list_unlock (); } void mlx5_devcom_register_component(struct mlx5_devcom *devcom,
Greg Kroah-Hartman
maintainerPATCH 114/119 arm64: dts: imx8mn-var-som: fix PHY detection bug by adding deassert delay
In reply to Greg Kroah-HartmanFrom: Hugo Villeneuve <[email protected]>
commit f161cea5a20f3aeeb637a88ad1705fc2720b4d58 upstream.
While testing the ethernet interface on a Variscite symphony carrier board using an imx8mn SOM with an onboard ADIN1300 PHY (EC hardware configuration), the ethernet PHY is not detected.
The ADIN1300 datasheet indicate that the "Management interface active (t4)" state is reached at most 5ms after the reset signal is deasserted.
The device tree in Variscite custom git repository uses the following property:
phy-reset-post-delay = <20>;
Add a new MDIO property 'reset-deassert-us' of 20ms to have the same delay inside the ethphy node. Adding this property fixes the problem with the PHY detection.
Note that this SOM can also have an Atheros AR8033 PHY. In this case, a 1ms deassert delay is sufficient. Add a comment to that effect.
--- arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mn-var-som.dtsi +7 -1
@@ -98,11 +98,17 @@ #address-cells = <1>; #size-cells = <0>; - ethphy: ethernet-phy@4 { + ethphy: ethernet-phy@4 { /* AR8033 or ADIN1300 */ compatible = "ethernet-phy-ieee802.3-c22"; reg = <4>; reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; reset-assert-us = <10000>; + /* + * Deassert delay: + * ADIN1300 requires 5ms. + * AR8033 requires 1ms. + */ + reset-deassert-us = <20000>; }; }; };
Greg Kroah-Hartman
maintainerPATCH 115/119 firmware: arm_ffa: Set reserved/MBZ fields to zero in the memory descriptors
In reply to Greg Kroah-HartmanFrom: Sudeep Holla <[email protected]>
commit 111a833dc5cbef3d05b2a796a7e23cb7f6ff2192 upstream.
The transmit buffers allocated by the driver can be used to transmit data by any messages/commands needing the buffer. However, it is not guaranteed to have been zero-ed before every new transmission and hence it will just contain residual value from the previous transmission. There are several reserved fields in the memory descriptors that must be zero(MBZ). The receiver can reject the transmission if any such MBZ fields are non-zero.
While we can set the whole page to zero, it is not optimal as most of the fields get initialised to the value required for the current transmission.
So, just set the reserved/MBZ fields to zero in the memory descriptors explicitly to honour the requirement and keep the receiver happy.
--- drivers/firmware/arm_ffa/driver.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/firmware/arm_ffa/driver.c +6 -0
@@ -501,12 +501,17 @@ ffa_setup_and_transmit(u32 func_id, void ep_mem_access->receiver = args->attrs[idx].receiver; ep_mem_access->attrs = args->attrs[idx].attrs; ep_mem_access->composite_off =COMPOSITE_OFFSET (args->nattrs); + ep_mem_access->flag =0 ; + ep_mem_access->reserved =0 ; } + mem_region->reserved_0 =0 ; + mem_region->reserved_1 =0 ; mem_region->ep_count = args->nattrs; composite = buffer +COMPOSITE_OFFSET (args->nattrs); composite->total_pg_cnt =ffa_get_num_pages_sg (args->sg); composite->addr_range_cnt = num_entries; + composite->reserved =0 ; length =COMPOSITE_CONSTITUENTS_OFFSET (args->nattrs, num_entries); frag_len =COMPOSITE_CONSTITUENTS_OFFSET (args->nattrs,0 );
@@ -541,6 +546,7 @@ ffa_setup_and_transmit(u32 func_id, void constituents->address =sg_phys (args->sg); constituents->pg_cnt = args->sg->length /FFA_PAGE_SIZE ; + constituents->reserved =0 ; constituents++; frag_len +=sizeof (struct ffa_mem_region_addr_range ); }while ((args->sg =sg_next (args->sg)));
Greg Kroah-Hartman
maintainerPATCH 116/119 regulator: mt6359: add read check for PMIC MT6359
In reply to Greg Kroah-HartmanFrom: Sen Chu <[email protected]>
commit a511637502b1caa135046d0f8fdabd55a31af8ef upstream.
Add hardware version read check for PMIC MT6359
--- drivers/regulator/mt6359-regulator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/regulator/mt6359-regulator.c +5 -2
@@ -951,9 +951,12 @@ static int mt6359_regulator_probe(structstruct regulator_config config = {};struct regulator_dev *rdev;struct mt6359_regulator_info *mt6359_info; -int i, hw_ver; +int i, hw_ver, ret; + + ret =regmap_read (mt6397->regmap,MT6359P_HWCID , &hw_ver); +if (ret) +return ret; -regmap_read (mt6397->regmap,MT6359P_HWCID , &hw_ver);if (hw_ver >=MT6359P_CHIP_VER ) mt6359_info = mt6359p_regulators;else
Greg Kroah-Hartman
maintainerPATCH 117/119 net/smc: Reset connection when trying to use SMCRv2 fails.
In reply to Greg Kroah-HartmanFrom: Wen Gu <[email protected]>
commit 35112271672ae98f45df7875244a4e33aa215e31 upstream.
We found a crash when using SMCRv2 with 2 Mellanox ConnectX-4. It can be reproduced by:
- smc_run nginx
- smc_run wrk -t 32 -c 500 -d 30 http://<ip>:<port>
BUG: kernel NULL pointer dereference, address: 0000000000000014 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 8000000108713067 P4D 8000000108713067 PUD 151127067 PMD 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 4 PID: 2441 Comm: kworker/4:249 Kdump: loaded Tainted: G W E 6.4.0-rc1+ #42 Workqueue: smc_hs_wq smc_listen_work [smc] RIP: 0010:smc_clc_send_confirm_accept+0x284/0x580 [smc] RSP: 0018:ffffb8294b2d7c78 EFLAGS: 00010a06 RAX: ffff8f1873238880 RBX: ffffb8294b2d7dc8 RCX: 0000000000000000 RDX: 00000000000000b4 RSI: 0000000000000001 RDI: 0000000000b40c00 RBP: ffffb8294b2d7db8 R08: ffff8f1815c5860c R09: 0000000000000000 R10: 0000000000000400 R11: 0000000000000000 R12: ffff8f1846f56180 R13: ffff8f1815c5860c R14: 0000000000000001 R15: 0000000000000001 FS: 0000000000000000(0000) GS:ffff8f1aefd00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000014 CR3: 00000001027a0001 CR4: 00000000003706e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> ? mlx5_ib_map_mr_sg+0xa1/0xd0 [mlx5_ib] ? smcr_buf_map_link+0x24b/0x290 [smc] ? __smc_buf_create+0x4ee/0x9b0 [smc] smc_clc_send_accept+0x4c/0xb0 [smc] smc_listen_work+0x346/0x650 [smc] ? __schedule+0x279/0x820 process_one_work+0x1e5/0x3f0 worker_thread+0x4d/0x2f0 ? __pfx_worker_thread+0x10/0x10 kthread+0xe5/0x120 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2c/0x50 </TASK>
During the CLC handshake, server sequentially tries available SMCRv2 and SMCRv1 devices in smc_listen_work().
If an SMCRv2 device is found. SMCv2 based link group and link will be assigned to the connection. Then assumed that some buffer assignment errors happen later in the CLC handshake, such as RMB registration failure, server will give up SMCRv2 and try SMCRv1 device instead. But the resources assigned to the connection won't be reset.
When server tries SMCRv1 device, the connection creation process will be executed again. Since conn->lnk has been assigned when trying SMCRv2, it will not be set to the correct SMCRv1 link in smcr_lgr_conn_assign_link(). So in such situation, conn->lgr points to correct SMCRv1 link group but conn->lnk points to the SMCRv2 link mistakenly.
Then in smc_clc_send_confirm_accept(), conn->rmb_desc->mr[link->link_idx] will be accessed. Since the link->link_idx is not correct, the related MR may not have been initialized, so crash happens.
| Try SMCRv2 device first | |-> conn->lgr: assign existed SMCRv2 link group; | |-> conn->link: assign existed SMCRv2 link (link_idx may be 1 in SMC_LGR_SYMMETRIC); | |-> sndbuf & RMB creation fails, quit; | | Try SMCRv1 device then | |-> conn->lgr: create SMCRv1 link group and assign; | |-> conn->link: keep SMCRv2 link mistakenly; | |-> sndbuf & RMB creation succeed, only RMB->mr[link_idx = 0] | initialized. | | Then smc_clc_send_confirm_accept() accesses | conn->rmb_desc->mr[conn->link->link_idx, which is 1], then crash.
v
This patch tries to fix this by cleaning conn->lnk before assigning link. In addition, it is better to reset the connection and clean the resources assigned if trying SMCRv2 failed in buffer creation or registration.
--- net/smc/af_smc.c | 9 +++++++-- net/smc/smc_core.c | 1 + 2 files changed, 8 insertions(+), 2 deletions(-)
net/smc/af_smc.c +7 -2
@@ -1987,8 +1987,10 @@ static int smc_listen_rdma_init(struct sreturn rc;/* create send buffer and rmb */ -if (smc_buf_create (new_smc, false)) +if (smc_buf_create (new_smc, false)) { +smc_conn_abort (new_smc, ini->first_contact_local);return SMC_CLC_DECL_MEM ; + }return 0 ; }
@@ -2204,8 +2206,11 @@ static void smc_find_rdma_v2_device_serv smcr_version = ini->smcr_version; ini->smcr_version =SMC_V2 ; rc =smc_listen_rdma_init (new_smc, ini); -if (!rc) +if (!rc) { rc =smc_listen_rdma_reg (new_smc, ini->first_contact_local); +if (rc) +smc_conn_abort (new_smc, ini->first_contact_local); + }if (!rc)return ; ini->smcr_version = smcr_version;
net/smc/smc_core.c +1 -0
@@ -127,6 +127,7 @@ static int smcr_lgr_conn_assign_link(strint i, j;/* do link balancing */ + conn->lnk =NULL ;/* reset conn->lnk first */ for (i =0 ; i <SMC_LINKS_PER_LGR_MAX ; i++) {struct smc_link *lnk = &conn->lgr->lnk[i];
Greg Kroah-Hartman
maintainerPATCH 118/119 3c589_cs: Fix an error handling path in tc589_probe()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
commit 640bf95b2c7c2981fb471acdafbd3e0458f8390d upstream.
Should tc589_config() fail, some resources need to be released as already done in the remove function.
--- drivers/net/ethernet/3com/3c589_cs.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/net/ethernet/3com/3c589_cs.c +10 -1
@@ -195,6 +195,7 @@ static int tc589_probe(struct pcmcia_dev {struct el3_private *lp;struct net_device *dev; +int ret;dev_dbg (&link->dev,"3c589_attach()\n" );
@@ -218,7 +219,15 @@ static int tc589_probe(struct pcmcia_dev dev->ethtool_ops = &netdev_ethtool_ops; -return tc589_config (link); + ret =tc589_config (link); +if (ret) + goto err_free_netdev; + +return 0 ; + +err_free_netdev: +free_netdev (dev); +return ret; }static void tc589_detach (struct pcmcia_device *link)
Greg Kroah-Hartman
maintainerPATCH 119/119 net: phy: mscc: add VSC8502 to MODULE_DEVICE_TABLE
In reply to Greg Kroah-HartmanFrom: David Epping <[email protected]>
commit 57fb54ab9f6945e204740b696bd4cee61ee04e5e upstream.
The mscc driver implements support for VSC8502, so its ID should be in the MODULE_DEVICE_TABLE for automatic loading.
--- drivers/net/phy/mscc/mscc_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/phy/mscc/mscc_main.c +1 -0
@@ -2664,6 +2664,7 @@ static struct phy_driver vsc85xx_driver[module_phy_driver (vsc85xx_driver);static struct mdio_device_id __maybe_unused vsc85xx_tbl[] = { + {PHY_ID_VSC8502 ,0xfffffff0 , }, {PHY_ID_VSC8504 ,0xfffffff0 , }, {PHY_ID_VSC8514 ,0xfffffff0 , }, {PHY_ID_VSC8530 ,0xfffffff0 , },
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Successfully compiled and installed bindeb-pkgs on my computer (Acer Aspire E15, Intel Core i3 Haswell). No noticeable regressions.
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Hi Greg
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.31-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
6.1.31-rc1 tested.
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64), arch linux)
Thanks
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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.
Thanks,
Conor
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
Hi Greg
6.1.31-rc1
compiles, boots and runs here on x86_64
(AMD Ryzen 5 PRO 4650G, Slackware64-15.0)
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.31-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
## Build
* kernel: 6.1.31-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-6.1.y
* git commit: 8482df0ff7e727d4244b8bf8537cce39a474eefc
* git describe: v6.1.29-413-g8482df0ff7e7
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.1.y/build/v6.1.29-413-g8482df0ff7e7
## Test Regressions (compared to v6.1.29-293-ge00a3d96f756)
## Metric Regressions (compared to v6.1.29-293-ge00a3d96f756)
## Test Fixes (compared to v6.1.29-293-ge00a3d96f756)
## Metric Fixes (compared to v6.1.29-293-ge00a3d96f756)
## Test result summary
total: 170063, pass: 146595, fail: 3956, skip: 19237, xfail: 275
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 151 total, 150 passed, 1 failed
* arm64: 54 total, 53 passed, 1 failed
* i386: 41 total, 38 passed, 3 failed
* mips: 30 total, 28 passed, 2 failed
* parisc: 8 total, 8 passed, 0 failed
* powerpc: 38 total, 36 passed, 2 failed
* riscv: 16 total, 15 passed, 1 failed
* s390: 16 total, 16 passed, 0 failed
* sh: 14 total, 12 passed, 2 failed
* sparc: 8 total, 8 passed, 0 failed
* x86_64: 46 total, 46 passed, 0 failed
## Test suites summary
* boot
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers-dma-buf
* kselftest-efivarfs
* kselftest-exec
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-firmware
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-net-forwarding
* kselftest-net-mptcp
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-user_events
* kselftest-vDSO
* kselftest-watchdog
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* perf
* rcutorture
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
Build results:
total: 155 pass: 155 fail: 0 Qemu test results: total: 519 pass: 519 fail: 0
Guenter
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.31-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.31-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.1:
11 builds: 11 pass, 0 fail
28 boots: 28 pass, 0 fail
130 tests: 130 pass, 0 failLinux version: 6.1.31-rc1-g8482df0ff7e7
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Wrong/strange TPM patches was Re: [PATCH 6.1 000/119] 6.1.31-rc1 review
In reply to Greg Kroah-HartmanHi!
Quoted 7 lines
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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.
Lino Sanfilippo <[email protected]>
tpm,tpm_tis: Avoid cache incoherency in test for interrupts
Description on this one is wrong/confused. There's no cache problem in the code. Plus test_bit and friend already use bit number, so
- bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND;
+ bool itpm = test_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags);
@@ -87,6 +87,7 @@ enum tpm_tis_flags {
TPM_TIS_ITPM_WORKAROUND = BIT(0),
TPM_TIS_INVALID_STATUS = BIT(1),
TPM_TIS_DEFAULT_CANCELLATION = BIT(2),
+ TPM_TIS_IRQ_TESTED = BIT(3),};
this enum needs to go from BIT() to raw numbers.
You can just do return tpm_pm_resume();
Quoted 2 lines
Jarkko Sakkinen <[email protected]>
tpm: Prevent hwrng from activating during resume
@@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev)
if (chip == NULL)
return -ENODEV;+ chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED;
+
+ /*
+ * Guarantee that SUSPENDED is written last, so that hwrng does not
+ * activate before the chip has been fully resumed.
+ */
+ wmb();
+
return 0; }
EXPORT_SYMBOL_GPL(tpm_pm_resume);
This code is confused. First, either you don't need memory barriers here, or you need real locking. Second, if you want to guarantee flags are written last, you need to put the barrier before the assignment. (But ... get rid of that confusion, first).
Best regards,
Pavel
Signature · 2 lines
DENX Software Engineering GmbH, Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Re: Wrong/strange TPM patches was Re: [PATCH 6.1 000/119] 6.1.31-rc1 review
Quoted 5 lines · Pavel Machek
Quoted 3 lines
Lino Sanfilippo <[email protected]>
tpm,tpm_tis: Avoid cache incoherency in test for interruptsDescription on this one is wrong/confused.
Yes. Commit 858e8b792d06 ("tpm, tpm_tis: Avoid cache incoherency in test for interrupts") in mainline.
The change to test_bit/set_bit may be a good one (and adding the IRQ_TESTED case to the bit flags), but that commit wasn't it.
As you say, the enum should now enumerate bits, not bitmasks.
Linus
Greg Kroah-Hartman
maintainerRe: Wrong/strange TPM patches was Re: [PATCH 6.1 000/119] 6.1.31-rc1 review
In reply to Pavel MachekQuoted 46 lines · Pavel Machek
Hi!
Quoted 7 lines
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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.
Lino Sanfilippo <[email protected]>
tpm,tpm_tis: Avoid cache incoherency in test for interruptsDescription on this one is wrong/confused. There's no cache problem in the code. Plus
test_bitand friend already use bit number, so(quoted diff) +2
-1- bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND; + bool itpm = test_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags);@@ -87,6 +87,7 @@ enum tpm_tis_flags { TPM_TIS_ITPM_WORKAROUND = BIT(0), TPM_TIS_INVALID_STATUS = BIT(1), TPM_TIS_DEFAULT_CANCELLATION = BIT(2), + TPM_TIS_IRQ_TESTED = BIT(3), };this enum needs to go from
BIT()to raw numbers.You can just do return
tpm_pm_resume();Quoted 2 lines
Jarkko Sakkinen <[email protected]>
tpm: Prevent hwrng from activating during resume(quoted diff) +8
-0@@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev) if (chip == NULL) return -ENODEV; + chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED; + + /* + * Guarantee that SUSPENDED is written last, so that hwrng does not + * activate before the chip has been fully resumed. + */ + wmb(); + return 0; } EXPORT_SYMBOL_GPL(tpm_pm_resume);
Quoted 4 lines
This code is confused. First, either you don't need memory barriers here, or you need real locking. Second, if you want to guarantee flags are written last, you need to put the barrier before the assignment. (But ... get rid of that confusion, first).
Care to submit patches to resolve this? It's this way in Linus's tree now from what I can tell, and these changes were needed for another stable-marked change, so I'll leave them in for now.
thanks,
greg k-h
Re: Wrong/strange TPM patches was Re: [PATCH 6.1 000/119] 6.1.31-rc1 review
Hi,
Quoted 50 lines · Greg Kroah-Hartman
ATTENTION: This e-mail is from an external sender. Please check attachments and links before opening e.g. with mouseover.
Quoted 46 lines · Pavel Machek
Hi!
Quoted 7 lines
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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.
Lino Sanfilippo <[email protected]>
tpm,tpm_tis: Avoid cache incoherency in test for interruptsDescription on this one is wrong/confused. There's no cache problem in the code. Plus
test_bitand friend already use bit number, so(quoted diff) +2
-1- bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND; + bool itpm = test_bit(TPM_TIS_ITPM_WORKAROUND, &priv->flags);@@ -87,6 +87,7 @@ enum tpm_tis_flags { TPM_TIS_ITPM_WORKAROUND = BIT(0), TPM_TIS_INVALID_STATUS = BIT(1), TPM_TIS_DEFAULT_CANCELLATION = BIT(2), + TPM_TIS_IRQ_TESTED = BIT(3), };this enum needs to go from
BIT()to raw numbers.You can just do return
tpm_pm_resume();Quoted 2 lines
Jarkko Sakkinen <[email protected]>
tpm: Prevent hwrng from activating during resume(quoted diff) +8
-0@@ -429,6 +431,14 @@ int tpm_pm_resume(struct device *dev) if (chip == NULL) return -ENODEV; + chip->flags &= ~TPM_CHIP_FLAG_SUSPENDED; + + /* + * Guarantee that SUSPENDED is written last, so that hwrng does not + * activate before the chip has been fully resumed. + */ + wmb(); + return 0; } EXPORT_SYMBOL_GPL(tpm_pm_resume);
Quoted 9 lines
Quoted 4 lines
This code is confused. First, either you don't need memory barriers here, or you need real locking. Second, if you want to guarantee flags are written last, you need to put the barrier before the assignment. (But ... get rid of that confusion, first).
Care to submit patches to resolve this? It's this way in Linus's tree now from what I can tell, and these changes were needed for another stable-marked change, so I'll leave them in for now.
First, thanks for the review Pavel and for spotting this. I will send a patch to fix the enums.
Regards,
Lino
Hello Greg,
Quoted 10 lines
From: Greg Kroah-Hartman <[email protected]>
Sent: Sunday, May 28, 2023 8:10 PMThis is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
CIP configurations built and booted with Linux 6.1.31-rc1 (8482df0ff7e7):
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/pipelines/881425030
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/commits/linux-6.1.y
Kind regards, Chris
Quoted 9 lines
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.31-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my x86_64 and ARM64 test systems. No errors or regressions.
Thanks.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.31 release. There are 119 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 Tue, 30 May 2023 19:08:13 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.31-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian